Statistics
| Revision:

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

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

    
119
import java.awt.BorderLayout;
120
import java.awt.Dimension;
121
import java.awt.FlowLayout;
122
import java.awt.event.ActionEvent;
123
import java.awt.event.ActionListener;
124
import java.util.Comparator;
125
import java.util.TreeSet;
126

    
127
import javax.swing.BorderFactory;
128
import javax.swing.JComboBox;
129
import javax.swing.JLabel;
130
import javax.swing.JPanel;
131
import javax.swing.JTabbedPane;
132

    
133
import org.gvsig.gui.beans.AcceptCancelPanel;
134

    
135
import com.iver.andami.PluginServices;
136
import com.iver.andami.ui.mdiManager.IWindow;
137
import com.iver.andami.ui.mdiManager.WindowInfo;
138
import com.iver.cit.gvsig.fmap.core.FShape;
139
import com.iver.cit.gvsig.fmap.core.SymbologyFactory;
140
import com.iver.cit.gvsig.fmap.core.symbols.IMultiLayerSymbol;
141
import com.iver.cit.gvsig.fmap.core.symbols.ISymbol;
142
import com.iver.cit.gvsig.fmap.core.symbols.MultiLayerFillSymbol;
143
import com.iver.cit.gvsig.fmap.core.symbols.MultiLayerLineSymbol;
144
import com.iver.cit.gvsig.fmap.core.symbols.MultiLayerMarkerSymbol;
145
import com.iver.cit.gvsig.fmap.core.v02.FSymbol;
146
import com.iver.cit.gvsig.gui.JUnitsComboBox;
147
import com.iver.utiles.XMLEntity;
148

    
149
/**
150
 *
151
 * @author jaume dominguez faus - jaume.dominguez@iver.es
152
 *
153
 */
