Statistics
| Revision:

svn-gvsig-desktop / trunk / extensions / extSymbology / src / org / gvsig / symbology / gui / styling / CharacterMarker.java @ 25807

History | View | Annotate | Download (16.9 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: CharacterMarker.java 13828 2007-09-19 11:06:36Z jvidal $
45
* $Log$
46
* Revision 1.20  2007-09-19 11:06:36  jvidal
47
* bug solved
48
*
49
* Revision 1.19  2007/09/17 09:21:45  jaume
50
* refactored SymboSelector (added support for multishapedsymbol)
51
*
52
* Revision 1.18  2007/08/08 11:45:38  jaume
53
* some bugs fixed
54
*
55
* Revision 1.17  2007/08/07 11:21:05  jvidal
56
* javadoc
57
*
58
* Revision 1.16  2007/08/03 11:29:13  jaume
59
* refactored AbstractTypeSymbolEditorPanel class name to AbastractTypeSymbolEditor
60
*
61
* Revision 1.15  2007/07/30 12:56:04  jaume
62
* organize imports, java 5 code downgraded to 1.4 and added PictureFillSymbol
63
*
64
* Revision 1.14  2007/07/12 10:43:55  jaume
65
* *** empty log message ***
66
*
67
* Revision 1.13  2007/06/29 13:07:33  jaume
68
* +PictureLineSymbol
69
*
70
* Revision 1.12  2007/05/31 09:36:22  jaume
71
* *** empty log message ***
72
*
73
* Revision 1.11  2007/05/29 15:47:06  jaume
74
* *** empty log message ***
75
*
76
* Revision 1.10  2007/05/21 10:38:27  jaume
77
* *** empty log message ***
78
*
79
* Revision 1.9  2007/05/09 16:08:14  jaume
80
* *** empty log message ***
81
*
82
* Revision 1.8  2007/04/26 11:40:09  jaume
83
* added new components (JIncrementalNumberField)
84
*
85
* Revision 1.7  2007/04/20 07:54:38  jaume
86
* *** empty log message ***
87
*
88
* Revision 1.6  2007/04/19 14:22:20  jaume
89
* *** empty log message ***
90
*
91
* Revision 1.5  2007/04/05 16:08:34  jaume
92
* Styled labeling stuff
93
*
94
* Revision 1.4  2007/04/04 16:01:13  jaume
95
* *** empty log message ***
96
*
97
* Revision 1.3  2007/03/30 12:54:11  jaume
98
* *** empty log message ***
99
*
100
* Revision 1.2  2007/03/09 11:25:00  jaume
101
* Advanced symbology (start committing)
102
*
103
* Revision 1.1.2.7  2007/02/21 07:35:14  jaume
104
* *** empty log message ***
105
*
106
* Revision 1.1.2.6  2007/02/08 15:43:05  jaume
107
* some bug fixes in the editor and removed unnecessary imports
108
*
109
* Revision 1.1.2.5  2007/02/05 14:58:28  jaume
110
* *** empty log message ***
111
*
112
* Revision 1.1.2.3  2007/02/04 16:57:22  jaume
113
* working the map of characters
114
*
115
* Revision 1.1.2.2  2007/02/02 16:21:32  jaume
116
* *** empty log message ***
117
*
118
* Revision 1.1.2.1  2007/01/26 13:49:03  jaume
119
* *** empty log message ***
120
*
121
* Revision 1.1  2007/01/16 11:52:11  jaume
122
* *** empty log message ***
123
*
124
* Revision 1.3  2006/11/06 17:08:45  jaume
125
* *** empty log message ***
126
*
127
* Revision 1.2  2006/11/06 16:06:52  jaume
128
* *** empty log message ***
129
*
130
* Revision 1.1  2006/10/31 16:16:34  jaume
131
* *** empty log message ***
132
*
133
*
134
*/
135
package org.gvsig.symbology.gui.styling;
136

    
137
import java.awt.BorderLayout;
138
import java.awt.Color;
139
import java.awt.Component;
140
import java.awt.Dimension;
141
import java.awt.Font;
142
import java.awt.event.ActionEvent;
143
import java.awt.event.ActionListener;
144
import java.awt.geom.Point2D;
145
import java.util.ArrayList;
146

    
147
import javax.swing.BorderFactory;
148
import javax.swing.BoxLayout;
149
import javax.swing.JCheckBox;
150
import javax.swing.JComponent;
151
import javax.swing.JLabel;
152
import javax.swing.JList;
153
import javax.swing.JPanel;
154
import javax.swing.JScrollPane;
155
import javax.swing.ListCellRenderer;
156
import javax.swing.ListModel;
157
import javax.swing.event.ListDataListener;
158
import javax.swing.event.ListSelectionEvent;
159
import javax.swing.event.ListSelectionListener;
160

    
161
import org.gvsig.gui.beans.swing.GridBagLayoutPanel;
162
import org.gvsig.gui.beans.swing.JComboBoxFontSizes;
163
import org.gvsig.gui.beans.swing.JComboBoxFonts;
164
import org.gvsig.gui.beans.swing.JIncrementalNumberField;
165
import org.gvsig.symbology.fmap.symbols.CharacterMarkerSymbol;
166

    
167
import com.iver.andami.PluginServices;
168
import com.iver.andami.messages.NotificationManager;
169
import com.iver.cit.gvsig.fmap.core.symbols.ISymbol;
170
import com.iver.cit.gvsig.fmap.core.v02.FConstant;
171
import com.iver.cit.gvsig.gui.panels.ColorChooserPanel;
172
import com.iver.cit.gvsig.gui.styling.AbstractTypeSymbolEditor;
173
import com.iver.cit.gvsig.gui.styling.EditorTool;
174
import com.iver.cit.gvsig.gui.styling.Mask;
175
import com.iver.cit.gvsig.gui.styling.SymbolEditor;
176
import com.iver.cit.gvsig.gui.styling.SymbolPreviewer;
177

    
178

    
179

    
180
/**
181
* CharacterMarker allows the user to store and modify the properties that
182
* define a <b>character marker</b>.<p>
183
* <p>
184
* This functionality is carried out thanks to two tabs (character marker and mask)which
185
* are included in the panel to edit the properities of a symbol (SymbolEditor)how
186
* is explained in AbstractTypeSymbolEditor.<p>
187
* <p>
188
* The first tab (Character marker)allows the user to change the font (<b>cmbFonts</b>)of
189
* the symbol for the character marker, the size of that (<b>cmbFontSize</b>),the angle
190
*(<b>numberAngle</b>)if the user wants to show the character with some rotation,the color
191
* (<b>jcc</b>) and the offset (<b>txtYOffset,txtXOffset</b>).<p>
192
* <p>
193
* The second tab (<b>Mask</b>) modifies attributes of a mask for points such
194
*  as style,size and symbol (to represent a point in the map).<p>
195
*
196
*@see Mask
197
*@see AbstractTypeSymbolEditor
198
*@author jaume dominguez faus - jaume.dominguez@iver.es
199
*/
200
public class CharacterMarker extends AbstractTypeSymbolEditor implements ActionListener {
201
        private ArrayList<JPanel> tabs = new ArrayList<JPanel>();
202
        private JList jListSymbols;
203
        private JScrollPane jScrollPane;
204
        private JComboBoxFonts cmbFonts;
205
        private Mask mask;
206
        private JComboBoxFontSizes cmbFontSize;
207
        private JIncrementalNumberField numberAngle;
208
        private ColorChooserPanel jcc;
209
        private JIncrementalNumberField txtYOffset;
210
        private JIncrementalNumberField txtXOffset;
211
        private Font font;
212
        private int unicode;
213
        private JCheckBox chkAdjustGlyph;
214

    
215
        /**
216
         * contructor method
217
         * @param owner
218
         */
219
        public CharacterMarker(SymbolEditor owner) {
220
                super(owner);
221
                initialize();
222
        }
223
        /**
224
         * Initializes the parameters that define a charactermarker.To do it, two tabs
225
         * are created inside the SymbolEditor panel with default values for the
226
         * different attributes of the character marker.This two tabs will be character
227
         * marker tab (options of font,size,angle,color and the offset of the character
228
         * marker)and a Mask added as a new tab.
229
         *
230
         */
231
        private void initialize() {
232
                JPanel myTab;
233
                {
234
                        // Character marker tab
235
                        myTab = new JPanel(new BorderLayout(10, 10));
236
                        myTab.setName(PluginServices.getText(this, "character_marker"));
237
                        myTab.setLayout(new BorderLayout(15,15));
238

    
239
                        JPanel aux = new JPanel(new BorderLayout(15, 15));
240
                        aux.add(new JLabel(PluginServices.getText(this, "font")+":"), BorderLayout.NORTH);
241
                        aux.add(getCmbFonts(), BorderLayout.NORTH);
242

    
243
                        getJListSymbols().setModel(
244
                                        new CharacterListModel(
245
                                                        new Font((String) getCmbFonts().getSelectedItem(), Font.PLAIN, 14)));
246
                        aux.add(getJScrollPane(), BorderLayout.CENTER);
247
                        myTab.add(aux, BorderLayout.CENTER);
248

    
249
                        GridBagLayoutPanel aux1 = new GridBagLayoutPanel();
250
                        aux1.addComponent(PluginServices.getText(this, "size")+":", getCmbFontSize());
251
                        aux1.addComponent(PluginServices.getText(this, "angle")+":", getNumberAngle());
252

    
253
                        aux1.addComponent(PluginServices.getText(this, "color")+":", getColorChooser());
254

    
255
                        GridBagLayoutPanel aux2 = new GridBagLayoutPanel();
256
                        aux2.addComponent("X:", getTxtXOffset());
257
                        aux2.addComponent("Y:", getTxtYOffset());
258
                        aux2.setBorder(BorderFactory.createTitledBorder(PluginServices.getText(this, "offset")));
259
                        aux1.addComponent(aux2);
260

    
261
                        myTab.add(aux1, BorderLayout.EAST);
262
                        myTab.add(getChkAdjustGlyph(), BorderLayout.SOUTH);
263

    
264
                        tabs.add(myTab);
265
                }
266

    
267
                {
268
                        // Mask tab
269
                        mask = new Mask(this);
270

    
271
                        tabs.add(mask);
272
                }
273

    
274
                jListSymbols.addListSelectionListener(new ListSelectionListener() {
275
                        public void valueChanged(ListSelectionEvent e) {
276
                                fireSymbolChangedEvent();
277
                        }
278
                });
279
        }
280

    
281
        /**
282
         * JCheckBox that allows the user to apply visual correction to glyph for
283
         * precise size and position.
284
         * @return JCheckBox
285
         */
286
        private JCheckBox getChkAdjustGlyph() {
287
                if (chkAdjustGlyph == null) {
288
                        chkAdjustGlyph = new JCheckBox(PluginServices.getText(this, "apply_visual_correction_to_glyph_for_precise_size_and_position"));
289
                        chkAdjustGlyph.addActionListener(this);
290
                }
291

    
292
                return chkAdjustGlyph;
293
        }
294

    
295
        /**
296
         * JIncrementalNumberField that controls the YOffset for the character that the
297
         * user wants to use as a marker.
298
         * @return JIncrementalNumberField
299
         */
300
        private JIncrementalNumberField getTxtYOffset() {
301
                if (txtYOffset == null) {
302
                        txtYOffset = new JIncrementalNumberField(String.valueOf(0), 7);
303
                        txtYOffset.addActionListener(this);
304
                }
305

    
306
                return txtYOffset;
307
        }
308
        /**
309
         * JIncrementalNumberField that controls the XOffset for the character that the
310
         * user wants to use as a marker.
311
         * @return JIncrementalNumberField
312
         */
313
        private JIncrementalNumberField getTxtXOffset() {
314
                if (txtXOffset == null) {
315
                        txtXOffset = new JIncrementalNumberField(String.valueOf(0), 7);
316
                        txtXOffset.addActionListener(this);
317
                }
318

    
319
                return txtXOffset;
320
        }
321
        /**
322
         * ColorChooserPanel used to select the color for the character that the
323
         * user wants to use as a marker.
324
         * @return ColorChooserPanel
325
         */
326
        private ColorChooserPanel getColorChooser() {
327
                if (jcc == null) {
328
                        jcc = new ColorChooserPanel();
329
                        jcc.setAlpha(255);
330
                        jcc.addActionListener(this);
331
                }
332

    
333
                return jcc;
334
        }
335
        /**
336
         * JComboBoxFontSizes that allows the user to change the size of the character
337
         * selected as a marker
338
         * @return JComboBoxFontSizes
339
         */
340
        private JComboBoxFontSizes getCmbFontSize() {
341
                if (cmbFontSize == null) {
342
                        cmbFontSize = new JComboBoxFontSizes();
343
                        cmbFontSize.addActionListener(this);
344
                }
345

    
346
                return cmbFontSize;
347
        }
348
        /**
349
         * JIncrementalNumberField that controls the angle (if the user wants to show the
350
         * character with some rotation) for the character that the user wants to use as
351
         * a marker.
352
         * @return JIncrementalNumberField
353
         */
354

    
355
        private JIncrementalNumberField getNumberAngle() {
356
                if (numberAngle == null) {
357
                        numberAngle = new JIncrementalNumberField(String.valueOf(0), 5);
358
                        numberAngle.addActionListener(this);
359

    
360
                }
361

    
362
                return numberAngle;
363
        }
364

    
365
        /**
366
         * JComboBoxFonts its a combobox of fonts where the user can select the font
367
         * for the character marker.Depends on this font, the character will change its
368
         * appearance.
369
         * @returnJComboBoxFonts
370
         */
371
        private JComboBoxFonts getCmbFonts() {
372
                if (cmbFonts == null) {
373
                        cmbFonts = new JComboBoxFonts();
374
                        cmbFonts.addActionListener(this);
375
                }
376
                return cmbFonts;
377
        }
378
        /**
379
         * JScrollPane to select the exact character marker.The content of this pane
380
         * will change depending on the font that the user had selected.
381
         * @return JScrollPane
382
         */
383

    
384
        private JScrollPane getJScrollPane() {
385
                if (jScrollPane == null) {
386
                        jScrollPane = new JScrollPane();
387
                        jScrollPane.setViewportView(getJListSymbols());
388
                        jScrollPane.setPreferredSize(new Dimension(300, 180));
389
                }
390
                return jScrollPane;
391
        }
392
        /**
393
         * Used with the JScrollPane to create the pane that allows the user to select the
394
         * character marker.
395
         * @see getJScrollPane()
396
         * @return JList
397
         */
398
        private JList getJListSymbols() {
399
                if (jListSymbols == null) {
400
                        jListSymbols = new JList();
401
                        jListSymbols.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
402
                        jListSymbols.setLayoutOrientation(JList.HORIZONTAL_WRAP);
403
                        jListSymbols.setVisibleRowCount(-1);
404
                        jListSymbols.addListSelectionListener(new ListSelectionListener() {
405

    
406
                                public void valueChanged(ListSelectionEvent e) {
407
                                        CharacterItem theChar = (CharacterItem) jListSymbols.getSelectedValue();
408
                                        if (theChar == null) return;
409
                                        font = theChar.font;
410
                                        unicode = theChar.glyph;
411
                                        fireSymbolChangedEvent();
412
                                }
413
                        });
414
                        ListCellRenderer renderer = new ListCellRenderer() {
415
                                private Color mySelectedBGColor = new Color(255,145,100,255);
416
                                public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
417
                                        CharacterItem theChar = (CharacterItem) value;
418
                                        CharacterMarkerSymbol sym = new CharacterMarkerSymbol(theChar.font, theChar.glyph, Color.BLACK);
419
                                        JPanel pnl = new JPanel();
420
                                        BoxLayout layout = new BoxLayout(pnl, BoxLayout.Y_AXIS);
421
                                        pnl.setLayout(layout);
422
                                        Color bgColor = (isSelected) ? mySelectedBGColor
423
                                                        : getJListSymbols().getBackground();
424

    
425
                                        pnl.setBackground(bgColor);
426
                                        SymbolPreviewer sp = new SymbolPreviewer();
427
                                        sp.setAlignmentX(Component.CENTER_ALIGNMENT);
428
                                        int prevSize = 30;
429
                                        sp.setPreferredSize(new Dimension(prevSize, prevSize));
430
                                        sp.setSymbol(sym);
431
                                        sp.setBackground(bgColor);
432
                                        sym.setSize(prevSize*.8);
433
//                                        sym.setVisuallyCorrected(getChkAdjustGlyph().isSelected());
434
                                        pnl.add(sp);
435
                                        JLabel lbl = new JLabel(sym.getDescription());
436
                                        lbl.setBackground(bgColor);
437
                                        lbl.setAlignmentX(Component.CENTER_ALIGNMENT);
438
                                        pnl.add(lbl);
439

    
440
                                        return pnl;
441
                                }
442
                        };
443
                        jListSymbols.setCellRenderer(renderer);
444
                }
445
                return jListSymbols;
446
        }
447

    
448

    
449
        public String getName() {
450
                return PluginServices.getText(this, "character_marker_symbol");
451
        }
452

    
453
        public JPanel[] getTabs() {
454
                return (JPanel[]) tabs .toArray(new JPanel[0]);
455
        }
456

    
457
        public void refreshControls(ISymbol layer) {
458
                CharacterMarkerSymbol sym;
459
                try {
460
                        sym = (CharacterMarkerSymbol) layer;
461
                        font = sym.getFont();
462
                        unicode = sym.getUnicode();
463
                        getTxtXOffset().setDouble( sym.getOffset().getX() );
464
                        getTxtYOffset().setDouble( -sym.getOffset().getY() );
465

    
466
                        getColorChooser().setColor(sym.getColor());
467

    
468
                        getCmbFonts().setSelectedItem(sym.getFont().getName());
469
                        getCmbFontSize().setSelectedItem(new Integer(sym.getFont().getSize()));
470
                        getJListSymbols().setSelectedIndex(sym.getUnicode());
471
                        getNumberAngle().setDouble( sym.getRotation()/FConstant.DEGREE_TO_RADIANS );
472

    
473

    
474

    
475

    
476
                        getChkAdjustGlyph().setSelected(sym.isVisuallyCorrected());
477
                        // TODO mask
478
                } catch (IndexOutOfBoundsException ioEx) {
479
                        NotificationManager.addWarning("Symbol layer index out of bounds", ioEx);
480
                } catch (ClassCastException ccEx) {
481
                        NotificationManager.addWarning("Illegal casting from " +
482
                                        layer.getClassName() + " to " + getSymbolClass().
483
                                        getName() + ".", ccEx);
484

    
485
                }
486

    
487
        }
488

    
489
        public Class<? extends ISymbol> getSymbolClass() {
490
                return CharacterMarkerSymbol.class;
491
        }
492

    
493
        public ISymbol getLayer() {
494
                CharacterMarkerSymbol layer = new CharacterMarkerSymbol();
495
                if (font == null) {
496
                        font = new Font((String) getCmbFonts().getSelectedItem(),
497
                                                         Font.PLAIN,
498
                                                   (int) getCmbFontSize().getSelectedValue());
499
                }
500
                layer.setFont(font);
501
                layer.setUnicode(unicode);
502
                layer.setColor(getColorChooser().getColor());
503
                layer.setSize(getCmbFontSize().getSelectedValue());
504
                layer.setOffset(new Point2D.Double(
505
                                getTxtXOffset().getDouble(),
506
                                -getTxtYOffset().getDouble()));
507
                layer.setRotation(getNumberAngle().getDouble()*FConstant.DEGREE_TO_RADIANS);
508

    
509
                layer.setUnit(owner.getUnit());
510
                layer.setReferenceSystem(owner.getUnitsReferenceSystem());
511
                layer.setMask(mask.getMask());
512
                layer.setVisuallyCorrected(getChkAdjustGlyph().isSelected());
513
                return layer;
514
        }
515

    
516
        /**
517
         * Creates a list with the specified items.
518
         *
519
         */
520
        private class CharacterListModel implements ListModel {
521

    
522
                private Font font;
523
                private ArrayList<ListDataListener> listeners;
524

    
525
                /**
526
                 * constructor method
527
                 * @param font
528
                 */
529
                public CharacterListModel(Font font) {
530
                        this.font = font;
531
                }
532

    
533
                public int getSize() {
534
                        return font.getNumGlyphs();
535
                }
536

    
537
                public Object getElementAt(int index) {
538
                        return new CharacterItem(font, index);
539
                }
540

    
541
                public void addListDataListener(ListDataListener l) {
542
                        if (listeners == null)
543
                                listeners = new ArrayList<ListDataListener>();
544
                        listeners.add(l);
545
                }
546

    
547
                public void removeListDataListener(ListDataListener l) {
548
                        if (listeners!=null)
549
                                listeners.remove(l);
550
                }
551
        }
552

    
553
        private class CharacterItem {
554
                int glyph;
555
                Font font;
556
                public CharacterItem(Font font, int glyph) {
557
                        this.font = font;
558
                        this.glyph = glyph;
559
                }
560
        }
561

    
562
        public void actionPerformed(ActionEvent e) {
563
                JComponent c = (JComponent) e.getSource();
564
                if (c.equals(getCmbFonts())) {
565
                        String fontName = (String) getCmbFonts().getSelectedItem();
566
                        getJListSymbols().setModel(
567
                                        new CharacterListModel(
568
                                                        new Font(fontName, Font.PLAIN, 10)));
569
                        return;
570
                }
571

    
572
                fireSymbolChangedEvent();
573
        }
574

    
575
        public EditorTool[] getEditorTools() {
576
                return null;
577
        }
578
}