Revision 41621 trunk/org.gvsig.desktop/org.gvsig.desktop.library/org.gvsig.fmap.control/src/main/java/org/gvsig/fmap/mapcontrol/dal/feature/swing/FeatureTablePanel.java

View differences:

FeatureTablePanel.java
10 10
 *
11 11
 * This program is distributed in the hope that it will be useful,
12 12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 14
 * GNU General Public License for more details.
15 15
 *
16 16
 * You should have received a copy of the GNU General Public License
17 17
 * along with this program; if not, write to the Free Software
18 18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
19
 * MA 02110-1301, USA.
20 20
 *
21 21
 * For any additional information, do not hesitate to contact us
22 22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
......
28 28
package org.gvsig.fmap.mapcontrol.dal.feature.swing;
29 29

  
30 30
import java.awt.BorderLayout;
31
import static java.awt.BorderLayout.CENTER;
32 31
import java.awt.Component;
32
import java.awt.Dimension;
33
import java.awt.font.FontRenderContext;
34
import java.awt.geom.Rectangle2D;
35
import java.beans.PropertyChangeEvent;
36
import java.beans.PropertyChangeListener;
33 37
import javax.swing.AbstractListModel;
34 38
import javax.swing.JButton;
35 39

  
......
40 44
import javax.swing.JTable;
41 45
import javax.swing.ListCellRenderer;
42 46
import javax.swing.ListModel;
47
import javax.swing.SwingUtilities;
43 48
import javax.swing.UIManager;
49
import javax.swing.event.TableModelEvent;
50
import javax.swing.event.TableModelListener;
44 51
import javax.swing.table.JTableHeader;
52
import javax.swing.table.TableModel;
45 53

  
46 54
import org.gvsig.fmap.dal.DataStoreNotification;
47 55
import org.gvsig.fmap.dal.exception.DataException;
......
54 62
import org.gvsig.tools.exception.BaseException;
55 63
import org.gvsig.tools.observer.Observable;
56 64
import org.gvsig.tools.observer.Observer;
65
import org.slf4j.Logger;
66
import org.slf4j.LoggerFactory;
57 67

  
58 68
/**
59 69
 * Panel to show a table of Feature data.
60
 * 
70
 *
61 71
 * @author <a href="mailto:cordin@disid.com">C?sar Ordi?ana</a>
62 72
 */