154
public class SymbolEditor extends JPanel implements IWindow {
155

    
156
        private WindowInfo wi;
157
        private JPanel pnlWest = null;
158
        private JPanel pnlCenter = null;
159
        private JPanel pnlPreview = null;
160
        private JPanel pnlLayers = null;
161
        private AcceptCancelPanel okCancelPanel;
162
        private ISymbol symbol;
163
        private SymbolPreviewer symbolPreview = null;
164
        private JPanel pnlTypeAndUnits = null;
165
        private JComboBox cmbType;
166
        private JUnitsComboBox cmbUnits;
167
        private JTabbedPane tabbedPane = null;
168
        private int shapeType;
169
        private XMLEntity oldSymbolProperties;
170
        private ActionListener cmbTypeActionListener;
171

    
172
        private AbstractTypeSymbolEditorPanel[] tabs;
173
        private SymbolLayerManager layerManager;
174
        private boolean replacing = false;
175
        private JComboBox cmbUnitsReferenceSystem;
176

    
177
        public SymbolEditor(ISymbol symbol, int shapeType) {
178
                if (!(symbol instanceof IMultiLayerSymbol)) {
179
                        // this is a simple symbol (or null one); it will be
180
                        // converted to a multilayer one to accept layer addition
181
                        IMultiLayerSymbol nSym = null;
182
                        switch (shapeType) {
183
                        case FShape.POINT:
184
                                nSym = new MultiLayerMarkerSymbol();
185
                                break;
186
                        case FShape.LINE:
187
                                nSym = new MultiLayerLineSymbol();
188
                                break;
189
                        case FShape.POLYGON:
190
                                nSym = new MultiLayerFillSymbol();
191
                                break;
192
                        case FShape.TEXT:
193

    
194
                        default:
195
                                throw new Error(PluginServices.getText(this,
196
                                                "shape_type_not_supported"));
197
                        }
198

    
199
                        if (!(symbol instanceof FSymbol))
200
                                nSym.addLayer(symbol);
201
                        this.symbol = nSym;
202

    
203
                } else {
204
                        this.symbol = symbol;
205
                }
206
                this.oldSymbolProperties = this.symbol.getXMLEntity();
207
                this.shapeType = shapeType;
208
                initialize();
209
        }
210

    
211
        /**
212
         * This method initializes this
213
         *
214
         */
215
        private void initialize() {
216

    
217
                cmbTypeActionListener = new ActionListener() {
218
                        int prevIndex = -2;
219

    
220
                        public void actionPerformed(ActionEvent e) {
221
                                int index = getCmbType().getSelectedIndex();
222
                                if (prevIndex != index) {
223
                                        // needs to refresh
224
                                        prevIndex = index;
225

    
226
                                        AbstractTypeSymbolEditorPanel options = (AbstractTypeSymbolEditorPanel) getCmbType()
227
                                                        .getSelectedItem();
228
                                        ISymbol l = getLayerManager().getSelectedLayer();
229

    
230
                                        // if the symbol is not null and is managed by the "options"
231
                                        // class
232
                                        // refresh the controls
233
                                        if (l != null
234
                                                        && l.getClass().equals(options.getSymbolClass()))
235
                                                options.refreshControls(l);
236

    
237
                                        replaceOptions(options);
238
                                }
239
                        }
240
                };
241

    
242
                Comparator tabComparator = new Comparator() {
243
                        public int compare(Object o1, Object o2) {
244
                                if (!(o1 instanceof AbstractTypeSymbolEditorPanel || o1 instanceof AbstractTypeSymbolEditorPanel))
245
                                        throw new IllegalArgumentException(PluginServices.getText(
246
                                                        this, "trying_to_add_a_non_TypeSymbolEditor_panel"));
247
                                AbstractTypeSymbolEditorPanel pnl1 = (AbstractTypeSymbolEditorPanel) o1, pnl2 = (AbstractTypeSymbolEditorPanel) o2;
248
                                int result = pnl1.getName().compareTo(pnl2.getName());
249
                                if (result == 0)
250
                                        throw new IllegalArgumentException(PluginServices.getText(
251
                                                        this, "two_panels_with_the_same_name"));
252
                                return result;
253
                        }
254
                };
255
                TreeSet set = new TreeSet(tabComparator);
256

    
257
                // TODO refactor this to make it dynamic and plug'n'play
258
                if (shapeType == FShape.POLYGON) {
259
                        // Polygon options
260

    
261
                        // add here your options for polygon symbols
262
                        set.add(new SimpleFill(SymbolEditor.this));
263
                        set.add(new MarkerFill(SymbolEditor.this));
264
                } else if (shapeType == FShape.POINT) {
265
                        // Point options
266

    
267
                        // add here your options for point symbol
268
                        set.add(new CharacterMarker(SymbolEditor.this));
269
                        set.add(new SimpleMarker(SymbolEditor.this));
270
                        set.add(new PictureMarker(SymbolEditor.this));
271
                } else if (shapeType == FShape.LINE) {
272
                        // Point options
273

    
274
                        // add here your options for line symbol
275
                        set.add(new SimpleLine(this));
276
                }
277
                tabs = (AbstractTypeSymbolEditorPanel[]) set
278
                                .toArray(new AbstractTypeSymbolEditorPanel[0]);
279

    
280
                this.setLayout(new BorderLayout());
281
                this.add(getPnlWest(), BorderLayout.WEST);
282
                this.add(getPnlCenter(), BorderLayout.CENTER);
283
                this.add(getOkCancelPanel(), BorderLayout.SOUTH);
284

    
285
                cmbTypeActionListener.actionPerformed(null);
286
                refresh();
287
        }
288

    
289
        private AbstractTypeSymbolEditorPanel getOptionsForSymbol(ISymbol sym) {
290
                if (sym == null)
291
                        return tabs[0];
292
                for (int i = 0; i < tabs.length; i++)
293
                        if (tabs[i].getSymbolClass().equals(sym.getClass()))
294
                                return tabs[i];
295
                return tabs[0];
296
        }
297

    
298
        private AcceptCancelPanel getOkCancelPanel() {
299
                if (okCancelPanel == null) {
300
                        ActionListener action = new ActionListener() {
301
                                public void actionPerformed(ActionEvent e) {
302
                                        if ("CANCEL".equals(e.getActionCommand())) {
303
                                                symbol = SymbologyFactory.createSymbolFromXML(
304
                                                                oldSymbolProperties, null);
305
                                        }
306
                                        PluginServices.getMDIManager().closeWindow(
307
                                                        SymbolEditor.this);
308
                                }
309
                        };
310
                        okCancelPanel = new AcceptCancelPanel(action, action);
311
                }
312
                return okCancelPanel;
313
        }
314

    
315
        public WindowInfo getWindowInfo() {
316
                if (wi == null) {
317
                        wi = new WindowInfo(WindowInfo.MODALDIALOG | WindowInfo.RESIZABLE);
318
                        wi.setWidth(650);
319
                        wi.setHeight(400);
320
                        wi.setTitle(PluginServices.getText(this, "symbol_property_editor"));
321
                }
322
                return wi;
323
        }
324

    
325
        public ISymbol getSymbol() {
326
                return symbol;
327
        }
328

    
329
        private JPanel getPnlWest() {
330
                if (pnlWest == null) {
331
                        pnlWest = new JPanel();
332
                        pnlWest.setLayout(new BorderLayout());
333
                        pnlWest.add(getPnlPreview(), java.awt.BorderLayout.NORTH);
334
                        pnlWest.add(getPnlLayers(), java.awt.BorderLayout.SOUTH);
335
                }
336
                return pnlWest;
337
        }
338

    
339
        private JPanel getPnlCenter() {
340
                if (pnlCenter == null) {
341
                        pnlCenter = new JPanel(new BorderLayout());
342
                        pnlCenter.setBorder(BorderFactory.createTitledBorder(null,
343
                                        PluginServices.getText(this, "properties")));
344
                        pnlCenter.add(getPnlTypeAndUnits(), java.awt.BorderLayout.NORTH);
345
                }
346
                return pnlCenter;
347
        }
348

    
349
        private JPanel getPnlPreview() {
350
                if (pnlPreview == null) {
351
                        pnlPreview = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 5));
352
                        pnlPreview.setBorder(BorderFactory.createTitledBorder(null,
353
                                        PluginServices.getText(this, "preview")));
354
                        pnlPreview.add(getSymbolPreviewer());
355
                }
