Statistics
| Revision:

root / trunk / applications / appgvSIG / src / com / iver / cit / gvsig / project / documents / view / legend / gui / SymbolTable.java @ 20779

History | View | Annotate | Download (15.1 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 com.iver.cit.gvsig.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 com.hardcode.gdbms.engine.values.NullValue;
68
import com.iver.andami.PluginServices;
69
import com.iver.andami.ui.mdiFrame.JMenuItem;
70
import com.iver.andami.ui.mdiFrame.JPopUpMenu;
71
import com.iver.cit.gvsig.fmap.core.symbols.ISymbol;
72
import com.iver.cit.gvsig.fmap.rendering.NullIntervalValue;
73
import com.iver.cit.gvsig.fmap.rendering.NullUniqueValue;
74
import com.iver.cit.gvsig.project.documents.gui.SymbolCellEditor;
75
import com.iver.cit.gvsig.project.documents.gui.TableSymbolCellRenderer;
76
import com.iver.cit.gvsig.project.documents.view.legend.edition.gui.IntervalCellEditor;
77
import com.iver.cit.gvsig.project.documents.view.legend.edition.gui.ValueCellEditor;
78
import com.iver.utiles.swing.jtable.JTable;
79
import com.iver.utiles.swing.jtable.TextFieldCellEditor;
80

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

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

    
98
        /**
99
         * Crea un nuevo FSymbolTable.
100
         * 
101
         * @param type
102
         *            tipo de valor si es intervalo: "intervals" y si es por
103
         *            valores: "values".
104
         */
105
        public SymbolTable(Component ownerComponent, String type, int shapeType) {
106
                super(new GridLayout(1, 0));
107
                this.type = type;
108
                this.shapeType = shapeType;
109
                
110
                rightClickActions = new OnTableMouseAdapter();
111
                table = new JTable();
112
                table.setModel(new MyTableModel());
113
                table.setPreferredScrollableViewportSize(new Dimension(480, 110));
114
                
115
                initializeCellEditors();
116
                
117
                // Create the scroll pane and add the table to it.
118
                JScrollPane scrollPane = new JScrollPane(table);
119

    
120
                // Set up column sizes.
121
                // initColumnSizes(table);
122
                setUpSymbolColumn(table, table.getColumnModel().getColumn(0));
123
                
124
                if(cellEditors.get(type) == null)
125
                        throw new Error("Symbol table type not set!");
126
                        
127
                setUpValueColumn(table, table.getColumnModel().getColumn(1),cellEditors.get(this.type));
128
                setUpLabelColumn(table, table.getColumnModel().getColumn(2));
129

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

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

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

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

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

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

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

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

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

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

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

    
232
                for (int i = 0; i < symbols.length; i++) {
233
                        theSymbol = symbols[i];
234
                        addTableRecord(theSymbol, values[i], descriptions[i]);
235
                }
236
        }
237

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

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

    
269
                return m.getValueAt(row, col);
270
        }
271

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

    
280
                return m.getRowCount();
281
        }
282

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

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

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

    
336
                // FSymbolCellEditor symboleditor = new FSymbolCellEditor();
337
                SymbolCellEditor symboleditor = new SymbolCellEditor(shapeType);
338
                column.setCellEditor(symboleditor);
339

    
340
                TableSymbolCellRenderer renderer = new TableSymbolCellRenderer(true);
341
                column.setCellRenderer(renderer);
342
        }
343

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

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

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

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

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

    
389
                        return getValueAt(0, c).getClass();
390
                }
391

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

    
402
        }
403
        
