001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: * The Original Software is NetBeans. The Initial Developer of the Original
026: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
027: * Microsystems, Inc. All Rights Reserved.
028: *
029: * If you wish your version of this file to be governed by only the CDDL
030: * or only the GPL Version 2, indicate your decision by adding
031: * "[Contributor] elects to include this software in this distribution
032: * under the [CDDL or GPL Version 2] license." If you do not indicate a
033: * single choice of license, a recipient has the option to distribute
034: * your version of this file under either the CDDL, the GPL Version 2 or
035: * to extend the choice of license to its licensees as provided above.
036: * However, if you add GPL Version 2 code and therefore, elected the GPL
037: * Version 2 license, then the option applies only if the new code is
038: * made subject to such option by the copyright holder.
039: */
040:
041: package org.netbeans.lib.profiler.ui.components.table;
042:
043: import org.netbeans.lib.profiler.ui.components.*;
044: import java.awt.event.InputEvent;
045: import java.awt.event.MouseAdapter;
046: import java.awt.event.MouseEvent;
047: import java.awt.event.MouseMotionListener;
048: import javax.swing.*;
049: import javax.swing.table.AbstractTableModel;
050: import javax.swing.table.JTableHeader;
051: import javax.swing.table.TableColumnModel;
052:
053: /**
054: * This class provides a superclass, from which Table Models can be derived, that will support
055: * sorting by a column on which the user clicks. A subclass should call setTable(table),
056: * and should provide an implementation of the sortByColumn(int column) method.
057: *
058: * @author Misha Dmitriev
059: * @author Jiri Sedlacek
060: */
061: public abstract class SortableTableModel extends AbstractTableModel {
062: //~ Inner Classes ------------------------------------------------------------------------------------------------------------
063:
064: /**
065: * This class is used for listening to the table header mouse events.
066: */
067: private class HeaderListener extends MouseAdapter implements
068: MouseMotionListener {
069: //~ Methods --------------------------------------------------------------------------------------------------------------
070:
071: /*
072: * If the user clicks to the sorting column (column defining the sort criterium and order), the sorting order is reversed.
073: * If new sorting column is selected, the appropriate sorting order for column's datatype is set.
074: */
075: public void mouseClicked(MouseEvent e) {
076: if (e.getModifiers() == InputEvent.BUTTON1_MASK) {
077: int column = tableHeader.columnAtPoint(e.getPoint());
078: int sortingColumn = headerRenderer.getSortingColumn();
079:
080: if (column == sortingColumn) {
081: headerRenderer.reverseSortingOrder();
082: } else {
083: headerRenderer.setSortingColumn(column);
084:
085: if (getInitialSorting(column)) {
086: headerRenderer.setSortingOrder(SORT_ORDER_ASC); // Default sort order for strings is Ascending
087: } else {
088: headerRenderer.setSortingOrder(SORT_ORDER_DESC); // Default sort order for numbers is Descending
089: }
090: }
091:
092: tableHeader.repaint();
093:
094: sortByColumn(column, headerRenderer.getSortingOrder());
095: }
096: }
097:
098: public void mouseDragged(MouseEvent e) {
099: }
100:
101: public void mouseMoved(MouseEvent e) {
102: int focusedColumn = tableHeader.columnAtPoint(e.getPoint());
103:
104: if ((focusedColumn != lastFocusedColumn)
105: && (focusedColumn != -1)) {
106: tableHeader.setToolTipText(SortableTableModel.this
107: .getColumnToolTipText(focusedColumn));
108: lastFocusedColumn = focusedColumn;
109: }
110: }
111:
112: /*
113: * Here the active header button is programatically pressed
114: */
115: public void mousePressed(MouseEvent e) {
116: if ((e.getModifiers() == InputEvent.BUTTON1_MASK)
117: && (tableHeader.getResizingColumn() == null)) {
118: headerRenderer.setPressedColumn(tableHeader
119: .columnAtPoint(e.getPoint()));
120: tableHeader.repaint();
121: }
122: }
123:
124: /*
125: * Here the active header button is programatically released
126: */
127: public void mouseReleased(MouseEvent e) {
128: if (e.getModifiers() == InputEvent.BUTTON1_MASK) {
129: headerRenderer.setPressedColumn(-1);
130: tableHeader.repaint();
131: }
132: }
133: }
134:
135: //~ Static fields/initializers -----------------------------------------------------------------------------------------------
136:
137: public static final boolean SORT_ORDER_DESC = false;
138: public static final boolean SORT_ORDER_ASC = true;
139:
140: //~ Instance fields ----------------------------------------------------------------------------------------------------------
141:
142: private CustomSortableHeaderRenderer headerRenderer;
143: private HeaderListener headerListener;
144: private ImageIcon sortAscIcon = new ImageIcon(
145: SortableTableModel.class
146: .getResource("/org/netbeans/lib/profiler/ui/resources/sortAsc.png")); //NOI18N
147: private ImageIcon sortDescIcon = new ImageIcon(
148: SortableTableModel.class
149: .getResource("/org/netbeans/lib/profiler/ui/resources/sortDesc.png")); //NOI18N
150: private JTableHeader tableHeader;
151: private int lastFocusedColumn = -1;
152:
153: //~ Constructors -------------------------------------------------------------------------------------------------------------
154:
155: public SortableTableModel() {
156: headerListener = new HeaderListener();
157: headerRenderer = new CustomSortableHeaderRenderer(sortAscIcon,
158: sortDescIcon);
159: }
160:
161: //~ Methods ------------------------------------------------------------------------------------------------------------------
162:
163: /**
164: * After the table to which this model belongs has been set, this method allows to set the initial sorting column and sorting order.
165: * @param sortingColumn The initial sorting column
166: * @param sortingOrder The initial sorting order
167: */
168: public void setInitialSorting(int sortingColumn,
169: boolean sortingOrder) {
170: if (headerRenderer != null) {
171: headerRenderer.setSortingColumn(sortingColumn);
172: headerRenderer.setSortingOrder(sortingOrder);
173: }
174: }
175:
176: /**
177: * @param column The table column index
178: * @return Initial sorting for the specified column - if true, ascending, if false descending
179: */
180: public abstract boolean getInitialSorting(int column); /* {
181: return (getColumnClass(column).equals(String.class));
182: }*/
183:
184: public int getSortingColumn() {
185: return headerRenderer.getSortingColumn();
186: }
187:
188: public boolean getSortingOrder() {
189: return headerRenderer.getSortingOrder();
190: }
191:
192: /**
193: * Assigns this SortableTableModel to the JTable and sets the custom renderer for the selectable table header.
194: * @param table The JTable to set this table model to
195: */
196: public void setTable(JTable table) {
197: TableColumnModel tableModel = table.getColumnModel();
198: int n = tableModel.getColumnCount();
199:
200: for (int i = 0; i < n; i++) {
201: tableModel.getColumn(i).setHeaderRenderer(headerRenderer);
202: }
203:
204: if (tableHeader != table.getTableHeader()) {
205: if (tableHeader != null) {
206: tableHeader.removeMouseListener(headerListener);
207: tableHeader.removeMouseMotionListener(headerListener);
208: lastFocusedColumn = -1;
209: }
210:
211: tableHeader = table.getTableHeader();
212: tableHeader.setReorderingAllowed(false);
213: tableHeader.addMouseListener(headerListener);
214: tableHeader.addMouseMotionListener(headerListener);
215: }
216: }
217:
218: public abstract void sortByColumn(int column, boolean order);
219:
220: public String getColumnToolTipText(int column) {
221: return null;
222: }
223: }
|