/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2013-2014, Geomatys * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotoolkit.gui.swing.style.symbolizer; import java.awt.Component; import java.awt.Image; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.util.logging.Level; import javax.swing.ImageIcon; import org.apache.sis.storage.DataStoreException; import org.geotoolkit.cql.CQLException; import org.geotoolkit.data.FeatureStoreUtilities; import org.geotoolkit.display2d.ext.cellular.CellSymbolizer; import org.geotoolkit.factory.FactoryFinder; import org.geotoolkit.factory.Hints; import org.opengis.feature.FeatureType; import org.geotoolkit.gui.swing.filter.JCQLEditor; import org.geotoolkit.gui.swing.propertyedit.PropertyPane; import org.geotoolkit.gui.swing.resource.IconBundle; import org.geotoolkit.gui.swing.resource.MessageBundle; import org.geotoolkit.gui.swing.style.StyleElementEditor; import org.geotoolkit.map.CoverageMapLayer; import org.geotoolkit.map.MapBuilder; import org.geotoolkit.map.MapLayer; import org.geotoolkit.style.MutableFeatureTypeStyle; import org.geotoolkit.style.MutableRule; import org.geotoolkit.style.MutableStyleFactory; import org.opengis.filter.Filter; import org.opengis.style.PointSymbolizer; import org.opengis.style.Symbolizer; import org.opengis.style.TextSymbolizer; /** * Cell Symbolizer editor. * * @author Johann Sorel (Geomatys) */ public class JCellSymbolizerPane extends StyleElementEditor<CellSymbolizer> implements PropertyPane { private static final MutableStyleFactory SF = (MutableStyleFactory) FactoryFinder.getStyleFactory(new Hints(Hints.STYLE_FACTORY, MutableStyleFactory.class)); private MapLayer layer = null; private StyleElementEditor editor = null; private Filter filter = null; private MapLayer cellMimicLayer = null; private final ItemListener listener = new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { final String typeName = String.valueOf(e.getItem()); pan_info.removeAll(); final Symbolizer symbol; if("Text".equalsIgnoreCase(typeName)){ symbol = getStyleFactory().textSymbolizer(); }else{ symbol = getStyleFactory().pointSymbolizer(); } setEditedSymbolizer(symbol); } }; //keep track of where the symbolizer was to avoid rewriting the complete style private MutableRule parentRule = null; private int parentIndex = 0; /** * Creates new form JCellSymbolizerPane */ public JCellSymbolizerPane() { super(CellSymbolizer.class); initComponents(); guiTypeList.addItemListener(listener); } private void setEditedSymbolizer(Symbolizer symbol){ pan_info.removeAll(); if(symbol instanceof TextSymbolizer){ guiTypeList.setSelectedIndex(1); }else{ guiTypeList.setSelectedIndex(0); } editor = StyleElementEditor.findEditor(symbol); if(editor != null){ editor.setLayer(cellMimicLayer); editor.parse(symbol); pan_info.add(editor); } pan_info.revalidate(); pan_info.repaint(); } @Override public boolean canHandle(Object target) { return target instanceof CoverageMapLayer || target instanceof CellSymbolizer; } @Override public ImageIcon getIcon() { return IconBundle.getIcon("16_classification_cell"); } @Override public Image getPreview() { return null; } @Override public String getTitle() { return MessageBundle.format("style_cellsymbolizer_tooltip"); } @Override public void setLayer(MapLayer layer) { this.layer = layer; } @Override public MapLayer getLayer() { return layer; } @Override public void setTarget(Object candidate) { cellMimicLayer = null; if (candidate instanceof CoverageMapLayer) { setLayer((CoverageMapLayer) candidate); try { final FeatureType sft = CellSymbolizer.buildCellType((CoverageMapLayer)this.layer); cellMimicLayer = MapBuilder.createFeatureLayer(FeatureStoreUtilities.collection("", sft), getStyleFactory().style()); } catch (DataStoreException ex) { LOGGER.log(Level.WARNING, ex.getMessage(),ex); } //search for a cell symbolizer parentRule = null; parentIndex = 0; for(MutableFeatureTypeStyle fts : this.layer.getStyle().featureTypeStyles()){ for(MutableRule r : fts.rules()){ for(int i=0,n=r.symbolizers().size();i<n;i++){ Symbolizer s = r.symbolizers().get(i); if(s instanceof CellSymbolizer){ parse((CellSymbolizer)s); parentRule = r; parentIndex = i; return; } } } } parse(null); }else if(candidate instanceof CellSymbolizer){ parse((CellSymbolizer)candidate); }else{ parse(null); } } @Override public void reset() { parse(null); } @Override public String getToolTip() { return ""; } @Override public Component getComponent() { return this; } @Override public void apply() { if(layer!=null){ final CellSymbolizer symbol = create(); if(parentRule!=null){ parentRule.symbolizers().remove(parentIndex); parentRule.symbolizers().add(parentIndex,symbol); }else{ //style did not exist, add a new feature type style for it final MutableFeatureTypeStyle fts = SF.featureTypeStyle(); final MutableRule rule = SF.rule(symbol); fts.rules().add(rule); fts.setDescription(SF.description("raster cell", "raster cell")); rule.setDescription(SF.description("raster cell", "raster cell")); layer.getStyle().featureTypeStyles().add(fts); parentRule = rule; parentIndex = 0; } } } @Override public void parse(CellSymbolizer target) { guiCellSize.setValue(20); pan_info.removeAll(); pan_info.revalidate(); pan_info.repaint(); editor = null; filter = Filter.INCLUDE; guiTypeList.setSelectedIndex(0); final Symbolizer symbol = getStyleFactory().pointSymbolizer(); setEditedSymbolizer(symbol); if(target!=null){ guiCellSize.setValue(target.getCellSize()); final PointSymbolizer ps = null; //target.getPointSymbolizer(); final TextSymbolizer ts = null; //target.getTextSymbolizer(); filter = target.getRule().getFilter(); if(ps!=null){ guiTypeList.setSelectedIndex(0); setEditedSymbolizer(ps); }else if(ts!=null){ guiTypeList.setSelectedIndex(1); setEditedSymbolizer(ts); } } guiCQL.setFilter(filter); } @Override public CellSymbolizer create() { try { filter = guiCQL.getFilter(); } catch (CQLException ex) { LOGGER.log(Level.INFO, ex.getMessage(), ex); } PointSymbolizer ps = null; TextSymbolizer ts = null; if(editor!=null){ Object c = editor.create(); if(c instanceof PointSymbolizer){ ps = (PointSymbolizer) c; }else{ ts = (TextSymbolizer) c; } } final MutableRule rule = SF.rule(); if(ps!=null){ rule.symbolizers().add(ps); } if(ts!=null){ rule.symbolizers().add(ts); } return new CellSymbolizer((Integer)guiCellSize.getValue(), rule); } @Override protected Object[] getFirstColumnComponents() { return new Object[]{}; } /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always * regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { jLabel1 = new javax.swing.JLabel(); guiCellSize = new javax.swing.JSpinner(); jLabel2 = new javax.swing.JLabel(); guiTypeList = new javax.swing.JComboBox(); guiCQL = new org.geotoolkit.cql.JCQLTextPane(); but_edit = new javax.swing.JButton(); jLabel3 = new javax.swing.JLabel(); jSeparator1 = new javax.swing.JSeparator(); jScrollPane1 = new javax.swing.JScrollPane(); pan_info = new javax.swing.JPanel(); jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); org.openide.awt.Mnemonics.setLocalizedText(jLabel1, MessageBundle.format("style_cellsymbolizer_cellsize")); // NOI18N guiCellSize.setModel(new javax.swing.SpinnerNumberModel(Integer.valueOf(3), Integer.valueOf(3), null, Integer.valueOf(1))); guiCellSize.addChangeListener(new javax.swing.event.ChangeListener() { public void stateChanged(javax.swing.event.ChangeEvent evt) { guiCellSizeStateChanged(evt); } }); org.openide.awt.Mnemonics.setLocalizedText(jLabel2, MessageBundle.format("style_cellsymbolizer_type")); // NOI18N guiTypeList.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Point", "Text" })); org.openide.awt.Mnemonics.setLocalizedText(but_edit, MessageBundle.format("style_cellsymbolizer_edit")); // NOI18N but_edit.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { but_editActionPerformed(evt); } }); jLabel3.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT); org.openide.awt.Mnemonics.setLocalizedText(jLabel3, MessageBundle.format("style_cellsymbolizer_filter")); // NOI18N pan_info.setLayout(new java.awt.BorderLayout()); jScrollPane1.setViewportView(pan_info); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jSeparator1) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jScrollPane1) .addGroup(layout.createSequentialGroup() .addComponent(jLabel1) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(guiCellSize, javax.swing.GroupLayout.PREFERRED_SIZE, 83, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(18, 18, 18) .addComponent(jLabel2) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(guiTypeList, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(but_edit) .addComponent(jLabel3)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(guiCQL, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) .addContainerGap()) ); layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {but_edit, jLabel1, jLabel3}); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel1) .addComponent(guiCellSize, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jLabel2) .addComponent(guiTypeList, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addGroup(layout.createSequentialGroup() .addComponent(jLabel3) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(but_edit)) .addComponent(guiCQL, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 133, Short.MAX_VALUE) .addContainerGap()) ); }// </editor-fold>//GEN-END:initComponents private void but_editActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_but_editActionPerformed try { filter = JCQLEditor.showDialog(this, cellMimicLayer, filter); guiCQL.setFilter(filter); firePropertyChange(PROPERTY_UPDATED, null, create()); } catch (CQLException ex) { LOGGER.log(Level.INFO, ex.getMessage(), ex); } }//GEN-LAST:event_but_editActionPerformed private void guiCellSizeStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_guiCellSizeStateChanged firePropertyChange(PROPERTY_UPDATED, null, create()); }//GEN-LAST:event_guiCellSizeStateChanged // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton but_edit; private org.geotoolkit.cql.JCQLTextPane guiCQL; private javax.swing.JSpinner guiCellSize; private javax.swing.JComboBox guiTypeList; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel3; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JSeparator jSeparator1; private javax.swing.JPanel pan_info; // End of variables declaration//GEN-END:variables }