1
/* ========================================================================
2
* JCommon : a free general purpose class library for the Java(tm) platform
3
* ========================================================================
5
* (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
7
* Project Info: http://www.jfree.org/jcommon/index.html
9
* This library is free software; you can redistribute it and/or modify it
10
* under the terms of the GNU Lesser General Public License as published by
11
* the Free Software Foundation; either version 2.1 of the License, or
12
* (at your option) any later version.
14
* This library is distributed in the hope that it will be useful, but
15
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17
* License for more details.
19
* You should have received a copy of the GNU Lesser General Public
20
* License along with this library; if not, write to the Free Software
21
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
24
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
25
* in the United States and other countries.]
27
* -----------------------
28
* SortButtonRenderer.java
29
* -----------------------
30
* (C) Copyright 2000-2004, by Nobuo Tamemasa and Contributors.
32
* Original Author: Nobuo Tamemasa;
33
* Contributor(s): David Gilbert (for Object Refinery Limited);
36
* $Id: SortButtonRenderer.java,v 1.6 2005/11/16 15:58:41 taqua Exp $
38
* Changes (from 26-Oct-2001)
39
* --------------------------
40
* 26-Oct-2001 : Changed package to com.jrefinery.ui.* (DG);
41
* 26-Jun-2002 : Removed unnecessary import (DG);
42
* 14-Oct-2002 : Fixed errors reported by Checkstyle (DG);
48
import java.awt.Component;
49
import java.awt.Insets;
50
import javax.swing.JButton;
51
import javax.swing.JComponent;
52
import javax.swing.JLabel;
53
import javax.swing.JTable;
54
import javax.swing.SwingConstants;
55
import javax.swing.UIManager;
56
import javax.swing.border.Border;
57
import javax.swing.table.JTableHeader;
58
import javax.swing.table.TableCellRenderer;
61
* A table cell renderer for table headings - uses one of three JButton instances to indicate the
62
* sort order for the table column.
64
* This class (and also BevelArrowIcon) is adapted from original code by Nobuo Tamemasa (version
65
* 1.0, 26-Feb-1999) posted on www.codeguru.com.
67
* @author David Gilbert
69
public class SortButtonRenderer implements TableCellRenderer {
72
* Useful constant indicating NO sorting.
74
public static final int NONE = 0;
77
* Useful constant indicating ASCENDING (that is, arrow pointing down) sorting in the table.
79
public static final int DOWN = 1;
82
* Useful constant indicating DESCENDING (that is, arrow pointing up) sorting in the table.
84
public static final int UP = 2;
87
* The current pressed column (-1 for no column).
89
private int pressedColumn = -1;
92
* The three buttons that are used to render the table header cells.
94
private JButton normalButton;
97
* The three buttons that are used to render the table header cells.
99
private JButton ascendingButton;
102
* The three buttons that are used to render the table header cells.
104
private JButton descendingButton;
107
* Used to allow the class to work out whether to use the buttuns
108
* or labels. Labels are required when using the aqua look and feel cos the
111
private boolean useLabels;
114
* The normal label (only used with MacOSX).
116
private JLabel normalLabel;
119
* The ascending label (only used with MacOSX).
121
private JLabel ascendingLabel;
124
* The descending label (only used with MacOSX).
126
private JLabel descendingLabel;
129
* Creates a new button renderer.
131
public SortButtonRenderer() {
133
this.pressedColumn = -1;
134
this.useLabels = UIManager.getLookAndFeel().getID().equals("Aqua");
136
final Border border = UIManager.getBorder("TableHeader.cellBorder");
138
if (this.useLabels) {
139
this.normalLabel = new JLabel();
140
this.normalLabel.setHorizontalAlignment(SwingConstants.LEADING);
142
this.ascendingLabel = new JLabel();
143
this.ascendingLabel.setHorizontalAlignment(SwingConstants.LEADING);
144
this.ascendingLabel.setHorizontalTextPosition(SwingConstants.LEFT);
145
this.ascendingLabel.setIcon(new BevelArrowIcon(BevelArrowIcon.DOWN, false, false));
147
this.descendingLabel = new JLabel();
148
this.descendingLabel.setHorizontalAlignment(SwingConstants.LEADING);
149
this.descendingLabel.setHorizontalTextPosition(SwingConstants.LEFT);
150
this.descendingLabel.setIcon(new BevelArrowIcon(BevelArrowIcon.UP, false, false));
152
this.normalLabel.setBorder(border);
153
this.ascendingLabel.setBorder(border);
154
this.descendingLabel.setBorder(border);
157
this.normalButton = new JButton();
158
this.normalButton.setMargin(new Insets(0, 0, 0, 0));
159
this.normalButton.setHorizontalAlignment(SwingConstants.LEADING);
161
this.ascendingButton = new JButton();
162
this.ascendingButton.setMargin(new Insets(0, 0, 0, 0));
163
this.ascendingButton.setHorizontalAlignment(SwingConstants.LEADING);
164
this.ascendingButton.setHorizontalTextPosition(SwingConstants.LEFT);
165
this.ascendingButton.setIcon(new BevelArrowIcon(BevelArrowIcon.DOWN, false, false));
166
this.ascendingButton.setPressedIcon(new BevelArrowIcon(BevelArrowIcon.DOWN, false, true));
168
this.descendingButton = new JButton();
169
this.descendingButton.setMargin(new Insets(0, 0, 0, 0));
170
this.descendingButton.setHorizontalAlignment(SwingConstants.LEADING);
171
this.descendingButton.setHorizontalTextPosition(SwingConstants.LEFT);
172
this.descendingButton.setIcon(new BevelArrowIcon(BevelArrowIcon.UP, false, false));
173
this.descendingButton.setPressedIcon(new BevelArrowIcon(BevelArrowIcon.UP, false, true));
175
this.normalButton.setBorder(border);
176
this.ascendingButton.setBorder(border);
177
this.descendingButton.setBorder(border);
184
* Returns the renderer component.
186
* @param table the table.
187
* @param value the value.
188
* @param isSelected selected?
189
* @param hasFocus focussed?
190
* @param row the row.
191
* @param column the column.
192
* @return the renderer.
194
public Component getTableCellRendererComponent(final JTable table,
196
final boolean isSelected,
197
final boolean hasFocus,
198
final int row, final int column) {
201
throw new NullPointerException("Table must not be null.");
204
final JComponent component;
205
final SortableTableModel model = (SortableTableModel) table.getModel();
206
final int cc = table.convertColumnIndexToModel(column);
207
final boolean isSorting = (model.getSortingColumn() == cc);
208
final boolean isAscending = model.isAscending();
210
final JTableHeader header = table.getTableHeader();
211
final boolean isPressed = (cc == this.pressedColumn);
213
if (this.useLabels) {
214
final JLabel label = getRendererLabel(isSorting, isAscending);
215
label.setText((value == null) ? "" : value.toString());
219
final JButton button = getRendererButton(isSorting, isAscending);
220
button.setText((value == null) ? "" : value.toString());
221
button.getModel().setPressed(isPressed);
222
button.getModel().setArmed(isPressed);
226
if (header != null) {
227
component.setForeground(header.getForeground());
228
component.setBackground(header.getBackground());
229
component.setFont(header.getFont());
235
* Returns the correct button component.
237
* @param isSorting whether the render component represents the sort column.
238
* @param isAscending whether the model is ascending.
239
* @return either the ascending, descending or normal button.
241
private JButton getRendererButton(final boolean isSorting, final boolean isAscending) {
244
return ascendingButton;
247
return descendingButton;
256
* Returns the correct label component.
258
* @param isSorting whether the render component represents the sort column.
259
* @param isAscending whether the model is ascending.
260
* @return either the ascending, descending or normal label.
262
private JLabel getRendererLabel(final boolean isSorting, final boolean isAscending) {
265
return ascendingLabel;
268
return descendingLabel;
277
* Sets the pressed column.
279
* @param column the column.
281
public void setPressedColumn(final int column) {
282
this.pressedColumn = column;