63 73
public class FeatureTablePanel extends JPanel implements Observer {
64 74

  
75
    private static final Logger logger = LoggerFactory.getLogger(FeatureTablePanel.class);
76

  
65 77
    private static final long serialVersionUID = -9199073063283531216L;
66 78

  
67 79
    private ConfigurableFeatureTableModel tableModel;
......
74 86

  
75 87
    /**
76 88
     * Constructs a Panel to show a table with the features of a FeatureStore.
77
     * 
89
     *
78 90
     * @param featureStore
79
     *            to extract the features from
91
     * to extract the features from
80 92
     * @throws BaseException
81
     *             if there is an error reading data from the FeatureStore
93
     * if there is an error reading data from the FeatureStore
82 94
     */
83 95
    public FeatureTablePanel(FeatureStore featureStore) throws BaseException {
84 96
        this(featureStore, true);
......
86 98

  
87 99
    /**
88 100
     * Constructs a Panel to show a table with the features of a FeatureStore.
89
     * 
101
     *
90 102
     * @param featureStore
91
     *            to extract the features from
103
     * to extract the features from
92 104
     * @param isDoubleBuffered
93
     *            a boolean, true for double-buffering, which uses additional
94
     *            memory space to achieve fast, flicker-free updates
105
     * a boolean, true for double-buffering, which uses additional
106
     * memory space to achieve fast, flicker-free updates
95 107
     * @throws BaseException
96
     *             if there is an error reading data from the FeatureStore
108
     * if there is an error reading data from the FeatureStore
97 109
     */
98 110
    public FeatureTablePanel(FeatureStore featureStore, boolean isDoubleBuffered)
99
        throws BaseException {
111
            throws BaseException {
100 112
        this(featureStore, null, isDoubleBuffered);
101 113
    }
102 114

  
103 115
    /**
104 116
     * @throws BaseException
105
     * 
117
     *
106 118
     */
107 119
    public FeatureTablePanel(FeatureStore featureStore,
108
        FeatureQuery featureQuery) throws BaseException {
120
            FeatureQuery featureQuery) throws BaseException {
109 121
        this(featureStore, featureQuery, true);
110 122
    }
111 123

  
......
114 126
     * @throws BaseException
115 127
     */
116 128
    public FeatureTablePanel(FeatureStore featureStore,
117
        FeatureQuery featureQuery, boolean isDoubleBuffered)
118
        throws BaseException {
129
            FeatureQuery featureQuery, boolean isDoubleBuffered)
130
            throws BaseException {
119 131
        this(createModel(featureStore, featureQuery));
120 132
    }
121 133

  
122 134
    public FeatureTablePanel(ConfigurableFeatureTableModel tableModel)
123
        throws DataException {
135
            throws DataException {
124 136
        this(tableModel, true);
125 137
    }
126 138

  
127 139
    public FeatureTablePanel(ConfigurableFeatureTableModel tableModel,
128
        boolean isDoubleBuffered) throws DataException {
140
            boolean isDoubleBuffered) throws DataException {
129 141
        super(isDoubleBuffered);
130 142
        this.tableModel = tableModel;
131 143
        this.setLayout(new BorderLayout());
......
135 147
    }
136 148

  
137 149
    private JPanel getSelectionPanel() {
138
        if (selectionPanel == null) {
150
        if ( selectionPanel == null ) {
139 151
            selectionLabel = new JLabel();
140 152
            selectionLabel.setText(getFeatureSelectionSize() + " / "
141
                + getTableModel().getHelper().getTotalSize() + " "
142
                + Messages.getText("registros_seleccionados_total") + ".");
153
                    + getTableModel().getHelper().getTotalSize() + " "
154
                    + Messages.getText("registros_seleccionados_total") + ".");
143 155
            selectionPanel = new JPanel();
144 156

  
145 157
            selectionPanel.add(selectionLabel, BorderLayout.EAST);
......
149 161

  
150 162
    private void updateSelection() {
151 163
        selectionLabel.setText(getFeatureSelectionSize() + " / "
152
            + getTableModel().getRowCount() + " "
153
            + Messages.getText("registros_seleccionados_total") + ".");
164
                + getTableModel().getRowCount() + " "
165
                + Messages.getText("registros_seleccionados_total") + ".");
154 166
    }
155 167

  
156 168
    private long getFeatureSelectionSize() {
......
158 170
            return getFeatureStore().getFeatureSelection().getSize();
159 171
        } catch (DataException e) {
160 172
            throw new RuntimeException("Error updating selection information",
161
                e);
173
                    e);
162 174
        }
163 175
    }
164 176

  
......
168 180

  
169 181
    /**
170 182
     * Returns the internal Table Model for the Features of the FeatureStore.
171
     * 
183
     *
172 184
     * @return the internal Table Model
173 185
     */
174 186
    public ConfigurableFeatureTableModel getTableModel() {
......
178 190
    /**
179 191
     * Returns the {@link FeatureStore} of the {@link Feature}s being shown in
180 192
     * the table.
181
     * 
193
     *
182 194
     * @return the store of the features
183 195
     */
184 196
    public FeatureStore getFeatureStore() {
......
187 199

  
188 200
    /**
189 201
     * Returns the FeatureQuery used to get the Features.
190
     * 
202
     *
191 203
     * @return the FeatureQuery
192 204
     */
193 205
    public FeatureQuery getFeatureQuery() {
......
206 218
    }
207 219

  
208 220
    private static ConfigurableFeatureTableModel createModel(
209
        FeatureStore featureStore, FeatureQuery featureQuery)
210
        throws BaseException {
211
        FeatureQuery query =
212
            featureQuery == null ? featureStore.createFeatureQuery()
221
            FeatureStore featureStore, FeatureQuery featureQuery)
222
            throws BaseException {
223
        FeatureQuery query
224
                = featureQuery == null ? featureStore.createFeatureQuery()
213 225
                : featureQuery;
214 226

  
215 227
        return new ConfigurableFeatureTableModel(featureStore, query);
216 228
    }
217 229

  
218 230
    public FeatureTable getTable() throws DataException {
219
        if (table == null) {
231
        if ( table == null ) {
220 232
            table = new FeatureTable(tableModel);
221 233
            // Change the selection model to link with the FeatureStore
222 234
            // selection
......
230 242

  
231 243
    /**
232 244
     * This method initializes jScrollPane
233
     * 
245
     *
234 246
     * @return javax.swing.JScrollPane
235 247
     * @throws DataException
236 248
     */
237 249
    private JScrollPane getJScrollPane() throws DataException {
238
        if (jScrollPane == null) {
250
        if ( jScrollPane == null ) {
239 251
            FeatureTable theTable = getTable();
240 252
            jScrollPane = new JScrollPane();
241 253
            jScrollPane.setViewportView(theTable);
242
            jScrollPane.setRowHeaderView(getRowHeader(theTable));
254
            createTheRowHeader();
255
            theTable.addPropertyChangeListener(new PropertyChangeListener() {
256
                public void propertyChange(PropertyChangeEvent pce) {
257
                    if( "RowHeight".equalsIgnoreCase(pce.getPropertyName())) {
258
                        // No he averigado como cambiar el ancho de las lineas
259
                        // ya creadas de la cabezera de lineas, asi que la
260
                        // reconstruyo entera cuando algo cambia.
261
                        createTheRowHeader();
262
                    }
263
                }
264
            });
265
            TableModel model = theTable.getModel();
266
            model.addTableModelListener(new TableModelListener() {
267
                public void tableChanged(TableModelEvent tme) {
268
                    // No he averigado como cambiar el ancho de las lineas
269
                    // ya creadas de la cabezera de lineas, asi que la
270
                    // reconstruyo entera cuando algo cambia.
271
                    createTheRowHeader();
272
                }
273
            });
243 274
        }
244 275
        return jScrollPane;
245 276
    }
246 277

  
278
    void createTheRowHeader() {
279
        // No se si ha sido paranoia o que, pero parece que si la recreo sin mas
280
        // a veces parece como si no la cambiase, asi que he probado a encolarlo 
281
        // en la cola de eventos de swing y parece que siempre funciona.
282
        //
283
        // Cuando se estan mostrando las geometrias, que cada linea tiene un ancho
284
        // distinto, se le llama muchisimas veces;
285
        // habria que evaluar retenerlas por ejemplo durante un segundo y solo 
286
        // recrearlo entonces.
287
        SwingUtilities.invokeLater(new Runnable() {
288

  
289
            public void run() {
290
                ListModel lm = new AbstractListModel() {
291
                    public int getSize() {
292
                        return table.getRowCount();
293
                    }
294

  
295
                    public Object getElementAt(int index) {
296
                        return String.valueOf(index + 1);
297
                    }
298
                };
299
                final JList rowHeader = new JList(lm);
300
                rowHeader.setCellRenderer(new RowHeaderRenderer(table));
301
                jScrollPane.setRowHeaderView(rowHeader);
302
            }
303
        });
304
    }
305

  
247 306
    private static class RowHeaderRenderer extends JButton implements ListCellRenderer {
248 307

  
308
        private JTable table = null;
309
        private final Dimension dimension = new Dimension();
310

  
249 311
        RowHeaderRenderer(JTable table) {
250
          JTableHeader header = table.getTableHeader();
251
          setOpaque(true);
252
          setBorder(UIManager.getBorder("TableHeader.cellBorder"));
253
          setHorizontalAlignment(CENTER);
254
          setForeground(header.getForeground());
255
          setBackground(header.getBackground());
256
          setFont(header.getFont());
312
            JTableHeader header = table.getTableHeader();
313
            setOpaque(true);
314
            setBorder(UIManager.getBorder("TableHeader.cellBorder"));
315
            setHorizontalAlignment(CENTER);
316
            setForeground(header.getForeground());
317
            setBackground(header.getBackground());
318
            setFont(header.getFont());
319
            this.table = table;
320
            //                                               1234567
321
            Rectangle2D r = this.getFont().getStringBounds( "_______", new FontRenderContext(null,true,true));
322
            this.dimension.width = (int) r.getWidth();
257 323
        }
258 324

  
259 325
        public Component getListCellRendererComponent(JList list, Object value,
260
            int index, boolean isSelected, boolean cellHasFocus) {
261
          setText((value == null) ? "" : value.toString());
262
          return this;
326
                int index, boolean isSelected, boolean cellHasFocus) {
327
            setText((value == null) ? "" : value.toString());
328
            this.dimension.height = this.table.getRowHeight(index);
329
            this.setPreferredSize(this.dimension);
330
            return this;
263 331
        }
332

  
264 333
    }
265
    
266
    private JList getRowHeader(final FeatureTable theTable) {
267
      
268
      ListModel lm = new AbstractListModel() {
269
        public int getSize() {
270
          return theTable.getRowCount();
271
        }
272 334

  
273
        public Object getElementAt(int index) {
274
          return String.valueOf(index+1);
275
        }
276
      };
277
      JList rowHeader = new JList(lm);
278
      rowHeader.setCellRenderer(new RowHeaderRenderer(theTable));
279
      rowHeader.setFixedCellWidth(50);
280
      rowHeader.setFixedCellHeight(table.getRowHeight()); //+ table.getRowMargin());
281
      return rowHeader;
282
    }
283
    
284 335
    public void update(Observable observable, Object notification) {
285 336
        // If selection changes from nothing selected to anything selected
286 337
        // or the reverse, update selection info
287
        if (notification instanceof DataStoreNotification) {
338
        if ( notification instanceof DataStoreNotification ) {
288 339
            String type = ((DataStoreNotification) notification).getType();
289
            if (DataStoreNotification.SELECTION_CHANGE.equals(type)) {
340
            if ( DataStoreNotification.SELECTION_CHANGE.equals(type) ) {
290 341
                updateSelection();
291 342
            }
292 343
        }

Also available in: Unified diff