Statistics
| Revision:

root / branches / v2_0_0_prep / applications / appgvSIG / src / org / gvsig / app / project / documents / view / legend / gui / SymbolTable.java @ 29598

History | View | Annotate | Download (15.6 KB)

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

    
49
import java.awt.Component;
50
import java.awt.Dimension;
51
import java.awt.GridLayout;
52
import java.awt.Point;
53
import java.awt.Rectangle;
54
import java.awt.event.ActionListener;
55
import java.awt.event.MouseAdapter;
56
import java.awt.event.MouseEvent;
57
import java.util.ArrayList;
58
import java.util.Hashtable;
59

    
60
import javax.swing.JPanel;
61
import javax.swing.JScrollPane;
62
import javax.swing.event.ChangeEvent;
63
import javax.swing.table.DefaultTableModel;
64
import javax.swing.table.TableCellEditor;
65
import javax.swing.table.TableColumn;
66

    
67
import org.gvsig.andami.PluginServices;
68
import org.gvsig.andami.ui.mdiFrame.JMenuItem;
69
import org.gvsig.andami.ui.mdiFrame.JPopUpMenu;
70
import org.gvsig.app.project.documents.gui.SymbolCellEditor;
71
import org.gvsig.app.project.documents.gui.TableSymbolCellRenderer;
72
import org.gvsig.app.project.documents.view.legend.edition.gui.IntervalCellEditor;
73
import org.gvsig.app.project.documents.view.legend.edition.gui.ValueCellEditor;
74
import org.gvsig.fmap.mapcontext.rendering.legend.NullIntervalValue;
75
import org.gvsig.fmap.mapcontext.rendering.legend.NullUniqueValue;
76
import org.gvsig.fmap.mapcontext.rendering.legend.NullValue;
77
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
78
import org.gvsig.utils.swing.jtable.JTable;
79
import org.gvsig.utils.swing.jtable.TextFieldCellEditor;
80

    
81

    
82
/**
83
 * JPanel que contiene la tabla con los s?mbolos intervalos o valores y
84
 * etiquetado de estos valores.
85
 *
86
 * @author Vicente Caballero Navarro
87
 */
