Statistics
| Revision:

root / trunk / applications / appgvSIG / src / com / iver / cit / gvsig / gui / styling / SymbolEditor.java @ 10959

History | View | Annotate | Download (13.2 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2005 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41

    
42
/* CVS MESSAGES:
43
 *
44
 * $Id: SymbolEditor.java 10959 2007-03-28 16:48:22Z jaume $
45
 * $Log$
46
 * Revision 1.4  2007-03-28 16:44:08  jaume
47
 * *** empty log message ***
48
 *
49
 * Revision 1.3  2007/03/27 09:49:03  jaume
50
 * *** empty log message ***
51
 *
52
 * Revision 1.2  2007/03/09 11:25:00  jaume
53
 * Advanced symbology (start committing)
54
 *
55
 * Revision 1.1.2.4  2007/02/21 07:35:14  jaume
56
 * *** empty log message ***
57
 *
58
 * Revision 1.1.2.3  2007/02/09 11:00:03  jaume
59
 * *** empty log message ***
60
 *
61
 * Revision 1.1.2.2  2007/02/08 15:43:05  jaume
62
 * some bug fixes in the editor and removed unnecessary imports
63
 *
64
 * Revision 1.1.2.1  2007/01/26 13:49:03  jaume
65
 * *** empty log message ***
66
 *
67
 * Revision 1.1  2007/01/16 11:52:11  jaume
68
 * *** empty log message ***
69
 *
70
 * Revision 1.11  2007/01/10 17:05:05  jaume
71
 * moved to FMap and gvSIG
72
 *
73
 * Revision 1.10  2006/11/13 09:15:23  jaume
74
 * javadoc and some clean-up
75
 *
76
 * Revision 1.9  2006/11/06 17:08:45  jaume
77
 * *** empty log message ***
78
 *
79
 * Revision 1.8  2006/11/06 16:06:52  jaume
80
 * *** empty log message ***
81
 *
82
 * Revision 1.7  2006/11/06 07:33:54  jaume
83
 * javadoc, source style
84
 *
85
 * Revision 1.6  2006/11/02 17:19:28  jaume
86
 * *** empty log message ***
87
 *
88
 * Revision 1.5  2006/10/31 16:16:34  jaume
89
 * *** empty log message ***
90
 *
91
 * Revision 1.4  2006/10/30 19:30:35  jaume
92
 * *** empty log message ***
93
 *
94
 * Revision 1.3  2006/10/29 23:53:49  jaume
95
 * *** empty log message ***
96
 *
97
 * Revision 1.2  2006/10/27 12:41:09  jaume
98
 * GUI
99
 *
100
 * Revision 1.1  2006/10/26 16:31:21  jaume
101
 * GUI
102
 *
103
 *
104
 */
105
package com.iver.cit.gvsig.gui.styling;
106

    
107
import java.awt.BorderLayout;
108
import java.awt.Dimension;
109
import java.awt.FlowLayout;
110
import java.awt.event.ActionEvent;
111
import java.awt.event.ActionListener;
112
import java.util.Comparator;
113
import java.util.TreeSet;
114

    
115
import javax.swing.BorderFactory;
116
import javax.swing.JComboBox;
117
import javax.swing.JLabel;
118
import javax.swing.JPanel;
119
import javax.swing.JTabbedPane;
120

    
121
import org.gvsig.gui.beans.AcceptCancelPanel;
122

    
123
import com.iver.andami.PluginServices;
124
import com.iver.andami.ui.mdiManager.IWindow;
125
import com.iver.andami.ui.mdiManager.WindowInfo;
126
import com.iver.cit.gvsig.fmap.core.FShape;
127
import com.iver.cit.gvsig.fmap.core.SymbologyFactory;
128
import com.iver.cit.gvsig.fmap.core.symbols.IMultiLayerSymbol;
129
import com.iver.cit.gvsig.fmap.core.symbols.ISymbol;
130
import com.iver.cit.gvsig.fmap.core.symbols.MultiLayerFillSymbol;
131
import com.iver.cit.gvsig.fmap.core.symbols.MultiLayerLineSymbol;
132
import com.iver.cit.gvsig.fmap.core.symbols.MultiLayerMarkerSymbol;
133
import com.iver.cit.gvsig.fmap.core.v02.FSymbol;
134
import com.iver.cit.gvsig.project.documents.layout.Attributes;
135
import com.iver.utiles.XMLEntity;
136

    
137
/**
138
 *
139
 * @author jaume dominguez faus - jaume.dominguez@iver.es
140
 *
141
 */
142
public class SymbolEditor extends JPanel implements IWindow {
143

    
144
        private WindowInfo wi;
145
        private JPanel pnlWest = null;
146
        private JPanel pnlCenter = null;
147
        private JPanel pnlPreview = null;
148
        private JPanel pnlLayers = null;
149
        private AcceptCancelPanel okCancelPanel;
150
        private ISymbol symbol;
151
        private SymbolPreviewer symbolPreview = null;
152
        private JPanel pnlTypeAndUnits = null;
153
        private JComboBox cmbType;
154
        private JComboBox cmbUnits;
155
        private JTabbedPane tabbedPane = null;
156
        private int shapeType;
157
        private XMLEntity oldSymbolProperties;
158
        private ActionListener cmbTypeActionListener;
159

    
160
        private AbstractTypeSymbolEditorPanel[] tabs;
161
        private SymbolLayerManager layerManager;
162
        private boolean replacing = false;
163

    
164
        public SymbolEditor(ISymbol symbol, int shapeType) {
165
                if (!(symbol instanceof IMultiLayerSymbol)) {
166
                        // this is a simple symbol (or null one); it will be
167
                        // converted to a multilayer one to accept layer addition
168
                        IMultiLayerSymbol nSym = null;
169
                        switch (shapeType) {
170
                        case FShape.POINT:
171
                                nSym = new MultiLayerMarkerSymbol();
172
                                break;
173
                        case FShape.LINE:
174
                                nSym = new MultiLayerLineSymbol();
175
                                break;
176
                        case FShape.POLYGON:
177
                                nSym = new MultiLayerFillSymbol();
178
                                break;
179
                        case FShape.TEXT:
180

    
181
                        default:
182
                                throw new Error(PluginServices.getText(this,
183
                                                "shape_type_not_supported"));
184
                        }
185

    
186
                        if (!(symbol instanceof FSymbol))
187
                                nSym.addLayer(symbol);
188
                        this.symbol = nSym;
189

    
190
                } else {
191
                        this.symbol = symbol;
192
                }
193
                this.oldSymbolProperties = this.symbol.getXMLEntity();
194
                this.shapeType = shapeType;
195
                initialize();
196
        }
197

    
198
        /**
199
         * This method initializes this
200
         *
201
         */
202
        private void initialize() {
203

    
204
                cmbTypeActionListener = new ActionListener() {
205
                        int prevIndex = -2;
206

    
207
                        public void actionPerformed(ActionEvent e) {
208
                                int index = getCmbType().getSelectedIndex();
209
                                if (prevIndex != index) {
210
                                        // needs to refresh
211
                                        prevIndex = index;
212

    
213
                                        AbstractTypeSymbolEditorPanel options = (AbstractTypeSymbolEditorPanel) getCmbType()
214
                                                        .getSelectedItem();
215
                                        ISymbol l = getLayerManager().getSelectedLayer();
216

    
217
                                        // if the symbol is not null and is managed by the "options"
218
                                        // class
219
                                        // refresh the controls
220
                                        if (l != null
221
                                                        && l.getClass().equals(options.getSymbolClass()))
222
                                                options.refreshControls(l);
223

    
224
                                        replaceOptions(options);
225
                                }
226
                        }
227
                };
228

    
229
                Comparator tabComparator = new Comparator() {
230
                        public int compare(Object o1, Object o2) {
231
                                if (!(o1 instanceof AbstractTypeSymbolEditorPanel || o1 instanceof AbstractTypeSymbolEditorPanel))
232
                                        throw new IllegalArgumentException(PluginServices.getText(
233
                                                        this, "trying_to_add_a_non_TypeSymbolEditor_panel"));
234
                                AbstractTypeSymbolEditorPanel pnl1 = (AbstractTypeSymbolEditorPanel) o1, pnl2 = (AbstractTypeSymbolEditorPanel) o2;
235
                                int result = pnl1.getName().compareTo(pnl2.getName());
236
                                if (result == 0)
237
                                        throw new IllegalArgumentException(PluginServices.getText(
238
                                                        this, "two_panels_with_the_same_name"));
239
                                return result;
240
                        }
241
                };
242
                TreeSet set = new TreeSet(tabComparator);
243

    
244
                if (shapeType == FShape.POLYGON) {
245
                        // Polygon options
246

    
247
                        // add here your options for polygon symbols
248
                        set.add(new SimpleFill(SymbolEditor.this));
249
                        set.add(new MarkerFill(SymbolEditor.this));
250
                } else if (shapeType == FShape.POINT) {
251
                        // Point options
252

    
253
                        // add here your options for point symbol
254
                        set.add(new CharacterMarker(SymbolEditor.this));
255
                        set.add(new SimpleMarker(SymbolEditor.this));
256
                } else if (shapeType == FShape.LINE) {
257
                        // Point options
258

    
259
                        // add here your options for line symbol
260
                        set.add(new SimpleLine(this));
261
                }
262
                tabs = (AbstractTypeSymbolEditorPanel[]) set
263
                                .toArray(new AbstractTypeSymbolEditorPanel[0]);
264

    
265
                this.setLayout(new BorderLayout());
266
                this.add(getPnlWest(), BorderLayout.WEST);
267
                this.add(getPnlCenter(), BorderLayout.CENTER);
268
                this.add(getOkCancelPanel(), BorderLayout.SOUTH);
269

    
270
                cmbTypeActionListener.actionPerformed(null);
271
                refresh();
272
        }
273

    
274
        private AbstractTypeSymbolEditorPanel getOptionsForSymbol(ISymbol sym) {
275
                if (sym == null)
276
                        return tabs[0];
277
                for (int i = 0; i < tabs.length; i++)
278
                        if (tabs[i].getSymbolClass().equals(sym.getClass()))
279
                                return tabs[i];
280
                return tabs[0];
281
        }
282

    
283
        private AcceptCancelPanel getOkCancelPanel() {
284
                if (okCancelPanel == null) {
285
                        ActionListener action = new ActionListener() {
286
                                public void actionPerformed(ActionEvent e) {
287
                                        if ("CANCEL".equals(e.getActionCommand())) {
288
                                                symbol = SymbologyFactory.createSymbolFromXML(
289
                                                                oldSymbolProperties, null);
290
                                        }
291
                                        PluginServices.getMDIManager().closeWindow(
292
                                                        SymbolEditor.this);
293
                                }
294
                        };
295
                        okCancelPanel = new AcceptCancelPanel(action, action);
296
                }
297
                return okCancelPanel;
298
        }
299

    
300
        public WindowInfo getWindowInfo() {
301
                if (wi == null) {
302
                        wi = new WindowInfo(WindowInfo.MODALDIALOG | WindowInfo.RESIZABLE);
303
                        wi.setWidth(600);
304
                        wi.setHeight(400);
305
                        wi.setTitle(PluginServices.getText(this, "symbol_property_editor"));
306
                }
307
                return wi;
308
        }
309

    
310
        public ISymbol getSymbol() {
311
                return symbol;
312
        }
313

    
314
        private JPanel getPnlWest() {
315
                if (pnlWest == null) {
316
                        pnlWest = new JPanel();
317
                        pnlWest.setLayout(new BorderLayout());
318
                        pnlWest.add(getPnlPreview(), java.awt.BorderLayout.NORTH);
319
                        pnlWest.add(getPnlLayers(), java.awt.BorderLayout.SOUTH);
320
                }
321
                return pnlWest;
322
        }
323

    
324
        private JPanel getPnlCenter() {
325
                if (pnlCenter == null) {
326
                        pnlCenter = new JPanel(new BorderLayout());
327
                        pnlCenter.setBorder(BorderFactory.createTitledBorder(null,
328
                                        PluginServices.getText(this, "properties")));
329
                        pnlCenter.add(getPnlTypeAndUnits(), java.awt.BorderLayout.NORTH);
330
                }
331
                return pnlCenter;
332
        }
333

    
334
        private JPanel getPnlPreview() {
335
                if (pnlPreview == null) {
336
                        pnlPreview = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 5));
337
                        pnlPreview.setBorder(BorderFactory.createTitledBorder(null,
338
                                        PluginServices.getText(this, "preview")));
339
                        pnlPreview.add(getSymbolPreviewer());
340
                }
341
                return pnlPreview;
342
        }
