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 @ 44644

History | View | Annotate | Download (10 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.slf4j.Logger;
61
import org.slf4j.LoggerFactory;
62

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
226
    @Override
227
    public JComponent asJComponent() {
228
        return this;
229
    }
230

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

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

    
260
    }
261

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

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

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