356
                return pnlPreview;
357
        }
358

    
359
        private JPanel getPnlLayers() {
360
                if (pnlLayers == null) {
361
                        pnlLayers = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 5));
362
                        pnlLayers.setBorder(BorderFactory.createTitledBorder(null,
363
                                        PluginServices.getText(this, "layers")));
364
                        pnlLayers.add(getLayerManager());
365
                }
366
                return pnlLayers;
367
        }
368

    
369
        private SymbolLayerManager getLayerManager() {
370
                if (layerManager == null) {
371
                        layerManager = new SymbolLayerManager(this);
372
                }
373
                return layerManager;
374
        }
375

    
376
        private SymbolPreviewer getSymbolPreviewer() {
377
                if (symbolPreview == null) {
378
                        symbolPreview = new SymbolPreviewer();
379
                        symbolPreview.setPreferredSize(new Dimension(150, 100));
380

    
381
                }
382
                return symbolPreview;
383
        }
384

    
385
        private JPanel getPnlTypeAndUnits() {
386
                if (pnlTypeAndUnits == null) {
387
                        pnlTypeAndUnits = new JPanel();
388
                        pnlTypeAndUnits.setLayout(new BorderLayout());
389
                        JPanel aux = new JPanel(new FlowLayout(FlowLayout.LEADING));
390
                        aux.add(new JLabel(PluginServices.getText(this, "type")));
391
                        aux.add(getCmbType());
392
                        pnlTypeAndUnits.add(aux, BorderLayout.WEST);
393

    
394
                        aux = new JPanel(new FlowLayout(FlowLayout.LEADING));
395
                        aux.add(new JLabel(PluginServices.getText(this, "units")));
396
                        aux.add(getCmbUnits());
397
                        aux.add(getCmbUnitsReferenceSystem());
398
                        pnlTypeAndUnits.add(aux, BorderLayout.EAST);
399

    
400
                }
401
                return pnlTypeAndUnits;
402
        }
