001: /*
002: * FindBugs - Find Bugs in Java programs
003: * Copyright (C) 2006, University of Maryland
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307, USA
018: */
019:
020: package edu.umd.cs.findbugs.gui2;
021:
022: import java.awt.Component;
023: import java.awt.Font;
024: import java.util.ArrayList;
025: import java.util.Collections;
026: import java.util.Enumeration;
027: import java.util.List;
028:
029: import javax.swing.BorderFactory;
030: import javax.swing.DefaultListSelectionModel;
031: import javax.swing.ImageIcon;
032: import javax.swing.JLabel;
033: import javax.swing.JTable;
034: import javax.swing.ListSelectionModel;
035: import javax.swing.SwingConstants;
036: import javax.swing.event.ListSelectionEvent;
037: import javax.swing.event.TableColumnModelEvent;
038: import javax.swing.event.TableColumnModelListener;
039: import javax.swing.table.JTableHeader;
040: import javax.swing.table.TableCellRenderer;
041: import javax.swing.table.TableColumn;
042: import javax.swing.table.TableColumnModel;
043: import javax.swing.tree.TreeModel;
044:
045: /**
046: * Handles the sorting order and informs the treeModel when changes are necessary
047: * @author Dan
048: *
049: */
050: public class SorterTableColumnModel implements TableColumnModel {
051:
052: private ArrayList<Sortables> order = new ArrayList<Sortables>();
053: private boolean[] showOrder = new boolean[Sortables.values().length];
054: private ArrayList<TableColumn> columnList = new ArrayList<TableColumn>();
055: private DefaultListSelectionModel dlsm;
056: private ArrayList<TableColumnModelListener> watchers = new ArrayList<TableColumnModelListener>();
057: private boolean frozen = false;
058:
059: public SorterTableColumnModel(Sortables[] columnHeaders) {
060:
061: for (int x = 0; x < columnHeaders.length; x++) {
062: Sortables c = columnHeaders[x];
063: //System.out.println(c);
064: for (int y = 0; y < Sortables.values().length; y++) {
065: if (c.equals(Sortables.values()[y]))
066: showOrder[y] = true;
067: }
068:
069: TableColumn tc = new TableColumn(x);
070: FBTableCellRenderer temp = new FBTableCellRenderer();
071: tc.setHeaderRenderer(temp);
072: tc.setIdentifier(c);
073: tc.setHeaderValue(c);
074: tc.setResizable(false);
075: tc.sizeWidthToFit();
076: columnList.add(tc);
077: }
078: dlsm = new DefaultListSelectionModel();
079: dlsm.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
080: orderUpdate();
081: }
082:
083: public void createFrom(SorterTableColumnModel other) {
084: if (this .getOrder().equals(other.getOrder()))
085: return;
086: columnList.clear();
087: for (int x = 0; x < order.size(); x++) {
088: for (TableColumnModelListener l : watchers)
089: l.columnRemoved(new TableColumnModelEvent(this , x, x));
090: }
091:
092: //First, empty showOrder
093: for (int x = 0; x < showOrder.length; x++)
094: showOrder[x] = false;
095:
096: for (int x = 0; x < other.order.size(); x++) {
097: Sortables c = other.order.get(x);
098: for (int y = 0; y < Sortables.values().length; y++) {
099: if (c.equals(Sortables.values()[y]))
100: showOrder[y] = true;//Then refill it, this allows sorterDialog to keep track of whats open
101: }
102:
103: TableColumn tc = new TableColumn(x);
104: tc.setHeaderRenderer(new FBTableCellRenderer());
105: tc.setIdentifier(c);
106: tc.setHeaderValue(c);
107: tc.setResizable(false);
108: tc.sizeWidthToFit();
109: columnList.add(tc);
110: for (TableColumnModelListener l : watchers)
111: l.columnAdded(new TableColumnModelEvent(this , x, x));
112: }
113: dlsm = new DefaultListSelectionModel();
114: dlsm.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
115:
116: orderUpdate();
117:
118: }
119:
120: public SorterTableColumnModel(ArrayList<Sortables> columnHeaders) {
121: this (columnHeaders.toArray(new Sortables[columnHeaders.size()]));
122: }
123:
124: static class FBTableCellRenderer implements TableCellRenderer {
125:
126: private TableCellRenderer defaultRenderer = new JTableHeader()
127: .getDefaultRenderer();
128:
129: public Component getTableCellRendererComponent(JTable table,
130: Object value, boolean isSelected, boolean hasFocus,
131: int row, int column) {
132:
133: Component comp = defaultRenderer
134: .getTableCellRendererComponent(table, value,
135: isSelected, hasFocus, row, column);
136: if (comp instanceof JLabel) {
137: JLabel cell = (JLabel) comp;
138: cell.setFont(cell.getFont().deriveFont(
139: Driver.getFontSize()));
140: cell.setFont(cell.getFont().deriveFont(Font.BOLD));
141: cell.setBorder(BorderFactory.createCompoundBorder(cell
142: .getBorder(), BorderFactory.createEmptyBorder(
143: 0, 6, 0, 6)));
144: cell.setHorizontalAlignment(SwingConstants.CENTER);
145: if (value == Sortables.DIVIDER) {
146: cell.setText("");
147: cell.setIcon(new ImageIcon(MainFrame.class
148: .getResource("arrows.png")));
149: new ImageIcon("a");
150: }
151: }
152: return comp;
153: }
154: }
155:
156: public void addColumn(TableColumn arg0) {
157: throw new UnsupportedOperationException(
158: "Can't change sorter table columns using addColumn");
159: }
160:
161: public void removeColumn(TableColumn arg0) {
162: throw new UnsupportedOperationException(
163: "Can't change sorter table columns using removeColumn");
164: }
165:
166: boolean[] getVisibleColumns() {
167: return showOrder;
168: }
169:
170: void setIndexChanged(int index) {
171: showOrder[index] = !showOrder[index];
172: Sortables s = Sortables.values()[index];
173:
174: boolean on = showOrder[index];
175:
176: if (on) {
177: TableColumn tc = new TableColumn(columnList.size());
178: tc.setHeaderRenderer(new FBTableCellRenderer());
179: tc.setIdentifier(s);
180: tc.setHeaderValue(s);
181: tc.setResizable(false);
182: tc.sizeWidthToFit();
183: columnList.add(tc);
184: for (int x = 0; x < columnList.size(); x++) {
185: columnList.get(x).setModelIndex(x);
186: }
187: orderUpdate();
188: for (TableColumnModelListener l : watchers) {
189: l.columnAdded(new TableColumnModelEvent(this ,
190: columnList.size() - 1, columnList.size() - 1));
191: }
192: } else if (!on) {
193: for (int x = 0; x < columnList.size(); x++) {
194: columnList.get(x).setModelIndex(x);
195: }
196:
197: for (int counter = 0; counter < columnList.size(); counter++) {
198: TableColumn tc = columnList.get(counter);
199: if (tc.getIdentifier().equals(s)) {
200: columnList.remove(counter);
201: for (int x = counter; x < columnList.size(); x++) {
202: columnList.get(x).setModelIndex(x);
203: }
204:
205: orderUpdate();
206: for (TableColumnModelListener l : watchers)
207: l.columnRemoved(new TableColumnModelEvent(this ,
208: counter, counter));
209:
210: }
211: }
212: }
213:
214: }
215:
216: public void moveColumn(int fromIndex, int toIndex) {
217:
218: MainFrame.getInstance().updateDesignationDisplay();
219: MainFrame.getInstance().saveComments();
220: TableColumn from = columnList.get(fromIndex);
221: TableColumn to = columnList.get(toIndex);
222:
223: columnList.set(fromIndex, to);
224: to.setModelIndex(fromIndex);
225:
226: columnList.set(toIndex, from);
227: from.setModelIndex(toIndex);
228:
229: orderUpdate();
230:
231: for (TableColumnModelListener w : (ArrayList<TableColumnModelListener>) watchers
232: .clone()) {
233: w.columnMoved(new TableColumnModelEvent(this , fromIndex,
234: toIndex));
235: }
236: }
237:
238: public void setColumnMargin(int arg0) {
239: throw new UnsupportedOperationException("NoBah");
240: }
241:
242: public int getColumnCount() {
243: return columnList.size();
244: }
245:
246: public Enumeration<TableColumn> getColumns() {
247: return Collections.enumeration(columnList);
248: }
249:
250: public int getColumnIndex(Object columnIdentifier) {
251:
252: if (columnIdentifier == null)
253: throw new IllegalArgumentException(
254: "Dont send null to getColumnIndex, null shouldn't be in the sorting table.");
255:
256: for (int x = 0; x < columnList.size(); x++) {
257: if (columnList.get(x).getIdentifier().equals(
258: columnIdentifier))
259: return x;
260: }
261:
262: throw new IllegalArgumentException();
263: }
264:
265: public TableColumn getColumn(int x) {
266: return columnList.get(x);
267: }
268:
269: public int getColumnMargin() {
270: return 0;
271: }
272:
273: public int getColumnIndexAtX(int XPosition) {
274:
275: for (TableColumn tc : columnList) {
276: XPosition -= tc.getWidth();
277: if (XPosition < 0)
278: return tc.getModelIndex();
279: }
280: return -1;
281: }
282:
283: public int getTotalColumnWidth() {
284: int total = 0;
285: for (TableColumn tc : columnList) {
286: total += tc.getWidth();
287: }
288: return total;
289: }
290:
291: public void setColumnSelectionAllowed(boolean arg0) {
292: throw new UnsupportedOperationException("BAH");//BAH
293: }
294:
295: public boolean getColumnSelectionAllowed() {
296: return true;
297: }
298:
299: public int[] getSelectedColumns() {
300: int index = dlsm.getMinSelectionIndex();
301: if (index == -1)
302: return new int[] {};
303: return new int[] { index };
304: }
305:
306: public int getSelectedColumnCount() {
307:
308: if (dlsm.getMinSelectionIndex() == -1)
309: return 0;
310: return 1;
311: }
312:
313: public void setSelectionModel(ListSelectionModel arg0) {
314: throw new UnsupportedOperationException("No... NO NO NO NO");
315: }
316:
317: public ListSelectionModel getSelectionModel() {
318: return dlsm;
319: }
320:
321: public void addColumnModelListener(TableColumnModelListener listener) {
322: watchers.add(listener);
323: }
324:
325: public void removeColumnModelListener(
326: TableColumnModelListener listener) {
327: watchers.remove(listener);
328: }
329:
330: public void columnSelectionChanged(ListSelectionEvent arg0) {
331: throw new UnsupportedOperationException(
332: "columnSelectionChangedBAH");
333: }
334:
335: ArrayList<Sortables> getOrder() {
336: return order;
337: }
338:
339: List<Sortables> getOrderBeforeDivider() {
340: if (!order.contains(Sortables.DIVIDER))
341: return order;
342:
343: return order.subList(0, order.indexOf(Sortables.DIVIDER));
344: }
345:
346: List<Sortables> getOrderAfterDivider() {
347: if (!order.contains(Sortables.DIVIDER)
348: || order.indexOf(Sortables.DIVIDER) == order.size() - 1)
349: return new ArrayList<Sortables>();
350:
351: return order.subList(order.indexOf(Sortables.DIVIDER) + 1,
352: order.size());
353: }
354:
355: private void orderUpdate() {
356: //order.clear();
357: if (!frozen) {
358: order = new ArrayList<Sortables>();
359: for (int x = 0; x < columnList.size(); x++) {
360: order
361: .add((Sortables) columnList.get(x)
362: .getIdentifier());
363: }
364: }
365: }
366:
367: public void freezeOrder() {
368: frozen = true;
369: }
370:
371: @SwingThread
372: public void thawOrder() {
373: frozen = false;
374: orderUpdate();
375: TreeModel model = MainFrame.getInstance().getTree().getModel();
376: if (model instanceof BugTreeModel) {
377: ((BugTreeModel) model).checkSorter();
378: }
379: }
380: }
|