1 /***
2 * SortableTableColumnEditor.java
3 *
4 * This file is part of the creme library.
5 * The creme library intends to ease the development effort of large
6 * applications by providing easy to use support classes.
7 *
8 * Copyright (C) 2003 Denis Bregeon
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 * contact information: dbregeon@sourceforge.net
25 */
26 package org.jcreme.swing.table.columnmodel.editor;
27
28 import java.awt.FlowLayout;
29 import java.awt.event.ActionEvent;
30 import java.awt.event.ActionListener;
31 import java.net.URL;
32
33 import javax.swing.BoxLayout;
34 import javax.swing.DefaultComboBoxModel;
35 import javax.swing.ImageIcon;
36 import javax.swing.JCheckBox;
37 import javax.swing.JComboBox;
38 import javax.swing.JLabel;
39 import javax.swing.JPanel;
40 import javax.swing.JSpinner;
41 import javax.swing.JToggleButton;
42 import javax.swing.SpinnerNumberModel;
43 import javax.swing.table.TableColumn;
44
45 import org.jcreme.enumerations.ComparatorType;
46 import org.jcreme.enumerations.SortOrder;
47 import org.jcreme.swing.table.SortableTableColumn;
48 import org.jcreme.swing.table.columnmodel.EditableTableColumnModel;
49
50 /***
51 * The subclass of TableColumnEditor that enables to edit SortableTableColumns.
52 *
53 * @author $Author: dbregeon $
54 * @version $Revision: 1.1 $
55 */
56 public class SortableTableColumnEditor extends TableColumnEditor {
57 /***
58 * The URL of the default icon for a column sorted by ascending values.
59 */
60 protected static final URL ASC_ICON = ClassLoader.getSystemClassLoader()
61 .getResource("images/uparrow.gif");
62
63 /***
64 * The URL of the default icon for a column sorted by descending values.
65 */
66 protected static final URL DESC_ICON = ClassLoader.getSystemClassLoader()
67 .getResource("images/downarrow.gif");
68
69 private final ImageIcon ascIcon = (ASC_ICON != null) ? new ImageIcon(
70 ASC_ICON) : null;
71
72 private final ImageIcon descIcon = (DESC_ICON != null) ? new ImageIcon(
73 DESC_ICON) : null;
74
75 /***
76 * Groups all the sortable specific edition elements.
77 */
78 private final JPanel sortPanel = new JPanel();
79
80 /***
81 * This Panel groups the order in sort edition elements.
82 */
83 private final JPanel orderInSortPanel = new JPanel();
84
85 /***
86 * CheckBox that signals whether the column is used in the Sort.
87 */
88 private final JCheckBox useInSortCheckBox = new JCheckBox();
89
90 /***
91 * Label for the order in sort Spinner.
92 */
93 private final JLabel orderInSortLabel = new JLabel();
94
95 /***
96 * The Spinner that enables to select the order of the column in the Sort.
97 */
98 private final JSpinner orderInSortSpinner = new JSpinner();
99
100 /***
101 * Groups the SortOrder edition elements.
102 */
103 private final JPanel sortOrderPanel = new JPanel();
104
105 /***
106 * The Label for the SortOrder ComboBox.
107 */
108 private final JLabel sortOrderLabel = new JLabel();
109
110 /***
111 * The ComboBox that enables to select the SortOrder for the column.
112 */
113 private final JToggleButton sortOrderToggleButton = new JToggleButton();
114
115 /***
116 * Groups the Comparator edition elements.
117 */
118 private final JPanel comparatorPanel = new JPanel();
119
120 /***
121 * The Label for the Comparator ComboBox.
122 */
123 private final JLabel comparatorLabel = new JLabel();
124
125 /***
126 * The ComboBox to select the Comparator.
127 */
128 private final JComboBox comparatorComboBox = new JComboBox();
129
130 /***
131 * The ActionListener for the useInSortCheckBox.
132 */
133 private final ActionListener useInSortCheckBoxActionListener = new ActionListener() {
134 public void actionPerformed(ActionEvent e) {
135 addColumnInSort();
136 }
137
138 };
139
140 /***
141 *
142 *
143 */
144 public SortableTableColumnEditor() {
145 initSortableTableColumnEditor();
146 }
147
148 protected final void initSortableTableColumnEditor() {
149 this.sortPanel
150 .setLayout(new BoxLayout(this.sortPanel, BoxLayout.Y_AXIS));
151
152 this.orderInSortPanel.setLayout(new FlowLayout());
153
154 this.useInSortCheckBox.setText("Use in sort");
155 this.useInSortCheckBox.setSelected(false);
156
157 this.orderInSortLabel.setText("in position");
158 this.orderInSortLabel.setEnabled(false);
159
160 SpinnerNumberModel model = new SpinnerNumberModel();
161 model.setMinimum(new Integer(0));
162 model.setMaximum(new Integer(0));
163 model.setStepSize(new Integer(1));
164 this.orderInSortSpinner.setModel(model);
165
166 this.orderInSortPanel.add(this.useInSortCheckBox);
167 this.orderInSortPanel.add(this.orderInSortLabel);
168 this.orderInSortPanel.add(this.orderInSortSpinner);
169
170 this.sortPanel.add(this.orderInSortPanel);
171
172 this.sortOrderLabel.setText("Order");
173 this.sortOrderToggleButton.setSelectedIcon(this.ascIcon);
174 this.sortOrderToggleButton.setIcon(this.descIcon);
175 this.sortOrderToggleButton.setEnabled(false);
176
177 this.sortOrderPanel.add(this.sortOrderLabel);
178 this.sortOrderPanel.add(this.sortOrderToggleButton);
179
180 this.sortPanel.add(this.sortOrderPanel);
181
182 this.comparatorLabel.setText("Comparator");
183 this.comparatorComboBox.setModel(new DefaultComboBoxModel(
184 ComparatorType.getComparatorTypes()));
185
186 this.comparatorPanel.add(this.comparatorLabel);
187 this.comparatorPanel.add(this.comparatorComboBox);
188
189 this.sortPanel.add(this.comparatorPanel);
190
191 add(this.sortPanel);
192
193 this.useInSortCheckBox
194 .addActionListener(this.useInSortCheckBoxActionListener);
195 }
196
197 /***
198 * @param column
199 * @param model
200 *
201 * @throws IllegalArgumentException
202 */
203 public void setEditedColumn(TableColumn column,
204 EditableTableColumnModel model) throws IllegalArgumentException {
205 if ((column != null) && (!(column instanceof SortableTableColumn))) {
206 throw new IllegalArgumentException(column.getClass().getName()
207 + " is not valid. Expected a "
208 + SortableTableColumn.class.getName());
209 }
210 super.setEditedColumn(column, model);
211 this.useInSortCheckBox.setSelected(((SortableTableColumn) column)
212 .getOrder() != SortOrder.NONE);
213 this.orderInSortSpinner.setEnabled(this.useInSortCheckBox.isSelected());
214 ((SpinnerNumberModel) this.orderInSortSpinner.getModel())
215 .setMaximum(countSortedColumns(model));
216 if (this.orderInSortSpinner.isEnabled()) {
217 this.orderInSortSpinner.setValue(((SortableTableColumn) column)
218 .getOrderInSort());
219
220 }
221 this.sortOrderToggleButton.setEnabled(this.useInSortCheckBox
222 .isSelected());
223 this.sortOrderToggleButton.setSelected(((SortableTableColumn) column)
224 .getOrder() == SortOrder.ASCENDING);
225 this.comparatorComboBox.setEnabled(this.useInSortCheckBox.isSelected());
226 this.comparatorComboBox.setModel(new DefaultComboBoxModel(
227 ComparatorType
228 .getComparatorTypes(((SortableTableColumn) column)
229 .getColumnClass())));
230 this.comparatorComboBox.setSelectedItem(((SortableTableColumn) column)
231 .getComparator());
232 }
233
234 /***
235 * @return the column currently edited.
236 */
237 public TableColumn getEditedColumn() {
238 SortableTableColumn column = (SortableTableColumn) super
239 .getEditedColumn();
240 if (this.useInSortCheckBox.isSelected()) {
241 column.setOrderInSort((Integer) this.orderInSortSpinner.getValue());
242 column.setComparator((ComparatorType) this.comparatorComboBox
243 .getSelectedItem());
244 column
245 .setOrder((this.sortOrderToggleButton.isSelected() ? SortOrder.ASCENDING
246 : SortOrder.DESCENDING));
247 } else {
248 column.setOrder(SortOrder.NONE);
249 }
250 return column;
251 }
252
253 protected Integer countSortedColumns(EditableTableColumnModel model) {
254 int result = 0;
255 TableColumn[] columns = model.getAllColumns();
256 for (int i = 0; i < columns.length; i++) {
257 if (columns[i] instanceof SortableTableColumn) {
258 if (((SortableTableColumn) columns[i]).getOrder() != SortOrder.NONE) {
259 result++;
260 }
261 }
262 }
263 return new Integer(--result);
264 }
265
266 protected void addColumnInSort() {
267 this.orderInSortSpinner.setEnabled(this.useInSortCheckBox.isSelected());
268 this.sortOrderToggleButton.setEnabled(this.useInSortCheckBox
269 .isSelected());
270 this.comparatorComboBox.setEnabled(this.useInSortCheckBox.isSelected());
271 Integer maxSpinner = (Integer) ((SpinnerNumberModel) this.orderInSortSpinner
272 .getModel()).getMaximum();
273 if (this.useInSortCheckBox.isSelected()) {
274 maxSpinner = new Integer(maxSpinner.intValue() + 1);
275 } else {
276 maxSpinner = new Integer(maxSpinner.intValue() - 1);
277 }
278 ((SpinnerNumberModel) this.orderInSortSpinner.getModel())
279 .setMaximum(maxSpinner);
280 this.orderInSortSpinner.setValue(maxSpinner);
281 }
282 }