View Javadoc

1   /*
2    *  File: DefaultTableViewState.java 
3    *  Copyright (c) 2004-2007  Peter Kliem (Peter.Kliem@jaret.de)
4    *  A commercial license is available, see http://www.jaret.de.
5    *
6    * All rights reserved. This program and the accompanying materials
7    * are made available under the terms of the Common Public License v1.0
8    * which accompanies this distribution, and is available at
9    * http://www.eclipse.org/legal/cpl-v10.html
10   */
11  package de.jaret.util.ui.table.model;
12  
13  import java.util.ArrayList;
14  import java.util.Comparator;
15  import java.util.HashMap;
16  import java.util.List;
17  import java.util.Map;
18  import java.util.Vector;
19  
20  import de.jaret.util.ui.table.renderer.DefaultCellStyleProvider;
21  import de.jaret.util.ui.table.renderer.ICellStyle;
22  import de.jaret.util.ui.table.renderer.ICellStyleListener;
23  import de.jaret.util.ui.table.renderer.ICellStyleProvider;
24  
25  /***
26   * Default implementation of a TableViewState for the jaret table.
27   * 
28   * @author Peter Kliem
29   * @version $Id: DefaultTableViewState.java 472 2007-05-22 22:30:07Z olk $
30   */
31  public class DefaultTableViewState implements ITableViewState, ICellStyleListener {
32      /*** map of row configurations. */
33      protected Map<IRow, RowConfiguration> _rowConfiguations = new HashMap<IRow, RowConfiguration>();
34  
35      /*** map of column configurations. */
36      protected Map<IColumn, ColumnConfiguration> _colConfigurations = new HashMap<IColumn, ColumnConfiguration>();
37  
38      /*** listener list for the tableviewstate listeners. */
39      protected List<ITableViewStateListener> _listeners;
40  
41      protected int _minimalRowHeight = 10;
42  
43      protected int _maximalRowHeight = -1; // undefined
44  
45      protected int _defaultRowHeight = 22;
46  
47      protected int _minimalColumnWidth = 10;
48  
49      protected int _maximalColumnWidth = -1; // undefined
50  
51      protected int _defaultColumnWidth = 100;
52  
53      /*** the sorted list (for display) of columns. */ 
54      protected List<IColumn> _sortedColumns;
55  
56      /*** the cell style provider used. */
57      protected ICellStyleProvider _cellStyleProvider;
58  
59      /*** The colummn resize mode used by the table. */
60      protected ColumnResizeMode _columnResizeMode;
61  
62      /*** Default row height mode for new rows. */
63      protected RowHeightMode _defaultRowHeightMode = RowHeightMode.OPTANDVAR;
64  
65      /***
66       * Constructor.
67       * 
68       */
69      public DefaultTableViewState() {
70          _cellStyleProvider = new DefaultCellStyleProvider();
71          _cellStyleProvider.addCellStyleListener(this);
72      }
73  
74      /***
75       * {@inheritDoc}
76       */
77      public int getRowHeight(IRow row) {
78          RowConfiguration configuration = getRowConfiguration(row);
79          return configuration.rowHeight;
80      }
81  
82      /***
83       * {@inheritDoc}
84       */
85      public void setRowHeight(IRow row, int height) {
86          RowConfiguration configuration = getRowConfiguration(row);
87          if (configuration.rowHeight != height) {
88              configuration.rowHeight = height;
89              fireRowHeightChanged(row, height);
90          }
91      }
92  
93      /***
94       * {@inheritDoc} 
95       */
96      public void setRowHeight(int height) {
97          _defaultRowHeight = height;
98          // set for all rows known
99          for (RowConfiguration rconfig : _rowConfiguations.values()) {
100             rconfig.rowHeight = height;
101         }
102         // TODO may be optimized 
103         for (IRow row : _rowConfiguations.keySet()) {
104             fireRowHeightChanged(row, height);
105         }
106         
107     }
108     
109     
110     /***
111      * {@inheritDoc}
112      */
113     public RowHeightMode getRowHeigthMode(IRow row) {
114         RowConfiguration configuration = getRowConfiguration(row);
115         return configuration.heightMode;
116     }
117 
118     /***
119      * {@inheritDoc}
120      */
121     public void setRowHeightMode(IRow row, RowHeightMode mode) {
122         RowConfiguration configuration = getRowConfiguration(row);
123         if (configuration.heightMode != mode) {
124             configuration.heightMode = mode;
125             fireRowHeightModeChanged(row, mode);
126         }
127     }
128 
129     /***
130      * {@inheritDoc}
131      */
132     public void setRowHeightMode(RowHeightMode mode) {
133         _defaultRowHeightMode = mode;
134         // set for all rows known
135         for (RowConfiguration rconfig : _rowConfiguations.values()) {
136             rconfig.heightMode = mode;
137         }
138         for (IRow row : _rowConfiguations.keySet()) {
139             fireRowHeightModeChanged(row, mode);
140         }
141     }
142 
143     /***
144      * {@inheritDoc}
145      */
146     public RowHeightMode getRowHeightMode() {
147         return _defaultRowHeightMode;
148     }
149 
150     private RowConfiguration getRowConfiguration(IRow row) {
151         RowConfiguration configuration = _rowConfiguations.get(row);
152         if (configuration == null) {
153             configuration = getDefaultRowConfiguration();
154             _rowConfiguations.put(row, configuration);
155         }
156         return configuration;
157     }
158 
159     private RowConfiguration getDefaultRowConfiguration() {
160         RowConfiguration configuration = new RowConfiguration();
161         configuration.rowHeight = _defaultRowHeight;
162         configuration.heightMode = _defaultRowHeightMode;
163         return configuration;
164     }
165 
166     private ColumnConfiguration getColumnConfiguration(IColumn col) {
167         ColumnConfiguration configuration = _colConfigurations.get(col);
168         if (configuration == null) {
169             configuration = getDefaultColumnConfiguration(col.getId());
170             _colConfigurations.put(col, configuration);
171         }
172         return configuration;
173     }
174 
175     private ColumnConfiguration getColumnConfiguration(String columnId) {
176         for (ColumnConfiguration colConf : _colConfigurations.values()) {
177             if (colConf.id.equals(columnId)) {
178                 return colConf;
179             }
180         }
181         return getDefaultColumnConfiguration(columnId);
182     }
183 
184     private ColumnConfiguration getDefaultColumnConfiguration(String colId) {
185         ColumnConfiguration configuration = new ColumnConfiguration();
186         configuration.id = colId;
187         configuration.resizable = true;
188         configuration.columnWidth = _defaultColumnWidth;
189         return configuration;
190     }
191 
192     /***
193      * {@inheritDoc}
194      */
195     public int getColumnWidth(IColumn column) {
196         ColumnConfiguration configuration = getColumnConfiguration(column);
197         return (int) Math.round(configuration.columnWidth);
198     }
199 
200     /***
201      * {@inheritDoc}
202      */
203     public void setColumnWidth(IColumn column, int width) {
204         ColumnConfiguration configuration = getColumnConfiguration(column);
205         if (configuration.columnWidth != width) {
206             int oldVal = (int) Math.round(configuration.columnWidth);
207             if (_columnResizeMode == ColumnResizeMode.SUBSEQUENT) {
208                 IColumn sCol = getSubsequentColumn(column);
209                 if (sCol == null) {
210                     // no subsequent col -> do it
211                     configuration.columnWidth = width;
212                     fireColumnWidthChanged(column, width);
213                 } else {
214                     int max = getColumnWidth(sCol) - _minimalColumnWidth;
215                     int delta = width - oldVal;
216                     delta = delta > max ? max : delta;
217                     configuration.columnWidth += delta;
218                     ColumnConfiguration sConfiguration = getColumnConfiguration(sCol);
219                     sConfiguration.columnWidth -= delta;
220                     fireColumnWidthsChanged();
221                 }
222             } else if (_columnResizeMode == ColumnResizeMode.ALLSUBSEQUENT || _columnResizeMode == ColumnResizeMode.ALL) {
223                 List<IColumn> sCols = null;
224                 if (_columnResizeMode == ColumnResizeMode.ALLSUBSEQUENT) {
225                     sCols = getSubsequentColumns(column);
226                 } else {
227                     sCols = getAllVisibleCols(column);
228                 }
229                 if (sCols.size() == 0) {
230                     // no subsequent cols -> do it
231                     configuration.columnWidth = width;
232                     fireColumnWidthChanged(column, width);
233                 } else {
234                     int max = 0;
235                     for (IColumn c : sCols) {
236                         max += getColumnWidth(c) - _minimalColumnWidth;
237                     }
238                     int delta = width - oldVal;
239                     delta = delta > max ? max : delta;
240                     configuration.columnWidth += delta;
241                     double distDelta = (double) delta / (double) sCols.size();
242                     for (IColumn c : sCols) {
243                         ColumnConfiguration sConfiguration = getColumnConfiguration(c);
244                         sConfiguration.columnWidth -= distDelta;
245                     }
246                     fireColumnWidthsChanged();
247                 }
248             } else { // mode NONE
249                 configuration.columnWidth = width;
250                 fireColumnWidthChanged(column, width);
251             }
252         }
253 
254     }
255 
256     /***
257      * Creates a list of al visible cols without the given column.
258      * 
259      * @param without the column to omit
260      * @return list of visible columns without a given one
261      */
262     private List<IColumn> getAllVisibleCols(IColumn without) {
263         List<IColumn> result = new ArrayList<IColumn>();
264         int idx = _sortedColumns.indexOf(without);
265         for (int i = 0; i < _sortedColumns.size(); i++) {
266             if (idx != i && getColumnVisible(_sortedColumns.get(i))) {
267                 result.add(_sortedColumns.get(i));
268             }
269         }
270         return result;
271     }
272 
273     /***
274      * Retrieve the next column after the given one.
275      * 
276      * @param column reference column
277      * @return next column in the sorted columns or <code>null</code> if the given column is the last
278      */
279     private IColumn getSubsequentColumn(IColumn column) {
280         List<IColumn> l = getSubsequentColumns(column);
281         if (l.size() > 0) {
282             return l.get(0);
283         }
284         return null;
285     }
286 
287     /***
288      * Retrieve the list of columns behind the given column.
289      * 
290      * @param column reference column
291      * @return list of columns behind the given column in the sorted columns
292      */
293     private List<IColumn> getSubsequentColumns(IColumn column) {
294         List<IColumn> result = new ArrayList<IColumn>();
295         int idx = _sortedColumns.indexOf(column);
296         if (idx == -1) {
297             return result;
298         }
299         for (int i = idx + 1; i < _sortedColumns.size(); i++) {
300             if (getColumnVisible(_sortedColumns.get(i))) {
301                 result.add(_sortedColumns.get(i));
302             }
303         }
304         return result;
305     }
306 
307     /***
308      * {@inheritDoc}
309      */
310     public boolean getColumnVisible(IColumn column) {
311         ColumnConfiguration configuration = getColumnConfiguration(column);
312         return configuration.visible;
313     }
314 
315     /***
316      * {@inheritDoc}
317      */
318     public void setColumnVisible(IColumn column, boolean visible) {
319         ColumnConfiguration configuration = getColumnConfiguration(column);
320         if (configuration.visible != visible) {
321             configuration.visible = visible;
322             fireColumnVisibilityChanged(column, visible);
323         }
324     }
325 
326     /***
327      * {@inheritDoc}
328      */
329     public void setColumnVisible(String columnId, boolean visible) {
330         ColumnConfiguration configuration = getColumnConfiguration(columnId);
331         if (configuration.visible != visible) {
332             configuration.visible = visible;
333             // TODO fireColumnVisibilityChanged(column, visible);
334         }
335     }
336 
337     /***
338      * {@inheritDoc}
339      */
340     public List<IColumn> getSortedColumns() {
341         if (_sortedColumns == null) {
342             _sortedColumns = new ArrayList<IColumn>();
343         }
344         return _sortedColumns;
345     }
346 
347     /***
348      * {@inheritDoc}
349      */
350     public void setSortedColumns(List<IColumn> sortedColumns) {
351         _sortedColumns = sortedColumns;
352         fireColumnOrderChanged();
353     }
354 
355     /***
356      * {@inheritDoc}
357      */
358     public int getColumnSortingPosition(IColumn column) {
359         ColumnConfiguration configuration = getColumnConfiguration(column);
360         return configuration.sortingPosition;
361     }
362 
363     /***
364      * {@inheritDoc}
365      */
366     public boolean getColumnSortingDirection(IColumn column) {
367         ColumnConfiguration configuration = getColumnConfiguration(column);
368         return configuration.sortingDirection;
369     }
370 
371     /***
372      * {@inheritDoc}
373      */
374     public void setSorting(IColumn column) {
375         ColumnConfiguration conf = getColumnConfiguration(column);
376         if (conf.sortingPosition == 0) {
377             addShiftSorting();
378             conf.sortingPosition = 1;
379         } else {
380             if (conf.sortingDirection) {
381                 conf.sortingDirection = false;
382             } else {
383                 conf.sortingDirection = true;
384                 remSorting(conf.sortingPosition);
385                 conf.sortingPosition = 0;
386             }
387         }
388         fireSortingChanged();
389     }
390 
391     private void addShiftSorting() {
392         for (ColumnConfiguration cconf : _colConfigurations.values()) {
393             if (cconf.sortingPosition > 0) {
394                 cconf.sortingPosition++;
395             }
396         }
397     }
398 
399     private void remSorting(int pos) {
400         for (ColumnConfiguration cconf : _colConfigurations.values()) {
401             if (cconf.sortingPosition > pos) {
402                 cconf.sortingPosition--;
403             }
404         }
405     }
406 
407     /***
408      * Simple helper class holding the configuration for a row.
409      * 
410      * @author Peter Kliem
411      * @version $Id: DefaultTableViewState.java 472 2007-05-22 22:30:07Z olk $
412      */
413     public class RowConfiguration {
414         /*** rowheightmode. */
415         public RowHeightMode heightMode;
416         /*** actual row height. */
417         public int rowHeight;
418     }
419 
420     /***
421      * Simple helper class holding the onfiguration information for a column.
422      * 
423      * @author Peter Kliem
424      * @version $Id: DefaultTableViewState.java 472 2007-05-22 22:30:07Z olk $
425      */
426     public class ColumnConfiguration {
427         /*** width of the column. */
428         public double columnWidth;
429         /*** resize allowance. */
430         public boolean resizable = true;
431         /*** true when visible. */
432         public boolean visible = true;
433         /*** id of the column. */
434         public String id;
435         /*** position in sorting. */
436         public int sortingPosition;
437         /*** sorting direction if sorting. */
438         public boolean sortingDirection = true; // ascending as default
439     }
440 
441     /***
442      * {@inheritDoc}
443      */
444     public synchronized void addTableViewStateListener(ITableViewStateListener tvsl) {
445         if (_listeners == null) {
446             _listeners = new Vector<ITableViewStateListener>();
447         }
448         _listeners.add(tvsl);
449     }
450 
451     /***
452      * {@inheritDoc}
453      */
454     public void removeTableViewStateListener(ITableViewStateListener tvsl) {
455         if (_listeners != null) {
456             _listeners.remove(tvsl);
457         }
458     }
459 
460     /***
461      * Inform listeners about a change in the height of a row.
462      * 
463      * @param row row
464      * @param newHeight new row height
465      */
466     protected void fireRowHeightChanged(IRow row, int newHeight) {
467         if (_listeners != null) {
468             for (ITableViewStateListener listener : _listeners) {
469                 listener.rowHeightChanged(row, newHeight);
470             }
471         }
472     }
473 
474     protected void fireRowHeightModeChanged(IRow row, RowHeightMode newMode) {
475         if (_listeners != null) {
476             for (ITableViewStateListener listener : _listeners) {
477                 listener.rowHeightModeChanged(row, newMode);
478             }
479         }
480     }
481 
482     protected void fireColumnWidthChanged(IColumn column, int newWidth) {
483         if (_listeners != null) {
484             for (ITableViewStateListener listener : _listeners) {
485                 listener.columnWidthChanged(column, newWidth);
486             }
487         }
488     }
489 
490     protected void fireColumnWidthsChanged() {
491         if (_listeners != null) {
492             for (ITableViewStateListener listener : _listeners) {
493                 listener.columnWidthsChanged();
494             }
495         }
496     }
497 
498     protected void fireColumnVisibilityChanged(IColumn column, boolean visible) {
499         if (_listeners != null) {
500             for (ITableViewStateListener listener : _listeners) {
501                 listener.columnVisibilityChanged(column, visible);
502             }
503         }
504     }
505 
506     protected void fireSortingChanged() {
507         if (_listeners != null) {
508             for (ITableViewStateListener listener : _listeners) {
509                 listener.sortingChanged();
510             }
511         }
512     }
513 
514     protected void fireColumnOrderChanged() {
515         if (_listeners != null) {
516             for (ITableViewStateListener listener : _listeners) {
517                 listener.columnOrderChanged();
518             }
519         }
520     }
521 
522     protected void fireCellStyleChanged(IRow row, IColumn column, ICellStyle cellStyle) {
523         if (_listeners != null) {
524             for (ITableViewStateListener listener : _listeners) {
525                 listener.cellStyleChanged(row, column, cellStyle);
526             }
527         }
528     }
529 
530     /***
531      * {@inheritDoc}
532      */
533     public int getMinimalRowHeight() {
534         return _minimalRowHeight;
535     }
536 
537     /***
538      * {@inheritDoc}
539      */
540     public void setMinimalRowHeight(int minimalRowHeight) {
541         _minimalRowHeight = minimalRowHeight;
542     }
543 
544     /***
545      * {@inheritDoc}
546      */
547     public int getMinimalColWidth() {
548         return _minimalColumnWidth;
549     }
550 
551     /***
552      * {@inheritDoc}
553      */
554     public void setMinimalColWidth(int minimalColumnWidth) {
555         _minimalColumnWidth = minimalColumnWidth;
556     }
557 
558     /***
559      * {@inheritDoc}
560      */
561     public ICellStyleProvider getCellStyleProvider() {
562         return _cellStyleProvider;
563     }
564 
565     /***
566      * {@inheritDoc}
567      */
568     public void setCellStyleProvider(ICellStyleProvider cellStyleProvider) {
569         if (_cellStyleProvider != null) {
570             _cellStyleProvider.remCellStyleListener(this);
571         }
572         _cellStyleProvider = cellStyleProvider;
573         _cellStyleProvider.addCellStyleListener(this);
574     }
575 
576     /***
577      * {@inheritDoc}
578      */
579     public ICellStyle getCellStyle(IRow row, IColumn column) {
580         return _cellStyleProvider.getCellStyle(row, column);
581     }
582 
583     /***
584      * {@inheritDoc} inform listeners abou the received cell style change.
585      */
586     public void cellStyleChanged(IRow row, IColumn column, ICellStyle style) {
587         fireCellStyleChanged(row, column, style);
588     }
589 
590     /***
591      * {@inheritDoc}
592      */
593     public boolean columnResizingAllowed(IColumn column) {
594         ColumnConfiguration conf = getColumnConfiguration(column);
595         return conf.resizable;
596     }
597 
598     /***
599      * {@inheritDoc}
600      */
601     public void setColumnResizingAllowed(IColumn column, boolean resizingAllowed) {
602         ColumnConfiguration conf = getColumnConfiguration(column);
603         conf.resizable = resizingAllowed;
604     }
605 
606     /***
607      * @return Returns the columnResizeMode.
608      */
609     public ColumnResizeMode getColumnResizeMode() {
610         return _columnResizeMode;
611     }
612 
613     /***
614      * @param columnResizeMode The columnResizeMode to set.
615      */
616     public void setColumnResizeMode(ColumnResizeMode columnResizeMode) {
617         _columnResizeMode = columnResizeMode;
618     }
619 
620 }