343

    
344
        private JPanel getPnlLayers() {
345
                if (pnlLayers == null) {
346
                        pnlLayers = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 5));
347
                        pnlLayers.setBorder(BorderFactory.createTitledBorder(null,
348
                                        PluginServices.getText(this, "layers")));
349
                        pnlLayers.add(getLayerManager());
350
                }
351
                return pnlLayers;
352
        }
353

    
354
        private SymbolLayerManager getLayerManager() {
355
                if (layerManager == null) {
356
                        layerManager = new SymbolLayerManager(this);
357
                }
358
                return layerManager;
359
        }
360

    
361
        private SymbolPreviewer getSymbolPreviewer() {
362
                if (symbolPreview == null) {
363
                        symbolPreview = new SymbolPreviewer();
364
                        symbolPreview.setPreferredSize(new Dimension(120, 100));
365

    
366
                }
367
                return symbolPreview;
368
        }
369

    
370
        private JPanel getPnlTypeAndUnits() {
371
                if (pnlTypeAndUnits == null) {
372
                        pnlTypeAndUnits = new JPanel();
373
                        pnlTypeAndUnits.setLayout(new BorderLayout());
374
                        JPanel aux = new JPanel(new FlowLayout(FlowLayout.LEADING));
375
                        aux.add(new JLabel(PluginServices.getText(this, "type")));
376
                        aux.add(getCmbType());
377
                        pnlTypeAndUnits.add(aux, BorderLayout.WEST);
378

    
379
                        aux = new JPanel(new FlowLayout(FlowLayout.LEADING));
380
                        aux.add(new JLabel(PluginServices.getText(this, "units")));
381
                        aux.add(getCmbUnits());
382
                        pnlTypeAndUnits.add(aux, BorderLayout.EAST);
383

    
384
                }
385
                return pnlTypeAndUnits;
386
        }