404
        private class OnTableMouseAdapter extends MouseAdapter {
405

    
406
                private JPopUpMenu menu = new JPopUpMenu();
407

    
408
                // group option
409
                private JMenuItem groupItem = new JMenuItem(
410
                                PluginServices.getText(this, "group"));
411
                private ActionListener groupAction = new ActionListener() {
412
                        public void actionPerformed(java.awt.event.ActionEvent e) {
413
                                hidePopUp();
414
                                int[] selectedRows = table.getSelectedRows();
415
                                if (selectedRows.length > 1) {
416
                                        DefaultTableModel model = (DefaultTableModel) table
417
                                                        .getModel();
418
                                        int theRow = selectedRows[0];
419
                                        ISymbol symboToBeApplied = (ISymbol) model.getValueAt(
420
                                                        theRow, 0);
421
                                        String labelToBeApplied = (String) model.getValueAt(
422
                                                        theRow, 2);
423
                                        ArrayList<Object> valuesToBeApplied = new ArrayList<Object>(
424
                                                        selectedRows.length);
425
                                        for (int i = 0; i < selectedRows.length; i++) {
426
                                                valuesToBeApplied.add(model.getValueAt(selectedRows[i],
427
                                                                1));
428
                                        }
429

    
430
                                        for (int i = selectedRows.length - 1; i > 0; i--) {
431
                                                model.removeRow(selectedRows[i]);
432
                                        }
433
                                        
434
                                        model.setValueAt(symboToBeApplied, theRow, 0);
435
                                        model.setValueAt(labelToBeApplied, theRow, 2);
436
                                        table.clearSelection();
437
                                        table.doLayout();
438
                                }
439
                        }
440
                };
441

    
442
                // combine option
443
                private JMenuItem combineItem = new JMenuItem(
444
                                PluginServices.getText(this, "combine"));
445
                private ActionListener combineAction = new ActionListener() {
446
                        public void actionPerformed(java.awt.event.ActionEvent e) {
447
                                hidePopUp();
448
                                int[] selectedRows = table.getSelectedRows();
449
                                if (selectedRows.length > 1) {
450
                                        DefaultTableModel model = (DefaultTableModel) table
451
                                                        .getModel();
452
                                        int theRow = selectedRows[0];
453
                                        ISymbol symboToBeApplied = (ISymbol) model.getValueAt(
454
                                                        theRow, 0);
455
                                        String labelToBeApplied = (String) model.getValueAt(
456
                                                        theRow, 2);
457
                                        ArrayList<Object> valuesToBeApplied = new ArrayList<Object>(
458
                                                        selectedRows.length);
459
                                        for (int i = 0; i < selectedRows.length; i++) {
460
                                                valuesToBeApplied.add(model.getValueAt(selectedRows[i],
461
                                                                1));
462
                                        }
463

    
464
                                        for (int i = selectedRows.length - 1; i > 0; i--) {
465
                                                model.removeRow(selectedRows[i]);
466
                                        }
467
                                        
468
                                        model.setValueAt(symboToBeApplied, theRow, 0);
469
                                        model.setValueAt(labelToBeApplied, theRow, 2);
470
                                        table.clearSelection();
471
                                        table.doLayout();
472
                                }
473
                        }
474
                };
475

    
476
                private boolean menuEmpty = false;
477

    
478

    
479
                {
480
                        groupItem.addActionListener(groupAction);
481
                        if (VALUES_TYPE.equals(type)) {
482
                                menu.add(groupItem);
483
                        } else if (INTERVALS_TYPE.equals(type)) {
484
                                menu.add(combineItem);
485
                        } else {
486
                                menuEmpty = true;
487
                        }
488
                                
489
                }
490

    
491
                @Override
492
                public void mouseExited(MouseEvent e) {
493
                        // if we click outside the popup menu
494
                        if (menu.isVisible()) {
495
                                Rectangle tableBounds = table.getBounds();
496
                                tableBounds.setLocation(table.getLocationOnScreen());
497
                                if (!tableBounds.contains(getClickLocation(e))) {
498
                                        hidePopUp();
499
                                }
500
                        }
501

    
502
                }
503
                
504
                @Override
505
                public void mouseClicked(MouseEvent e) {
506
                        super.mouseClicked(e);
507

    
508
                        // if we click outside the popup menu
509
                        if (menu.isVisible()
510
                                        && !menu.getBounds().contains(getClickLocation(e))) {
511
                                hidePopUp();
512
                        }
513

    
514
                        if (e.getButton() == MouseEvent.BUTTON3) {
515
                                e.consume();
516
                                int[] selectedRows = table.getSelectedRows();
517
                                if (selectedRows.length > 0) {
518
                                        Point realClickLocation = getClickLocation(e);
519
                                        menu.setLocation(realClickLocation);
520
                                        showPopUp();
521
                                }
522
                        }
523

    
524
                }
525

    
526
                private void showPopUp() {
527
                        if (!menuEmpty) {
528
                                table.setEnabled(false);
529
                                table.editingCanceled(new ChangeEvent(table));
530
                                menu.setVisible(true);
531
                        }
532
                }
533

    
534
                private void hidePopUp() {
535
                        if (!menuEmpty ) {
536
                                menu.setVisible(false);
537
                                table.setEnabled(true);
538
                        }
539
                }
540

    
541
                private Point getClickLocation(MouseEvent e) {
542
                        Point tableLocation = table.getLocationOnScreen();
543
                        Point relativeClickPoint = e.getPoint();
544
                        Point realClickLocation = new Point(tableLocation.x
545
                                        + relativeClickPoint.x, tableLocation.y
546
                                        + relativeClickPoint.y);
547
                        return realClickLocation;
548
                }
549

    
550
        }
551

    
552
}