diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /libjava/classpath/javax/swing/table/DefaultTableColumnModel.java | |
download | cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2 cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz |
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig;
imported gcc-4.6.4 source tree from verified upstream tarball.
downloading a git-generated archive based on the 'upstream' tag
should provide you with a source tree that is binary identical
to the one extracted from the above tarball.
if you have obtained the source via the command 'git clone',
however, do note that line-endings of files in your working
directory might differ from line-endings of the respective
files in the upstream repository.
Diffstat (limited to 'libjava/classpath/javax/swing/table/DefaultTableColumnModel.java')
-rw-r--r-- | libjava/classpath/javax/swing/table/DefaultTableColumnModel.java | 671 |
1 files changed, 671 insertions, 0 deletions
diff --git a/libjava/classpath/javax/swing/table/DefaultTableColumnModel.java b/libjava/classpath/javax/swing/table/DefaultTableColumnModel.java new file mode 100644 index 000000000..532b513a9 --- /dev/null +++ b/libjava/classpath/javax/swing/table/DefaultTableColumnModel.java @@ -0,0 +1,671 @@ +/* DefaultTableColumnModel.java -- + Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.swing.table; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.Serializable; +import java.util.Enumeration; +import java.util.EventListener; +import java.util.Vector; + +import javax.swing.DefaultListSelectionModel; +import javax.swing.JTable; +import javax.swing.ListSelectionModel; +import javax.swing.event.ChangeEvent; +import javax.swing.event.EventListenerList; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.event.TableColumnModelEvent; +import javax.swing.event.TableColumnModelListener; + +/** + * A model that stores information about the columns used in a {@link JTable}. + * + * @see JTable#setColumnModel(TableColumnModel) + * + * @author Andrew Selkirk + */ +public class DefaultTableColumnModel + implements TableColumnModel, PropertyChangeListener, ListSelectionListener, + Serializable +{ + private static final long serialVersionUID = 6580012493508960512L; + + /** + * Storage for the table columns. + */ + protected Vector<TableColumn> tableColumns; + + /** + * A selection model that keeps track of column selections. + */ + protected ListSelectionModel selectionModel; + + /** + * The space between the columns (the default value is <code>1</code>). + */ + protected int columnMargin; + + /** + * Storage for the listeners registered with the model. + */ + protected EventListenerList listenerList = new EventListenerList(); + + /** + * A change event used when notifying listeners of a change to the + * <code>columnMargin</code> field. This single event is reused for all + * notifications (it is lazily instantiated within the + * {@link #fireColumnMarginChanged()} method). + */ + protected transient ChangeEvent changeEvent; + + /** + * A flag that indicates whether or not columns can be selected. + */ + protected boolean columnSelectionAllowed; + + /** + * The total width of all the columns in this model. + */ + protected int totalColumnWidth; + + /** + * Creates a new table column model with zero columns. A default column + * selection model is created by calling {@link #createSelectionModel()}. + * The default value for <code>columnMargin</code> is <code>1</code> and + * the default value for <code>columnSelectionAllowed</code> is + * <code>false</code>. + */ + public DefaultTableColumnModel() + { + tableColumns = new Vector(); + selectionModel = createSelectionModel(); + selectionModel.addListSelectionListener(this); + columnMargin = 1; + columnSelectionAllowed = false; + } + + /** + * Adds a column to the model then calls + * {@link #fireColumnAdded(TableColumnModelEvent)} to notify the registered + * listeners. The model registers itself with the column as a + * {@link PropertyChangeListener} so that changes to the column width will + * invalidate the cached {@link #totalColumnWidth} value. + * + * @param column the column (<code>null</code> not permitted). + * + * @throws IllegalArgumentException if <code>column</code> is + * <code>null</code>. + * + * @see #removeColumn(TableColumn) + */ + public void addColumn(TableColumn column) + { + if (column == null) + throw new IllegalArgumentException("Null 'col' argument."); + tableColumns.add(column); + column.addPropertyChangeListener(this); + invalidateWidthCache(); + fireColumnAdded(new TableColumnModelEvent(this, 0, + tableColumns.size() - 1)); + } + + /** + * Removes a column from the model then calls + * {@link #fireColumnRemoved(TableColumnModelEvent)} to notify the registered + * listeners. If the specified column does not belong to the model, or is + * <code>null</code>, this method does nothing. + * + * @param column the column to be removed (<code>null</code> permitted). + * + * @see #addColumn(TableColumn) + */ + public void removeColumn(TableColumn column) + { + int index = this.tableColumns.indexOf(column); + if (index < 0) + return; + tableColumns.remove(column); + fireColumnRemoved(new TableColumnModelEvent(this, index, 0)); + column.removePropertyChangeListener(this); + invalidateWidthCache(); + } + + /** + * Moves the column at index i to the position specified by index j, then + * calls {@link #fireColumnMoved(TableColumnModelEvent)} to notify registered + * listeners. + * + * @param i index of the column that will be moved. + * @param j index of the column's new location. + * + * @throws IllegalArgumentException if <code>i</code> or <code>j</code> are + * outside the range <code>0</code> to <code>N-1</code>, where + * <code>N</code> is the column count. + */ + public void moveColumn(int i, int j) + { + int columnCount = getColumnCount(); + if (i < 0 || i >= columnCount) + throw new IllegalArgumentException("Index 'i' out of range."); + if (j < 0 || j >= columnCount) + throw new IllegalArgumentException("Index 'j' out of range."); + TableColumn column = tableColumns.remove(i); + tableColumns.add(j, column); + fireColumnMoved(new TableColumnModelEvent(this, i, j)); + } + + /** + * Sets the column margin then calls {@link #fireColumnMarginChanged()} to + * notify the registered listeners. + * + * @param margin the column margin. + * + * @see #getColumnMargin() + */ + public void setColumnMargin(int margin) + { + columnMargin = margin; + fireColumnMarginChanged(); + } + + /** + * Returns the number of columns in the model. + * + * @return The column count. + */ + public int getColumnCount() + { + return tableColumns.size(); + } + + /** + * Returns an enumeration of the columns in the model. + * + * @return An enumeration of the columns in the model. + */ + public Enumeration<TableColumn> getColumns() + { + return tableColumns.elements(); + } + + /** + * Returns the index of the {@link TableColumn} with the given identifier. + * + * @param identifier the identifier (<code>null</code> not permitted). + * + * @return The index of the {@link TableColumn} with the given identifier. + * + * @throws IllegalArgumentException if <code>identifier</code> is + * <code>null</code> or there is no column with that identifier. + */ + public int getColumnIndex(Object identifier) + { + if (identifier == null) + throw new IllegalArgumentException("Null identifier."); + int columnCount = tableColumns.size(); + for (int i = 0; i < columnCount; i++) + { + TableColumn tc = tableColumns.get(i); + if (identifier.equals(tc.getIdentifier())) + return i; + } + throw new IllegalArgumentException("No TableColumn with that identifier."); + } + + /** + * Returns the column at the specified index. + * + * @param columnIndex the column index (in the range from <code>0</code> to + * <code>N-1</code>, where <code>N</code> is the number of columns in + * the model). + * + * @return The column at the specified index. + * + * @throws ArrayIndexOutOfBoundsException if <code>i</code> is not within + * the specified range. + */ + public TableColumn getColumn(int columnIndex) + { + return tableColumns.get(columnIndex); + } + + /** + * Returns the column margin. + * + * @return The column margin. + * + * @see #setColumnMargin(int) + */ + public int getColumnMargin() + { + return columnMargin; + } + + /** + * Returns the index of the column that contains the specified x-coordinate. + * This method assumes that: + * <ul> + * <li>column zero begins at position zero;</li> + * <li>all columns appear in order;</li> + * <li>individual column widths are taken into account, but the column margin + * is ignored.</li> + * </ul> + * If no column contains the specified position, this method returns + * <code>-1</code>. + * + * @param x the x-position. + * + * @return The column index, or <code>-1</code>. + */ + public int getColumnIndexAtX(int x) + { + for (int i = 0; i < tableColumns.size(); ++i) + { + int w = (tableColumns.get(i)).getWidth(); + if (0 <= x && x < w) + return i; + else + x -= w; + } + return -1; + } + + /** + * Returns total width of all the columns in the model, ignoring the + * {@link #columnMargin}. + * + * @return The total width of all the columns. + */ + public int getTotalColumnWidth() + { + if (totalColumnWidth == -1) + recalcWidthCache(); + return totalColumnWidth; + } + + /** + * Sets the selection model that will be used to keep track of the selected + * columns. + * + * @param model the selection model (<code>null</code> not permitted). + * + * @throws IllegalArgumentException if <code>model</code> is + * <code>null</code>. + * + * @see #getSelectionModel() + */ + public void setSelectionModel(ListSelectionModel model) + { + if (model == null) + throw new IllegalArgumentException(); + + selectionModel.removeListSelectionListener(this); + selectionModel = model; + selectionModel.addListSelectionListener(this); + } + + /** + * Returns the selection model used to track table column selections. + * + * @return The selection model. + * + * @see #setSelectionModel(ListSelectionModel) + */ + public ListSelectionModel getSelectionModel() + { + return selectionModel; + } + + /** + * Sets the flag that indicates whether or not column selection is allowed. + * + * @param flag the new flag value. + * + * @see #getColumnSelectionAllowed() + */ + public void setColumnSelectionAllowed(boolean flag) + { + columnSelectionAllowed = flag; + } + + /** + * Returns <code>true</code> if column selection is allowed, and + * <code>false</code> if column selection is not allowed. + * + * @return A boolean. + * + * @see #setColumnSelectionAllowed(boolean) + */ + public boolean getColumnSelectionAllowed() + { + return columnSelectionAllowed; + } + + /** + * Returns an array containing the indices of the selected columns. + * + * @return An array containing the indices of the selected columns. + */ + public int[] getSelectedColumns() + { + // FIXME: Implementation of this method was taken from private method + // JTable.getSelections(), which is used in various places in JTable + // including selected row calculations and cannot be simply removed. + // This design should be improved to illuminate duplication of code. + + ListSelectionModel lsm = this.selectionModel; + int sz = getSelectedColumnCount(); + int [] ret = new int[sz]; + + int lo = lsm.getMinSelectionIndex(); + int hi = lsm.getMaxSelectionIndex(); + int j = 0; + java.util.ArrayList ls = new java.util.ArrayList(); + if (lo != -1 && hi != -1) + { + switch (lsm.getSelectionMode()) + { + case ListSelectionModel.SINGLE_SELECTION: + ret[0] = lo; + break; + + case ListSelectionModel.SINGLE_INTERVAL_SELECTION: + for (int i = lo; i <= hi; ++i) + ret[j++] = i; + break; + + case ListSelectionModel.MULTIPLE_INTERVAL_SELECTION: + for (int i = lo; i <= hi; ++i) + if (lsm.isSelectedIndex(i)) + ret[j++] = i; + break; + } + } + return ret; + } + + /** + * Returns the number of selected columns in the model. + * + * @return The selected column count. + * + * @see #getSelectionModel() + */ + public int getSelectedColumnCount() + { + // FIXME: Implementation of this method was taken from private method + // JTable.countSelections(), which is used in various places in JTable + // including selected row calculations and cannot be simply removed. + // This design should be improved to illuminate duplication of code. + + ListSelectionModel lsm = this.selectionModel; + int lo = lsm.getMinSelectionIndex(); + int hi = lsm.getMaxSelectionIndex(); + int sum = 0; + + if (lo != -1 && hi != -1) + { + switch (lsm.getSelectionMode()) + { + case ListSelectionModel.SINGLE_SELECTION: + sum = 1; + break; + + case ListSelectionModel.SINGLE_INTERVAL_SELECTION: + sum = hi - lo + 1; + break; + + case ListSelectionModel.MULTIPLE_INTERVAL_SELECTION: + for (int i = lo; i <= hi; ++i) + if (lsm.isSelectedIndex(i)) + ++sum; + break; + } + } + + return sum; + } + + /** + * Registers a listener with the model, so that it will receive + * {@link TableColumnModelEvent} notifications. + * + * @param listener the listener (<code>null</code> ignored). + */ + public void addColumnModelListener(TableColumnModelListener listener) + { + listenerList.add(TableColumnModelListener.class, listener); + } + + /** + * Deregisters a listener so that it no longer receives notification of + * changes to this model. + * + * @param listener the listener to remove + */ + public void removeColumnModelListener(TableColumnModelListener listener) + { + listenerList.remove(TableColumnModelListener.class, listener); + } + + /** + * Returns an array containing the listeners that are registered with the + * model. If there are no listeners, an empty array is returned. + * + * @return An array containing the listeners that are registered with the + * model. + * + * @see #addColumnModelListener(TableColumnModelListener) + * @since 1.4 + */ + public TableColumnModelListener[] getColumnModelListeners() + { + return (TableColumnModelListener[]) + listenerList.getListeners(TableColumnModelListener.class); + } + + /** + * Sends the specified {@link TableColumnModelEvent} to all registered + * listeners, to indicate that a column has been added to the model. The + * event's <code>toIndex</code> attribute should contain the index of the + * added column. + * + * @param e the event. + * + * @see #addColumn(TableColumn) + */ + protected void fireColumnAdded(TableColumnModelEvent e) + { + TableColumnModelListener[] listeners = getColumnModelListeners(); + + for (int i = 0; i < listeners.length; i++) + listeners[i].columnAdded(e); + } + + /** + * Sends the specified {@link TableColumnModelEvent} to all registered + * listeners, to indicate that a column has been removed from the model. The + * event's <code>fromIndex</code> attribute should contain the index of the + * removed column. + * + * @param e the event. + * + * @see #removeColumn(TableColumn) + */ + protected void fireColumnRemoved(TableColumnModelEvent e) + { + TableColumnModelListener[] listeners = getColumnModelListeners(); + + for (int i = 0; i < listeners.length; i++) + listeners[i].columnRemoved(e); + } + + /** + * Sends the specified {@link TableColumnModelEvent} to all registered + * listeners, to indicate that a column in the model has been moved. The + * event's <code>fromIndex</code> attribute should contain the old column + * index, and the <code>toIndex</code> attribute should contain the new + * column index. + * + * @param e the event. + * + * @see #moveColumn(int, int) + */ + protected void fireColumnMoved(TableColumnModelEvent e) + { + TableColumnModelListener[] listeners = getColumnModelListeners(); + + for (int i = 0; i < listeners.length; i++) + listeners[i].columnMoved(e); + } + + /** + * Sends the specified {@link ListSelectionEvent} to all registered listeners, + * to indicate that the column selections have changed. + * + * @param e the event. + * + * @see #valueChanged(ListSelectionEvent) + */ + protected void fireColumnSelectionChanged(ListSelectionEvent e) + { + EventListener [] listeners = getListeners(TableColumnModelListener.class); + for (int i = 0; i < listeners.length; ++i) + ((TableColumnModelListener) listeners[i]).columnSelectionChanged(e); + } + + /** + * Sends a {@link ChangeEvent} to the model's registered listeners to + * indicate that the column margin was changed. + * + * @see #setColumnMargin(int) + */ + protected void fireColumnMarginChanged() + { + EventListener[] listeners = getListeners(TableColumnModelListener.class); + if (changeEvent == null && listeners.length > 0) + changeEvent = new ChangeEvent(this); + for (int i = 0; i < listeners.length; ++i) + ((TableColumnModelListener) listeners[i]).columnMarginChanged(changeEvent); + } + + /** + * Returns an array containing the listeners (of the specified type) that + * are registered with this model. + * + * @param listenerType the listener type (must indicate a subclass of + * {@link EventListener}, <code>null</code> not permitted). + * + * @return An array containing the listeners (of the specified type) that + * are registered with this model. + */ + public <T extends EventListener> T[] getListeners(Class<T> listenerType) + { + return listenerList.getListeners(listenerType); + } + + /** + * Receives notification of property changes for the columns in the model. + * If the <code>width</code> property for any column changes, we invalidate + * the {@link #totalColumnWidth} value here. + * + * @param event the event. + */ + public void propertyChange(PropertyChangeEvent event) + { + if (event.getPropertyName().equals("width")) + invalidateWidthCache(); + } + + /** + * Receives notification of the change to the list selection model, and + * responds by calling + * {@link #fireColumnSelectionChanged(ListSelectionEvent)}. + * + * @param e the list selection event. + * + * @see #getSelectionModel() + */ + public void valueChanged(ListSelectionEvent e) + { + fireColumnSelectionChanged(e); + } + + /** + * Creates a default selection model to track the currently selected + * column(s). This method is called by the constructor and returns a new + * instance of {@link DefaultListSelectionModel}. + * + * @return A new default column selection model. + */ + protected ListSelectionModel createSelectionModel() + { + return new DefaultListSelectionModel(); + } + + /** + * Recalculates the total width of the columns, if the cached value is + * <code>-1</code>. Otherwise this method does nothing. + * + * @see #getTotalColumnWidth() + */ + protected void recalcWidthCache() + { + if (totalColumnWidth == -1) + { + totalColumnWidth = 0; + for (int i = 0; i < tableColumns.size(); ++i) + { + totalColumnWidth += tableColumns.get(i).getWidth(); + } + } + } + + /** + * Sets the {@link #totalColumnWidth} field to <code>-1</code>. + * + * @see #recalcWidthCache() + */ + private void invalidateWidthCache() + { + totalColumnWidth = -1; + } +} |