Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.swing / org.gvsig.fmap.dal.swing.impl / src / main / java / org / gvsig / fmap / dal / swing / impl / featuretable / FeatureTablePanel.java @ 46723

History | View | Annotate | Download (10.2 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA 02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24

    
25
package org.gvsig.fmap.dal.swing.impl.featuretable;
26

    
27
import java.awt.BorderLayout;
28
import java.awt.Component;
29
import java.awt.Dimension;
30
import java.awt.event.ActionEvent;
31
import java.awt.event.ActionListener;
32
import java.beans.PropertyChangeEvent;
33
import java.beans.PropertyChangeListener;
34
import javax.swing.AbstractListModel;
35
import javax.swing.JButton;
36
import javax.swing.JComponent;
37

    
38
import javax.swing.JLabel;
39
import javax.swing.JList;
40
import javax.swing.JPanel;
41
import javax.swing.JScrollPane;
42
import javax.swing.JTable;
43
import javax.swing.ListCellRenderer;
44
import javax.swing.ListModel;
45
import javax.swing.SwingUtilities;
46
import javax.swing.UIManager;
47
import javax.swing.event.TableModelEvent;
48
import javax.swing.event.TableModelListener;
49
import javax.swing.table.JTableHeader;
50
import javax.swing.table.TableModel;
51

    
52
import org.gvsig.fmap.dal.DataStoreNotification;
53
import org.gvsig.fmap.dal.feature.FeatureSelection;
54
import org.gvsig.fmap.dal.feature.FeatureStore;
55
import org.gvsig.fmap.dal.swing.FeatureTableModel;
56
import org.gvsig.fmap.dal.swing.JFeatureTable;
57
import org.gvsig.i18n.Messages;
58
import org.gvsig.tools.observer.Observable;
59
import org.gvsig.tools.observer.Observer;
60
import org.gvsig.tools.swing.api.ToolsSwingLocator;
61
import org.slf4j.Logger;
62
import org.slf4j.LoggerFactory;
63

    
64
/**
65
 * Panel to show a table of Feature data.
66
 *
67
 * @author <a href="mailto:cordin@disid.com">C?sar Ordi?ana</a>
68
 */
69
public class FeatureTablePanel extends JPanel implements Observer,JFeatureTable {
70

    
71
    private static final Logger logger = LoggerFactory.getLogger(FeatureTablePanel.class);
72

    
73
    private static final long serialVersionUID = -9199073063283531216L;
74

    
75
    private FeatureTable table = null;
76
    private JScrollPane jScrollPane = null;
77
    private JPanel selectionPanel;
78
    private JLabel selectionLabel;
79

    
80
    public FeatureTablePanel(FeatureTableModel tableModel,
81
            boolean isDoubleBuffered)  {
82
        super(isDoubleBuffered);
83
        table = new FeatureTable(tableModel);
84
        this.initComonents();
85
        tableModel.getFeatureStore().addObserver(this);
86
        tableModel.getFeatureSelection().addObserver(this);
87
        tableModel.addChangeListener(new ActionListener() {
88
            @Override
89
            public void actionPerformed(ActionEvent e) {
90
                if( FeatureTableModel.CHANGE_SELECTION.equals(e.getActionCommand()) ) {
91
                    featureSelectionChanged();
92
                }
93
            }
94
        });        
95
    }
96
    
97
    private void featureSelectionChanged() {
98
        ((FeatureTableModel)table.getModel()).getFeatureSelection().addObserver(this);
99
    }
100

    
101
    private void initComonents() {
102
        this.setLayout(new BorderLayout());
103

    
104
        table.setRowSelectionAllowed(true);
105
        table.setColumnSelectionAllowed(false);
106

    
107
        jScrollPane = new JScrollPane();
108
        jScrollPane.setViewportView(table);
109
        createTheRowHeader();
110

    
111
        table.addPropertyChangeListener(new PropertyChangeListener() {
112
            @Override
113
            public void propertyChange(PropertyChangeEvent pce) {
114
                if( "RowHeight".equalsIgnoreCase(pce.getPropertyName())) {
115
                    // No he averigado como cambiar el ancho de las lineas
116
                    // ya creadas de la cabezera de lineas, asi que la
117
                    // reconstruyo entera cuando algo cambia.
118
                    createTheRowHeader();
119
                }
120
            }
121
        });
122

    
123
        getFeatureTableModel().addTableModelListener(new TableModelListener() {
124
            @Override
125
            public void tableChanged(TableModelEvent tme) {
126
                // No he averigado como cambiar el ancho de las lineas
127
                // ya creadas de la cabezera de lineas, asi que la
128
                // reconstruyo entera cuando algo cambia.
129
                createTheRowHeader();
130
            }
131
        });
132
        selectionLabel = new JLabel();
133
        selectionLabel.setText( this.getSelectionLabel() );
134
        selectionPanel = new JPanel();
135
        selectionPanel.add(selectionLabel, BorderLayout.EAST);
136
 
137
        this.add(jScrollPane, BorderLayout.CENTER);
138
        this.add(selectionPanel, BorderLayout.SOUTH);
139
        ToolsSwingLocator.getToolsSwingManager().createTableColumnAdjuster(table);
140
    }
141
    
142
    public void addColumnSelectionListener(ActionListener listener) {
143
       this.table.addColumnSelectionListener(listener);
144
    }
145
    
146
    public void fireColumnSelection(ActionEvent e) {
147
        this.table.fireColumnSelection(e);
148
    }    
149

    
150
    @Override
151
    public void setModel(TableModel dataModel) {
152
        this.table.setModel(dataModel);
153
    }
154

    
155
    @Override
156
    public TableModel getModel() {
157
        return this.table.getModel();
158
    }    
159

    
160
    @Override
161
    public FeatureTableModel getFeatureTableModel() {
162
        return (FeatureTableModel) this.table.getModel();
163
    }    
164
    
165
    @Override
166
    public int getSelectedColumnCount() {
167
        return this.table.getSelectedColumnCount();
168
    }
169

    
170
    @Override
171
    public int[] getSelectedColumns() {
172
        return this.table.getSelectedColumns();
173
    }
174
    
175
    private String getSelectionLabel() {
176
        String label =
177
                getFeatureTableModel().getSelectionCount() + 
178
            " / " +
179
            getFeatureTableModel().getRowCount() + 
180
            " " +
181
            Messages.getText("registros_seleccionados_total") + 
182
            ".";
183
        return label;
184
    }
185
    
186
    private void createTheRowHeader() {
187
        // No se si ha sido paranoia o que, pero parece que si la recreo sin mas
188
        // a veces parece como si no la cambiase, asi que he probado a encolarlo 
189
        // en la cola de eventos de swing y parece que siempre funciona.
190
        //
191
        // Cuando se estan mostrando las geometrias, que cada linea tiene un ancho
192
        // distinto, se le llama muchisimas veces;
193
        // habria que evaluar retenerlas por ejemplo durante un segundo y solo 
194
        // recrearlo entonces.
195
        SwingUtilities.invokeLater(new Runnable() {
196

    
197
            @Override
198
            public void run() {
199
                if( table.getRowCount()<1 ) {
200
                    jScrollPane.setRowHeaderView(null);
201
                    return;
202
                }
203
                ListModel lm = new AbstractListModel() {
204
                    private static final long serialVersionUID = -310252331647118271L;
205
                    @Override
206
                    public int getSize() {
207
                        return table.getRowCount();
208
                    }
209

    
210
                    @Override
211
                    public Object getElementAt(int index) {
212
                        return String.valueOf(index + 1);
213
                    }
214
                };
215
                final JList rowHeader = new JList(lm);
216
                rowHeader.setBackground(table.getTableHeader().getBackground());
217
                rowHeader.setCellRenderer(new RowHeaderRenderer(table,rowHeader));
218
                jScrollPane.setRowHeaderView(rowHeader);
219
            }
220
        });
221
    }
222

    
223
    @Override
224
    public JTable getJTable() {
225
        return this.table;
226
    }
227

    
228
    @Override
229
    public JComponent asJComponent() {
230
        return this;
231
    }
232

    
233
    private static class RowHeaderRenderer extends JButton implements ListCellRenderer {
234
        private static final long serialVersionUID = -3811876981965840126L;
235
        private JTable table = null;
236
        private final Dimension dimension = new Dimension();
237
        private final JList rowHeader;
238
        
239
        RowHeaderRenderer(JTable table,JList rowHeader) {
240
            JTableHeader header = table.getTableHeader();
241
            setOpaque(true);
242
            setBorder(UIManager.getBorder("TableHeader.cellBorder"));
243
            setHorizontalAlignment(CENTER);
244
            setForeground(header.getForeground());
245
            setBackground(header.getBackground());
246
            setFont(header.getFont());
247
            this.table = table;
248
            this.rowHeader = rowHeader;
249
        }
250

    
251
        @Override
252
        public Component getListCellRendererComponent(JList list, Object value,
253
                int index, boolean isSelected, boolean cellHasFocus) {
254
            setText((value == null) ? "" : value.toString());
255
            this.setPreferredSize(null); // Fuerza recalcular el tama?o del boton
256
            this.dimension.height = this.table.getRowHeight(index);
257
            this.dimension.width = this.getPreferredSize().width+10;
258
            this.setPreferredSize(this.dimension);
259
            return this;
260
        }
261

    
262
    }
263

    
264
    @Override
265
    public void update(Observable observable, Object notification) {
266
            if( observable instanceof FeatureSelection ) {
267
                    // Ha cambiado la seleccion, simplemente repintamos.
268
                    repaint();
269
                    return;
270
            }
271
            // If selection changes from nothing selected to anything selected
272
            // or the reverse, update selection info
273
            if( observable instanceof FeatureStore ) {
274
                    String type = ((DataStoreNotification) notification).getType();
275
                    if ( DataStoreNotification.SELECTION_CHANGE.equals(type) ) {
276
                            selectionLabel.setText( this.getSelectionLabel() );
277
                    }
278
            }
279
    }
280

    
281
    @Override
282
    public void setCurrent(int index) {
283
        logger.warn("setCurrent not implemented !!!!!!!!!!!!!!!!!!!!!!!!");
284
    }
285

    
286
    public void setVisibleStatusbar(boolean visible) {
287
        this.selectionPanel.setVisible(visible);
288
    }
289
    
290
    public boolean isVisibleStatusbar() {
291
        return this.selectionPanel.isVisible();
292
    }
293
}