Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.labeling.app / org.gvsig.labeling.app.mainplugin / src / main / java / org / gvsig / labeling / gui / styling / CharacterMarker.java @ 40911

History | View | Annotate | Download (16.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: 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.labeling.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.andami.messages.NotificationManager;
162
import org.gvsig.app.gui.panels.ColorChooserPanel;
163
import org.gvsig.app.gui.styling.AbstractTypeSymbolEditor;
164
import org.gvsig.app.gui.styling.EditorTool;
165
import org.gvsig.app.gui.styling.SymbolEditor;
166
import org.gvsig.app.gui.styling.SymbolPreviewer;
167
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
168
import org.gvsig.gui.beans.swing.GridBagLayoutPanel;
169
import org.gvsig.gui.beans.swing.JComboBoxFontSizes;
170
import org.gvsig.gui.beans.swing.JComboBoxFonts;
171
import org.gvsig.gui.beans.swing.JIncrementalNumberField;
172
import org.gvsig.i18n.Messages;
173
import org.gvsig.labeling.symbol.CharacterMarkerSymbol;
174
/**
175
* CharacterMarker allows the user to store and modify the properties that
176
* define a <b>character marker</b>.<p>
177
* <p>
178
* This functionality is carried out thanks to two tabs (character marker and mask)which
179
* are included in the panel to edit the properities of a symbol (SymbolEditor)how
180
* is explained in AbstractTypeSymbolEditor.<p>
181
* <p>
182
* The first tab (Character marker)allows the user to change the font (<b>cmbFonts</b>)of
183
* the symbol for the character marker, the size of that (<b>cmbFontSize</b>),the angle
184
*(<b>numberAngle</b>)if the user wants to show the character with some rotation,the color
185
* (<b>jcc</b>) and the offset (<b>txtYOffset,txtXOffset</b>).<p>
186
* <p>
187
* The second tab (<b>Mask</b>) modifies attributes of a mask for points such
188
*  as style,size and symbol (to represent a point in the map).<p>
189
*
190
*@see Mask
191
*@see AbstractTypeSymbolEditor
192
*@author jaume dominguez faus - jaume.dominguez@iver.es
193
*/
194
public class CharacterMarker extends AbstractTypeSymbolEditor
195
implements ActionListener {
196
        
197
        private ArrayList<JPanel> tabs = new ArrayList<JPanel>();
198
        private JList jListSymbols;
199
        private JScrollPane jScrollPane;
200
        private JComboBoxFonts cmbFonts;
201
        //TODO: Comentarizado hasta que mask est? acabado
202
//        private Mask mask;
203
        private JComboBoxFontSizes cmbFontSize;
204
        private JIncrementalNumberField numberAngle;
205
        private ColorChooserPanel jcc;
206
        private JIncrementalNumberField txtYOffset;
207
        private JIncrementalNumberField txtXOffset;
208
        private Font font;
209
        private int unicode;
210
        private JCheckBox chkAdjustGlyph;
211

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

    
236
                        JPanel aux = new JPanel(new BorderLayout(15, 15));
237
                        aux.add(new JLabel(Messages.getText("font")+":"), BorderLayout.NORTH);
238
                        aux.add(getCmbFonts(), BorderLayout.NORTH);
239

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

    
246
                        GridBagLayoutPanel aux1 = new GridBagLayoutPanel();
247
                        aux1.addComponent(Messages.getText("size")+":", getCmbFontSize());
248
                        aux1.addComponent(Messages.getText("angle")+":", getNumberAngle());
249

    
250
                        aux1.addComponent(Messages.getText("color")+":", getColorChooser());
251

    
252
                        GridBagLayoutPanel aux2 = new GridBagLayoutPanel();
253
                        aux2.addComponent("X:", getTxtXOffset());
254
                        aux2.addComponent("Y:", getTxtYOffset());
255
                        aux2.setBorder(BorderFactory.createTitledBorder(
256
                                        Messages.getText("offset")));
257
                        aux1.addComponent(aux2);
258

    
259
                        myTab.add(aux1, BorderLayout.EAST);
260
                        myTab.add(getChkAdjustGlyph(), BorderLayout.SOUTH);
261

    
262
                        tabs.add(myTab);
263
                }
264

    
265
                {
266
                        // Mask tab
267
//                        mask = new Mask(this);
268
//
269
//                        tabs.add(mask);
270
                }
271

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

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

    
291
                return chkAdjustGlyph;
292
        }
293

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

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

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

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

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

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

    
359
                }
360

    
361
                return numberAngle;
362
        }
363

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

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

    
405
                                public void valueChanged(ListSelectionEvent e) {
406
                                        CharacterItem theChar = (CharacterItem) jListSymbols.getSelectedValue();
407
                                        if (theChar == null) return;
408
                                        font = theChar.font;
409
                                        unicode = theChar.glyph;
410
                                        fireSymbolChangedEvent();
411
                                }
412
                        });
413
                        ListCellRenderer renderer = new ListCellRenderer() {
414
                                private Color mySelectedBGColor = new Color(255,145,100,255);
415
                                public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
416
                                        CharacterItem theChar = (CharacterItem) value;
417
                                        CharacterMarkerSymbol sym = new CharacterMarkerSymbol(
418
                                                        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 Messages.getText("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(
472
                                        // convert to degrees
473
                                        sym.getRotation() * 180.0 / Math.PI);
474

    
475
                        getChkAdjustGlyph().setSelected(sym.isVisuallyCorrected());
476
                        // TODO mask
477
                } catch (IndexOutOfBoundsException ioEx) {
478
                        NotificationManager.addWarning("Symbol layer index out of bounds", ioEx);
479
                } catch (ClassCastException ccEx) {
480
                        NotificationManager.addWarning(ccEx.getMessage(), ccEx);
481
                }
482

    
483
        }
484

    
485
        public Class<? extends ISymbol> getSymbolClass() {
486
                return CharacterMarkerSymbol.class;
487
        }
488

    
489
        public ISymbol getLayer() {
490
                CharacterMarkerSymbol layer = new CharacterMarkerSymbol();
491
                if (font == null) {
492
                        font = new Font((String) getCmbFonts().getSelectedItem(),
493
                                                         Font.PLAIN,
494
                                                   (int) getCmbFontSize().getSelectedValue());
495
                }
496
                layer.setFont(font);
497
                layer.setUnicode(unicode);
498
                layer.setColor(getColorChooser().getColor());
499
                layer.setSize(getCmbFontSize().getSelectedValue());
500
                layer.setOffset(new Point2D.Double(
501
                                getTxtXOffset().getDouble(),
502
                                -getTxtYOffset().getDouble()));
503
                layer.setRotation(
504
                                // convert to radians
505
                                getNumberAngle().getDouble() * Math.PI / 180.0); 
506

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

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

    
520
                private Font font;
521
                private ArrayList<ListDataListener> listeners;
522

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

    
531
                public int getSize() {
532
                        return font.getNumGlyphs();
533
                }
534

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

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

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

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

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

    
570
                fireSymbolChangedEvent();
571
        }
572

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

    
578
        public boolean canManageSymbol(ISymbol symbol) {
579
                return symbol instanceof CharacterMarkerSymbol;
580
        }
581
}