387

    
388
        private JComboBox getCmbUnits() {
389
                if (cmbUnits == null) {
390
                        String[] units = new String[Attributes.NAMES.length+1];
391
                        for (int i = 0; i < Attributes.NAMES.length; i++) {
392
                                units[i] = PluginServices.getText(this, Attributes.NAMES[i]);
393
                        }
394
                        units[units.length-1] = PluginServices.getText(this, "pixels");
395

    
396
                        cmbUnits = new JComboBox(units);
397
                        cmbUnits.setSelectedIndex(units.length-1);
398
                }
399
                return cmbUnits;
400
        }
401

    
402
        private JComboBox getCmbType() {
403
                if (cmbType == null) {
404
                        cmbType = new JComboBox(tabs);
405
                        cmbType.addActionListener(cmbTypeActionListener);
406
                }
407
                return cmbType;
408
        }
409

    
410
        protected void setLayerToSymbol(ISymbol layer) {
411
                int i = layerManager.getSelectedLayerIndex();
412
                IMultiLayerSymbol s = (IMultiLayerSymbol) symbol;
413
                if (i >= 0 && i < s.getLayerCount()) {
414
                        s.setLayer(s.getLayerCount() - 1 - i, layer);
415
                }
416
                refresh();
417
        }
418

    
419
        public void refresh() {
420
                getSymbolPreviewer().setSymbol(symbol);
421
                doLayout();
422
                repaint();
423
        }