403

    
404
        private JComboBox getCmbUnitsReferenceSystem() {
405
                if (cmbUnitsReferenceSystem == null) {
406
                        cmbUnitsReferenceSystem = new JComboBox(new String[] {
407
                                        PluginServices.getText(this, "in_the_map"),
408
                                        PluginServices.getText(this, "in_the_paper")
409
                        });
410

    
411
                }
412

    
413
                return cmbUnitsReferenceSystem;
414
        }
415

    
416
        private JUnitsComboBox getCmbUnits() {
417
                if (cmbUnits == null) {
418
                        cmbUnits = new JUnitsComboBox();
419
                }
420
                return cmbUnits;
421
        }
422

    
423
        public double getUnitConversionFactor() {
424
                return getCmbUnits().getUnitConversionFactor();
425
        }
426

    
427
        private JComboBox getCmbType() {
428
                if (cmbType == null) {
429
                        cmbType = new JComboBox(tabs);
430
                        cmbType.addActionListener(cmbTypeActionListener);
431
                }
432
                return cmbType;
433
        }
434

    
435
        protected void setLayerToSymbol(ISymbol layer) {
436
                int i = layerManager.getSelectedLayerIndex();
437
                IMultiLayerSymbol s = (IMultiLayerSymbol) symbol;
438
                if (i >= 0 && i < s.getLayerCount()) {
439
                        s.setLayer(s.getLayerCount() - 1 - i, layer);
440
                }
441
                refresh();
442
        }
443

    
444
        public void refresh() {
445
                getSymbolPreviewer().setSymbol(symbol);
446
                doLayout();
447
                repaint();
448
        }
449

    
450
        /**
451
         * <p>
452
         * Returns the type of the symbol that this panels is created for.<br>
453
         * </p>
454
         * <p>
455
         * Possible values returned by this method are
456
         * <ol>
457
         * <li> <b> FShape.POINT </b>, for maker symbols </li>
458
         * <li> <b> FShape.POLYGON </b>, for fill symbols </li>
459
         * <li> <b> FShape.LINE </b>, for line symbols (not yet implemented) </li>
460
         * <li> <b> FShape.TEXT </b>, for text symbols (not yet implemented) </li>
461
         * <li> maybe some other in the future </li>
462
         * </ol>
463
         * </p>
464
         *
465
         * @return
466
         */
467
        public int getShapeType() {
468
                return shapeType;
469
        }
470

    
471
        public ISymbol getNewLayer() {
472
                return ((AbstractTypeSymbolEditorPanel) getCmbType().getSelectedItem())
473
                                .getLayer();
474
        }
475

    
476
        private void replaceOptions(AbstractTypeSymbolEditorPanel options) {
477
                if (!replacing) {
478
                        replacing = true;
479
                        if (tabbedPane != null)
480
                                getPnlCenter().remove(tabbedPane);
481
                        JPanel[] tabs = options.getTabs();
482
                        tabbedPane = new JTabbedPane();
483
                        tabbedPane.setPreferredSize(new Dimension(300, 300));
484
                        for (int i = 0; i < tabs.length; i++) {
485
                                tabbedPane.addTab(tabs[i].getName(), tabs[i]);
486
                        }
487
                        getPnlCenter().add(tabbedPane, BorderLayout.CENTER);
488
                        getPnlCenter().doLayout();
489
                        replacing = false;
490
                }
491
        }
492

    
493
        /**
494
         *
495
         * @param symbol
496
         */
497
        public void setOptionsPageFor(ISymbol symbol) {
498
                AbstractTypeSymbolEditorPanel options = getOptionsForSymbol(symbol);
499
                options.refreshControls(symbol);
500
                cmbType.setSelectedItem(options);
501
        }
502
}