88
public class SymbolTable extends JPanel {
89
        private static final long serialVersionUID = -8694846716328735113L;
90
        private static Hashtable<String,TableCellEditor> cellEditors = new Hashtable<String,TableCellEditor>();
91

    
92
        public static final String VALUES_TYPE = "values";
93
        public static final String INTERVALS_TYPE = "intervals";
94
        private JTable table;
95
        private String type;
96
        private int shapeType;
97
        private OnTableMouseAdapter rightClickActions;
98

    
99
        /**
100
         * Crea un nuevo FSymbolTable.
101
         *
102
         * @param type
103
         *            tipo de valor si es intervalo: "intervals" y si es por
104
         *            valores: "values".
105
         */
106
        public SymbolTable(Component ownerComponent, String type, int shapeType) {
107
                super(new GridLayout(1, 0));
108
                this.type = type;
109
                this.shapeType = shapeType;
110

    
111
                rightClickActions = new OnTableMouseAdapter();
112
                table = new JTable();
113
                table.setModel(new MyTableModel());
114
                table.setPreferredScrollableViewportSize(new Dimension(480, 110));
115

    
116
                initializeCellEditors();
117

    
118
                // Create the scroll pane and add the table to it.
119
                JScrollPane scrollPane = new JScrollPane(table);
120

    
121
                // Set up column sizes.
122
                // initColumnSizes(table);
123
                setUpSymbolColumn(table, table.getColumnModel().getColumn(0));
124

    
125
                if(cellEditors.get(type) == null)
126
                        throw new Error("Symbol table type not set!");
127

    
128
                setUpValueColumn(table, table.getColumnModel().getColumn(1),cellEditors.get(this.type));
129
                setUpLabelColumn(table, table.getColumnModel().getColumn(2));
130

    
131
                // Add the scroll pane to this panel.
132
                add(scrollPane);
133
                table.setRowSelectionAllowed(true);
134
                table.addMouseListener(rightClickActions);
135
        }
136
        /**
137
         * Inicializa los valores de los CellEditors que la SymbolTable poseer? por defecto
138
         */
139
        private void initializeCellEditors() {
140
                this.cellEditors.put(this.INTERVALS_TYPE,new IntervalCellEditor());
141
                this.cellEditors.put(this.VALUES_TYPE, new ValueCellEditor());
142
        }
143
        /**
144
         * A?ade un nuevo CellEditor a la lista de disponibles
145
         *
146
         * @param key String con el nombre identificativo del CellEditor
147
         * @param cellEditor CellEditor que va a ser a?adido
148
         */
149
        public static void addNewCellEditor(String key,TableCellEditor cellEditor ) {
150
                cellEditors.put(key, cellEditor);
151
        }
152
        /**
153
         * Obtiene el valor de los elementos de una fila seleccionada
154
         *
155
         * @return Object[] Array con los objetos de cada una de las columnas de la fila seleccionada
156
         */
157
        public Object[] getSelectedRowElements() {
158
                Object[] values = new Object[3];
159

    
160
                MyTableModel m = (MyTableModel) table.getModel();
161
                int[] selectedRows = table.getSelectedRows();
162

    
163
                if(selectedRows.length != 1)
164
                        return null;
165

    
166
                for (int i = 0; i < 3; i++) {
167
                        values[i] = m.getValueAt(selectedRows[0], i);
168
                }
169

    
170
                return values;
171
        }
172
        /**
173
         * A?ade una fila al modelo.
174
         *
175
         * @param vector
176
         *            Fila en forma de vector de Object para a?adir al modelo.
177
         */
178
        public void addRow(Object[] vector) {
179
                MyTableModel m = (MyTableModel) table.getModel();
180
                m.addRow(vector);
181

    
182
        }
183

    
184
        /**
185
         * Elimina la fila que tiene como clave el objeto que se pasa como
186
         * par?metro.
187
         *
188
         * @param obj
189
         *            clave del objeto a eliminar.
190
         */
191
        public void removeRow(Object obj) {
192
                MyTableModel m = (MyTableModel) table.getModel();
193

    
194
                for (int i = 0; i < m.getRowCount(); i++) {
195
                        if (m.getValueAt(i, 1) instanceof NullUniqueValue
196
                                        || m.getValueAt(i, 1) instanceof NullIntervalValue) {
197
                                m.removeRow(i);
198
                        }
199
                }
200
        }
201

    
202
        /**
203
         * Elimina las filas que est?n seleccionadas.
204
         */
205
        public void removeSelectedRows() {
206
                if (table.getCellEditor() != null) {
207
                        table.getCellEditor().cancelCellEditing();
208
                }
209

    
210
                MyTableModel m = (MyTableModel) table.getModel();
211
                int[] selectedRows = table.getSelectedRows();
212

    
213
                for (int i = selectedRows.length - 1; i >= 0; i--) {
214
                        m.removeRow(selectedRows[i]);
215
                }
216
        }
217

    
218
        /**
219
         * Rellena la tabla con los s?mbolos valores y descripciones que se pasan
220
         * como par?metro.
221
         *
222
         * @param symbols
223
         *            Array de s?mbolos
224
         * @param values
225
         *            Array de valores.
226
         * @param descriptions
227
         *            Array de descripciones.
228
         */
229
        public void fillTableFromSymbolList(ISymbol[] symbols, Object[] values,
230
                        String[] descriptions) {
231
                ISymbol theSymbol;
232

    
233
                for (int i = 0; i < symbols.length; i++) {
234
                        theSymbol = symbols[i];
235
                        if(!(values[i] instanceof NullIntervalValue) && !(values[i] instanceof NullUniqueValue))
236
                                addTableRecord(theSymbol, values[i], descriptions[i]);
237
                }
238
        }
239

    
240
        /**
241
         * A?ade una fila con los objetos que se pasan como par?metros.
242
         *
243
         * @param symbol
244
         *            s?mbolo de la fila.
245
         * @param value
246
         *            Valor de la fila.
247
         * @param description
248
         *            Descripci?n.
249
         */
250
        public void addTableRecord(ISymbol symbol, Object value, String description) {
251
                Object[] theRow = new Object[3];
252
                theRow[0] = symbol;
253
                theRow[1] = value;
254
                theRow[2] = description;
255
                addRow(theRow);
256
        }
257

    
258
        /**
259
         * Devuelve el valor a partie del n?mero de fila y columna.
260
         *
261
         * @param row
262
         *            n?mero de fila.
263
         * @param col
264
         *            n?mero de columna.
265
         *
266
         * @return Objeto.
267
         */
268
        public Object getFieldValue(int row, int col) {
269
                MyTableModel m = (MyTableModel) table.getModel();
270

    
271
                return m.getValueAt(row, col);
272
        }
273

    
274
        /**
275
         * Devuelve el n?mero total de filas que contiene el modelo.
276
         *
277
         * @return N?mero de filas.
278
         */
279
        public int getRowCount() {
280
                MyTableModel m = (MyTableModel) table.getModel();
281

    
282
                return m.getRowCount();
283
        }
284

    
285
        /**
286
         * Elimina todas las filas del modelo.
287
         */
288
        public void removeAllItems() {
289
                table.setModel(new MyTableModel());
290
                setUpSymbolColumn(table, table.getColumnModel().getColumn(0));
291
                setUpValueColumn(table, table.getColumnModel().getColumn(1),cellEditors.get(this.type));
292
                setUpLabelColumn(table, table.getColumnModel().getColumn(2));
293
        }
294

    
295
        /**
296
         * Inicializa el cell editor de tipo descripci?n de la columna que se pasa
297
         * como par?metro.
298
         *
299
         * @param table2
300
         *            Tabla.
301
         * @param column
302
         *            Columna.
303
         */
304
        public void setUpLabelColumn(JTable table2, TableColumn column) {
305
                TextFieldCellEditor labeleditor = new TextFieldCellEditor();
306
                column.setCellEditor(labeleditor);
307
        }
308

    
309
        /**
310
         * Inicializa el cell editor de tipo valor de la columna que se pasa como
311
         * par?metro.
312
         *
313
         * @param table2
314
         *            Tabla.
315
         * @param column
316
         *            Columna.
317
         * @param tableCellEditor
318
         */
319
        public void setUpValueColumn(JTable table2,TableColumn column, TableCellEditor tableCellEditor) {
320
                column.setCellEditor(tableCellEditor);
321
        }
322
        /**
323
         * Inicializa el cell editor de tipo s?mbolo de la columna que se pasa como
324
         * par?metro.
325
         *
326
         * @param table2
327
         *            Tabla.
328
         * @param column
329
         *            Columna.
330
         */
331
        public void setUpSymbolColumn(JTable table2, TableColumn column) {
332
                // Set up the editor
333
                column.setMaxWidth(100);
334
                column.setWidth(60);
335
                column.setPreferredWidth(60);
336
                column.setMinWidth(50);
337

    
338
                // FSymbolCellEditor symboleditor = new FSymbolCellEditor();
339
                SymbolCellEditor symboleditor = new SymbolCellEditor(shapeType);
340
                column.setCellEditor(symboleditor);
341

    
342
                TableSymbolCellRenderer renderer = new TableSymbolCellRenderer(true);
343
                column.setCellRenderer(renderer);
344
        }
345

    
346
        /**
347
         * Modelo que propio que se aplica a la tabla.
348
         *
349
         * @author Vicente Caballero Navarro
350
         */
351
        class MyTableModel extends DefaultTableModel {
352
                private static final long serialVersionUID = 1L;
353

    
354
                // AbstractTableModel {
355
                private String[] columnNames = {
356
                                PluginServices.getText(this, "Simbolo"),
357
                                PluginServices.getText(this, "Valor"),
358
                                PluginServices.getText(this, "Etiqueta") };
359

    
360
                /**
361
                 * Devuelve el n?mero de columnas.
362
                 *
363
                 * @return N?mero de columnas.
364
                 */
365
                public int getColumnCount() {
366
                        return columnNames.length;
367
                }
368

    
369
                /**
370
                 * Devuelve el String del valor de la columna.
371
                 *
372
                 * @param col
373
                 *            N?mero de columna.
374
                 *
375
                 * @return Nombre de la columna.
376
                 */
377
                public String getColumnName(int col) {
378
                        return columnNames[col];
379
                }
380

    
381
                /**
382
                 * JTable uses this method to determine the default renderer/ editor for
383
                 * each cell. If we didn't implement this method, then the last column
384
                 * would contain text ("true"/"false"), rather than a check box.
385
                 */
386
                public Class getColumnClass(int c) {
387
                        if (getValueAt(0, c) == null) {
388
                                return NullValue.class;
389
                        }
390

    
391
                        return getValueAt(0, c).getClass();
392
                }
393

    
394
                /*
395
                 * Don't need to implement this method unless your table's editable.
396
                 */
397
                public boolean isCellEditable(int row, int col) {
398
                        // Note that the data/cell address is constant,
399
                        // no matter where the cell appears onscreen.
400
                        // if (col > 0) {
401
                        return true;
402
                }
403

    
404
                @Override
405
                public Object getValueAt(int row, int column) {
406
                        if(column == 2)
407
                                return ((ISymbol)getValueAt(row,0)).getDescription();
408

    
409
                        return super.getValueAt(row, column);
410
                }
411

    
412
                @Override
413
                public void setValueAt(Object aValue, int row, int column) {
414

    
415
                        if(column == 2){
416
                                ISymbol symbol = (ISymbol) getValueAt(row,0);
417
                                symbol.setDescription((String) aValue);
418
                                setValueAt(symbol,row,0);
419
                        }
420

    
421
                        super.setValueAt(aValue, row, column);
422
                }
423

    
424
        }
425

    
426
        private class OnTableMouseAdapter extends MouseAdapter {
427

    
428
                private JPopUpMenu menu = new JPopUpMenu();
429

    
430
                // group option
431
                private JMenuItem groupItem = new JMenuItem(
432
                                PluginServices.getText(this, "group"));
433
                private ActionListener groupAction = new ActionListener() {
434
                        public void actionPerformed(java.awt.event.ActionEvent e) {
435
                                hidePopUp();
436
                                int[] selectedRows = table.getSelectedRows();
437
                                if (selectedRows.length > 1) {
438
                                        DefaultTableModel model = (DefaultTableModel) table
439
                                                        .getModel();
440
                                        int theRow = selectedRows[0];
441
                                        ISymbol symboToBeApplied = (ISymbol) model.getValueAt(
442
                                                        theRow, 0);
443
                                        String labelToBeApplied = (String) model.getValueAt(
444
                                                        theRow, 2);
445
                                        ArrayList<Object> valuesToBeApplied = new ArrayList<Object>(
446
                                                        selectedRows.length);
447
                                        for (int i = 0; i < selectedRows.length; i++) {
448
                                                valuesToBeApplied.add(model.getValueAt(selectedRows[i],
449
                                                                1));
450
                                        }
451

    
452
                                        for (int i = selectedRows.length - 1; i > 0; i--) {
453
                                                model.removeRow(selectedRows[i]);
454
                                        }
455

    
456
                                        model.setValueAt(symboToBeApplied, theRow, 0);
457
                                        model.setValueAt(labelToBeApplied, theRow, 2);
458
                                        table.clearSelection();
459
                                        table.doLayout();
460
                                }
461
                        }
462
                };
463

    
464
                // combine option
465
                private JMenuItem combineItem = new JMenuItem(
466
                                PluginServices.getText(this, "combine"));
467
                private ActionListener combineAction = new ActionListener() {
468
                        public void actionPerformed(java.awt.event.ActionEvent e) {
469
                                hidePopUp();
470
                                int[] selectedRows = table.getSelectedRows();
471
                                if (selectedRows.length > 1) {
472
                                        DefaultTableModel model = (DefaultTableModel) table
473
                                                        .getModel();
474
                                        int theRow = selectedRows[0];
475
                                        ISymbol symboToBeApplied = (ISymbol) model.getValueAt(
476
                                                        theRow, 0);
477
                                        String labelToBeApplied = (String) model.getValueAt(
478
                                                        theRow, 2);
479
                                        ArrayList<Object> valuesToBeApplied = new ArrayList<Object>(
480
                                                        selectedRows.length);
481
                                        for (int i = 0; i < selectedRows.length; i++) {
482
                                                valuesToBeApplied.add(model.getValueAt(selectedRows[i],
483
                                                                1));
484
                                        }
485

    
486
                                        for (int i = selectedRows.length - 1; i > 0; i--) {
487
                                                model.removeRow(selectedRows[i]);
488
                                        }
489

    
490
                                        model.setValueAt(symboToBeApplied, theRow, 0);
491
                                        model.setValueAt(labelToBeApplied, theRow, 2);
492
                                        table.clearSelection();
493
                                        table.doLayout();
494
                                }
495
                        }
496
                };
497

    
498
                private boolean menuEmpty = false;
499

    
500

    
501
                {
502
                        groupItem.addActionListener(groupAction);
503
                        if (VALUES_TYPE.equals(type)) {
504
                                menu.add(groupItem);
505
                        } else if (INTERVALS_TYPE.equals(type)) {
506
                                menu.add(combineItem);
507
                        } else {
508
                                menuEmpty = true;
509
                        }
510

    
511
                }
512

    
513
                @Override
514
                public void mouseExited(MouseEvent e) {
515
                        // if we click outside the popup menu
516
                        if (menu.isVisible()) {
517
                                Rectangle tableBounds = table.getBounds();
518
                                tableBounds.setLocation(table.getLocationOnScreen());
519
                                if (!tableBounds.contains(getClickLocation(e))) {
520
                                        hidePopUp();
521
                                }
522
                        }
523

    
524
                }
525

    
526
                @Override
527
                public void mouseClicked(MouseEvent e) {
528
                        super.mouseClicked(e);
529

    
530
                        // if we click outside the popup menu
531
                        if (menu.isVisible()
532
                                        && !menu.getBounds().contains(getClickLocation(e))) {
533
                                hidePopUp();
534
                        }
535

    
536
                        if (e.getButton() == MouseEvent.BUTTON3) {
537
                                e.consume();
538
                                int[] selectedRows = table.getSelectedRows();
539
                                if (selectedRows.length > 0) {
540
                                        Point realClickLocation = getClickLocation(e);
541
                                        menu.setLocation(realClickLocation);
542
                                        showPopUp();
543
                                }
544
                        }
545

    
546
                }
547

    
548
                private void showPopUp() {
549
                        if (!menuEmpty) {
550
                                table.setEnabled(false);
551
                                table.editingCanceled(new ChangeEvent(table));
552
                                menu.setVisible(true);
553
                        }
554
                }
555

    
556
                private void hidePopUp() {
557
                        if (!menuEmpty ) {
558
                                menu.setVisible(false);
559
                                table.setEnabled(true);
560
                        }
561
                }
562

    
563
                private Point getClickLocation(MouseEvent e) {
564
                        Point tableLocation = table.getLocationOnScreen();
565
                        Point relativeClickPoint = e.getPoint();
566
                        Point realClickLocation = new Point(tableLocation.x
567
                                        + relativeClickPoint.x, tableLocation.y
568
                                        + relativeClickPoint.y);
569
                        return realClickLocation;
570
                }
571

    
572
        }
573

    
574
}