424

    
425
        /**
426
         * <p>
427
         * Returns the type of the symbol that this panels is created for.<br>
428
         * </p>
429
         * <p>
430
         * Possible values returned by this method are
431
         * <ol>
432
         * <li> <b> FShape.POINT </b>, for maker symbols </li>
433
         * <li> <b> FShape.POLYGON </b>, for fill symbols </li>
434
         * <li> <b> FShape.LINE </b>, for line symbols (not yet implemented) </li>
435
         * <li> <b> FShape.TEXT </b>, for text symbols (not yet implemented) </li>
436
         * <li> maybe some other in the future </li>
437
         * </ol>
438
         * </p>
439
         *
440
         * @return
441
         */
442
        public int getShapeType() {
443
                return shapeType;
444
        }
445

    
446
        public ISymbol getNewLayer() {
447
                return ((AbstractTypeSymbolEditorPanel) getCmbType().getSelectedItem())
448
                                .getLayer();
449
        }
450

    
451
        private void replaceOptions(AbstractTypeSymbolEditorPanel options) {
452
                if (!replacing) {
453
                        replacing = true;
454
                        if (tabbedPane != null)
455
                                getPnlCenter().remove(tabbedPane);
456
                        JPanel[] tabs = options.getTabs();
457
                        tabbedPane = new JTabbedPane();
458
                        tabbedPane.setPreferredSize(new Dimension(300, 300));
459
                        for (int i = 0; i < tabs.length; i++) {
460
                                tabbedPane.addTab(tabs[i].getName(), tabs[i]);
461
                        }
462
                        getPnlCenter().add(tabbedPane, BorderLayout.CENTER);
463
                        getPnlCenter().doLayout();
464
                        replacing = false;
465
                }
466
        }
467

    
468
        /**
469
         *
470
         * @param symbol
471
         */
472
        public void setOptionsPageFor(ISymbol symbol) {
473
                AbstractTypeSymbolEditorPanel options = getOptionsForSymbol(symbol);
474
                options.refreshControls(symbol);
475
                cmbType.setSelectedItem(options);
476
        }
477
}