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 | 40559 | jjdelcerro | /**
|
---|---|---|---|
2 | * gvSIG. Desktop Geographic Information System.
|
||
3 | 40435 | jjdelcerro | *
|
4 | 40559 | jjdelcerro | * Copyright (C) 2007-2013 gvSIG Association.
|
5 | 40435 | jjdelcerro | *
|
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 | 40559 | jjdelcerro | * as published by the Free Software Foundation; either version 3
|
9 | 40435 | jjdelcerro | * 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 | 41621 | jjdelcerro | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14 | 40435 | jjdelcerro | * 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 | 41621 | jjdelcerro | * MA 02110-1301, USA.
|
20 | 40435 | jjdelcerro | *
|
21 | 40559 | jjdelcerro | * For any additional information, do not hesitate to contact us
|
22 | * at info AT gvsig.com, or visit our website www.gvsig.com.
|
||
23 | 40435 | jjdelcerro | */
|
24 | |||
25 | 42775 | jjdelcerro | package org.gvsig.fmap.dal.swing.impl.featuretable; |
26 | |||
27 | 40435 | jjdelcerro | import java.awt.BorderLayout; |
28 | 41611 | jjdelcerro | import java.awt.Component; |
29 | 41621 | jjdelcerro | import java.awt.Dimension; |
30 | 42775 | jjdelcerro | import java.awt.event.ActionEvent; |
31 | import java.awt.event.ActionListener; |
||
32 | 41621 | jjdelcerro | import java.beans.PropertyChangeEvent; |
33 | import java.beans.PropertyChangeListener; |
||
34 | 41611 | jjdelcerro | import javax.swing.AbstractListModel; |
35 | import javax.swing.JButton; |
||
36 | 42775 | jjdelcerro | import javax.swing.JComponent; |
37 | 40435 | jjdelcerro | |
38 | import javax.swing.JLabel; |
||
39 | 41611 | jjdelcerro | import javax.swing.JList; |
40 | 40435 | jjdelcerro | import javax.swing.JPanel; |
41 | import javax.swing.JScrollPane; |
||
42 | 41611 | jjdelcerro | import javax.swing.JTable; |
43 | import javax.swing.ListCellRenderer; |
||
44 | import javax.swing.ListModel; |
||
45 | 41621 | jjdelcerro | import javax.swing.SwingUtilities; |
46 | 41611 | jjdelcerro | import javax.swing.UIManager; |
47 | 41621 | jjdelcerro | import javax.swing.event.TableModelEvent; |
48 | import javax.swing.event.TableModelListener; |
||
49 | 41611 | jjdelcerro | import javax.swing.table.JTableHeader; |
50 | 41621 | jjdelcerro | import javax.swing.table.TableModel; |
51 | 40435 | jjdelcerro | |
52 | import org.gvsig.fmap.dal.DataStoreNotification; |
||
53 | 42808 | jbadia | import org.gvsig.fmap.dal.feature.FeatureSelection; |
54 | import org.gvsig.fmap.dal.feature.FeatureStore; |
||
55 | 42775 | jjdelcerro | import org.gvsig.fmap.dal.swing.FeatureTableModel; |
56 | import org.gvsig.fmap.dal.swing.JFeatureTable; |
||
57 | 40435 | jjdelcerro | import org.gvsig.i18n.Messages; |
58 | import org.gvsig.tools.observer.Observable; |
||
59 | import org.gvsig.tools.observer.Observer; |
||
60 | 41621 | jjdelcerro | import org.slf4j.Logger; |
61 | import org.slf4j.LoggerFactory; |
||
62 | 40435 | jjdelcerro | |
63 | /**
|
||
64 | * Panel to show a table of Feature data.
|
||
65 | 41621 | jjdelcerro | *
|
66 | 40435 | jjdelcerro | * @author <a href="mailto:cordin@disid.com">C?sar Ordi?ana</a>
|
67 | */
|
||
68 | 42775 | jjdelcerro | public class FeatureTablePanel extends JPanel implements Observer,JFeatureTable { |
69 | 40435 | jjdelcerro | |
70 | 41621 | jjdelcerro | private static final Logger logger = LoggerFactory.getLogger(FeatureTablePanel.class); |
71 | |||
72 | 40435 | jjdelcerro | private static final long serialVersionUID = -9199073063283531216L; |
73 | |||
74 | private FeatureTable table = null; |
||
75 | 42775 | jjdelcerro | private JScrollPane jScrollPane = null; |
76 | 40435 | jjdelcerro | private JPanel selectionPanel; |
77 | private JLabel selectionLabel; |
||
78 | |||
79 | 42775 | jjdelcerro | public FeatureTablePanel(FeatureTableModel tableModel,
|
80 | boolean isDoubleBuffered) {
|
||
81 | 40435 | jjdelcerro | super(isDoubleBuffered);
|
82 | 42805 | jbadia | table = new FeatureTable(tableModel);
|
83 | 42775 | jjdelcerro | this.initComonents();
|
84 | 40435 | jjdelcerro | tableModel.getFeatureStore().addObserver(this);
|
85 | 42808 | jbadia | 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 | 40435 | jjdelcerro | } |
95 | 42808 | jbadia | |
96 | private void featureSelectionChanged() { |
||
97 | ((FeatureTableModel)table.getModel()).getFeatureSelection().addObserver(this);
|
||
98 | } |
||
99 | 40435 | jjdelcerro | |
100 | 42775 | jjdelcerro | private void initComonents() { |
101 | this.setLayout(new BorderLayout()); |
||
102 | 40435 | jjdelcerro | |
103 | 42775 | jjdelcerro | table.setRowSelectionAllowed(true);
|
104 | table.setColumnSelectionAllowed(false);
|
||
105 | 40435 | jjdelcerro | |
106 | 42775 | jjdelcerro | jScrollPane = new JScrollPane(); |
107 | jScrollPane.setViewportView(table); |
||
108 | createTheRowHeader(); |
||
109 | 40435 | jjdelcerro | |
110 | 42775 | jjdelcerro | 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 | 40435 | jjdelcerro | |
122 | 42805 | jbadia | getFeatureTableModel().addTableModelListener(new TableModelListener() { |
123 | 42775 | jjdelcerro | @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 | 40435 | jjdelcerro | } |
139 | 42775 | jjdelcerro | |
140 | public void addColumnSelectionListener(ActionListener listener) { |
||
141 | this.table.addColumnSelectionListener(listener);
|
||
142 | 40435 | jjdelcerro | } |
143 | 42775 | jjdelcerro | |
144 | public void fireColumnSelection(ActionEvent e) { |
||
145 | this.table.fireColumnSelection(e);
|
||
146 | } |
||
147 | 40435 | jjdelcerro | |
148 | 42775 | jjdelcerro | @Override
|
149 | public void setModel(TableModel dataModel) { |
||
150 | this.table.setModel(dataModel);
|
||
151 | 40435 | jjdelcerro | } |
152 | |||
153 | 42775 | jjdelcerro | @Override
|
154 | public TableModel getModel() { |
||
155 | return this.table.getModel(); |
||
156 | } |
||
157 | 40435 | jjdelcerro | |
158 | 42775 | jjdelcerro | @Override
|
159 | public FeatureTableModel getFeatureTableModel() {
|
||
160 | 42805 | jbadia | return (FeatureTableModel) this.table.getModel(); |
161 | 42775 | jjdelcerro | } |
162 | |||
163 | @Override
|
||
164 | public int getSelectedColumnCount() { |
||
165 | return this.table.getSelectedColumnCount(); |
||
166 | 40435 | jjdelcerro | } |
167 | |||
168 | 42775 | jjdelcerro | @Override
|
169 | public int[] getSelectedColumns() { |
||
170 | return this.table.getSelectedColumns(); |
||
171 | 40435 | jjdelcerro | } |
172 | 42775 | jjdelcerro | |
173 | private String getSelectionLabel() { |
||
174 | String label =
|
||
175 | 42805 | jbadia | getFeatureTableModel().getSelectionCount() + |
176 | 42775 | jjdelcerro | " / " +
|
177 | 42805 | jbadia | getFeatureTableModel().getRowCount() + |
178 | 42775 | jjdelcerro | " " +
|
179 | Messages.getText("registros_seleccionados_total") +
|
||
180 | ".";
|
||
181 | return label;
|
||
182 | 40435 | jjdelcerro | } |
183 | 42775 | jjdelcerro | |
184 | private void createTheRowHeader() { |
||
185 | 41621 | jjdelcerro | // 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 | 42775 | jjdelcerro | @Override
|
196 | 41621 | jjdelcerro | public void run() { |
197 | 42775 | jjdelcerro | if( table.getRowCount()<1 ) { |
198 | jScrollPane.setRowHeaderView(null);
|
||
199 | return;
|
||
200 | } |
||
201 | 41621 | jjdelcerro | ListModel lm = new AbstractListModel() { |
202 | 42775 | jjdelcerro | private static final long serialVersionUID = -310252331647118271L; |
203 | @Override
|
||
204 | 41621 | jjdelcerro | public int getSize() { |
205 | return table.getRowCount();
|
||
206 | } |
||
207 | |||
208 | 42775 | jjdelcerro | @Override
|
209 | 41621 | jjdelcerro | public Object getElementAt(int index) { |
210 | return String.valueOf(index + 1); |
||
211 | } |
||
212 | }; |
||
213 | final JList rowHeader = new JList(lm); |
||
214 | 41707 | jjdelcerro | rowHeader.setBackground(table.getTableHeader().getBackground()); |
215 | 41830 | jjdelcerro | rowHeader.setCellRenderer(new RowHeaderRenderer(table,rowHeader));
|
216 | 41621 | jjdelcerro | jScrollPane.setRowHeaderView(rowHeader); |
217 | } |
||
218 | }); |
||
219 | } |
||
220 | |||
221 | 42775 | jjdelcerro | @Override
|
222 | public JTable getJTable() { |
||
223 | return this.table; |
||
224 | } |
||
225 | |||
226 | @Override
|
||
227 | public JComponent asJComponent() { |
||
228 | return this; |
||
229 | } |
||
230 | |||
231 | 41611 | jjdelcerro | private static class RowHeaderRenderer extends JButton implements ListCellRenderer { |
232 | 42775 | jjdelcerro | private static final long serialVersionUID = -3811876981965840126L; |
233 | 41621 | jjdelcerro | private JTable table = null; |
234 | private final Dimension dimension = new Dimension(); |
||
235 | 42775 | jjdelcerro | private final JList rowHeader; |
236 | 41830 | jjdelcerro | |
237 | RowHeaderRenderer(JTable table,JList rowHeader) { |
||
238 | 41621 | jjdelcerro | 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 | 41830 | jjdelcerro | this.rowHeader = rowHeader;
|
247 | 41611 | jjdelcerro | } |
248 | |||
249 | 42775 | jjdelcerro | @Override
|
250 | 41611 | jjdelcerro | public Component getListCellRendererComponent(JList list, Object value, |
251 | 41621 | jjdelcerro | int index, boolean isSelected, boolean cellHasFocus) { |
252 | setText((value == null) ? "" : value.toString()); |
||
253 | 41830 | jjdelcerro | this.setPreferredSize(null); // Fuerza recalcular el tama?o del boton |
254 | 41621 | jjdelcerro | this.dimension.height = this.table.getRowHeight(index); |
255 | 41830 | jjdelcerro | this.dimension.width = this.getPreferredSize().width+10; |
256 | 41621 | jjdelcerro | this.setPreferredSize(this.dimension); |
257 | return this; |
||
258 | 41611 | jjdelcerro | } |
259 | 41621 | jjdelcerro | |
260 | 41611 | jjdelcerro | } |
261 | |||
262 | 42775 | jjdelcerro | @Override
|
263 | 40435 | jjdelcerro | public void update(Observable observable, Object notification) { |
264 | 42808 | jbadia | 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 | 40435 | jjdelcerro | } |
278 | 42775 | jjdelcerro | |
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 | 40435 | jjdelcerro | } |