All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jdesktop.swingx.table.DefaultTableColumnModelExt Maven / Gradle / Ivy

There is a newer version: 1.6.5-1
Show newest version
/*
 * $Id: DefaultTableColumnModelExt.java 3975 2011-03-28 14:05:29Z kleopatra $
 *
 * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
 * Santa Clara, California 95054, U.S.A. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library 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
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

package org.jdesktop.swingx.table;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import javax.swing.event.EventListenerList;
import javax.swing.event.TableColumnModelListener;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.TableColumn;

import org.jdesktop.swingx.event.TableColumnModelExtListener;


/**
 * A default implementation of TableColumnModelExt.
 * 

* * TODO: explain sub-optimal notification on showing/hiding columns. * (hot fixed issues #156, #157. To really do it * need enhanced TableColumnModelEvent and -Listeners that are * aware of the event.) * * * @author Richard Bair * @author Jeanette Winzenburg */ public class DefaultTableColumnModelExt extends DefaultTableColumnModel implements TableColumnModelExt { /** flag to distinguish a shown/hidden column from really added/removed * columns during notification. This is brittle! */ // private static final String IGNORE_EVENT = "TableColumnModelExt.ignoreEvent"; private boolean isVisibilityChange; /** * contains a list of all columns, in the order in which were * added to the model. */ private List initialColumns = new ArrayList(); /** * contains a list of all column, in the order they would appear if * all were visible. */ private List currentColumns = new ArrayList(); /** * Listener attached to TableColumnExt instances to listen for changes * to their visibility status, and to hide/show the column as oppropriate */ private VisibilityListener visibilityListener = new VisibilityListener(); /** * Creates a an empty DefaultTableColumnModelExt. */ public DefaultTableColumnModelExt() { super(); } //----------------------- implement TableColumnModelExt /** * {@inheritDoc} */ @Override public List getColumns(boolean includeHidden) { if (includeHidden) { return new ArrayList(initialColumns); } return Collections.list(getColumns()); } /** * {@inheritDoc} */ @Override public int getColumnCount(boolean includeHidden) { if (includeHidden) { return initialColumns.size(); } return getColumnCount(); } /** * {@inheritDoc} */ @Override public TableColumnExt getColumnExt(Object identifier) { for (Iterator iter = initialColumns.iterator(); iter.hasNext();) { TableColumn column = iter.next(); if ((column instanceof TableColumnExt) && (identifier.equals(column.getIdentifier()))) { return (TableColumnExt) column; } } return null; } /** * {@inheritDoc} */ @Override public TableColumnExt getColumnExt(int columnIndex) { TableColumn column = getColumn(columnIndex); if (column instanceof TableColumnExt) { return (TableColumnExt) column; } return null; } /** * hot fix for #157: listeners that are aware of * the possible existence of invisible columns * should check if the received columnRemoved originated * from moving a column from visible to invisible. * * @param oldIndex the fromIndex of the columnEvent * @return true if the column was moved to invisible */ public boolean isRemovedToInvisibleEvent(int oldIndex) { return isVisibilityChange; } /** * hot fix for #157: listeners that are aware of * the possible existence of invisible columns * should check if the received columnAdded originated * from moving a column from invisible to visible. * * @param newIndex the toIndex of the columnEvent * @return true if the column was moved to visible */ public boolean isAddedFromInvisibleEvent(int newIndex) { return isVisibilityChange; } //------------------------ TableColumnModel /** * {@inheritDoc}

* * Overridden to update internals related to column visibility. */ @Override public void removeColumn(TableColumn column) { boolean oldVisible = true; //remove the visibility listener if appropriate if (column instanceof TableColumnExt) { oldVisible = ((TableColumnExt) column).isVisible(); ((TableColumnExt) column).setVisible(true); ((TableColumnExt)column).removePropertyChangeListener(visibilityListener); } currentColumns.remove(column); initialColumns.remove(column); //let the superclass handle notification etc super.removeColumn(column); if (column instanceof TableColumnExt) { ((TableColumnExt) column).setVisible(oldVisible); } } /** * {@inheritDoc}

* * Overridden to update internals related to column visibility. */ @Override public void addColumn(TableColumn aColumn) { // hacking to guarantee correct events // two step: add as visible, setVisible boolean oldVisible = true; //add the visibility listener if appropriate if (aColumn instanceof TableColumnExt) { TableColumnExt xColumn = (TableColumnExt) aColumn; oldVisible = xColumn.isVisible(); xColumn.setVisible(true); xColumn.addPropertyChangeListener(visibilityListener); } // append the column to the end of both initial- and currentColumns. currentColumns.add(aColumn); initialColumns.add(aColumn); // let super handle the event notification, super.book-keeping super.addColumn(aColumn); if (aColumn instanceof TableColumnExt) { // reset original visibility ((TableColumnExt) aColumn).setVisible(oldVisible); } } /** * {@inheritDoc}

* * Overridden to update internals related to column visibility. */ @Override public void moveColumn(int columnIndex, int newIndex) { if (columnIndex != newIndex) { updateCurrentColumns(columnIndex, newIndex); } super.moveColumn(columnIndex, newIndex); } /** * Adjusts the current column sequence when a visible column is moved. * * @param oldIndex the old visible position. * @param newIndex the new visible position. */ private void updateCurrentColumns(int oldIndex, int newIndex) { TableColumn movedColumn = tableColumns.elementAt(oldIndex); int oldPosition = currentColumns.indexOf(movedColumn); TableColumn targetColumn = tableColumns.elementAt(newIndex); int newPosition = currentColumns.indexOf(targetColumn); currentColumns.remove(oldPosition); currentColumns.add(newPosition, movedColumn); } /** * Update internal state after the visibility of the column * was changed to invisible. The given column is assumed to * be contained in this model. * * @param col the column which was hidden. */ protected void moveToInvisible(TableColumnExt col) { isVisibilityChange = true; super.removeColumn(col); isVisibilityChange = false; } /** * Update internal state after the visibility of the column * was changed to visible. The given column is assumed to * be contained in this model. * * @param col the column which was made visible. */ protected void moveToVisible(TableColumnExt col) { isVisibilityChange = true; // two step process: first add at end of columns // then move to "best" position relative to where it // was before hiding. super.addColumn(col); // this is analogous to the proposed fix in #253-swingx // but uses the currentColumns as reference. Integer addIndex = currentColumns.indexOf(col); for (int i = 0; i < (getColumnCount() - 1); i++) { TableColumn tableCol = getColumn(i); int actualPosition = currentColumns.indexOf(tableCol); if (actualPosition > addIndex) { super.moveColumn(getColumnCount() - 1, i); break; } } isVisibilityChange = false; } /** * TODO JW: move into propertyChanged! No need for a dedicated listener. * Changed evaluation JW: may still be required as super removes itself as * propertyChangeListener if column is hidden */ private class VisibilityListener implements PropertyChangeListener, Serializable { @Override public void propertyChange(PropertyChangeEvent evt) { if ("visible".equals(evt.getPropertyName())) { TableColumnExt columnExt = (TableColumnExt)evt.getSource(); if (columnExt.isVisible()) { moveToVisible(columnExt); fireColumnPropertyChange(evt); } else { moveToInvisible(columnExt); } } else if (!((TableColumnExt) evt.getSource()).isVisible()) { fireColumnPropertyChange(evt); } } } // enhanced listener notification /** * Exposed for testing only - don't use! Will be removed again! * @return super's listener list */ protected EventListenerList getEventListenerList() { return listenerList; } /** * {@inheritDoc} */ @Override public void propertyChange(PropertyChangeEvent evt) { super.propertyChange(evt); fireColumnPropertyChange(evt); } /** * Notifies TableColumnModelExtListeners about property * changes of contained columns. The event instance * is the original as fired by the TableColumn. * @param evt the event received * @see EventListenerList */ protected void fireColumnPropertyChange(PropertyChangeEvent evt) { // if (IGNORE_EVENT.equals(evt.getPropertyName())) return; // Guaranteed to return a non-null array Object[] listeners = listenerList.getListenerList(); // Process the listeners last to first, notifying // those that are interested in this event for (int i = listeners.length-2; i>=0; i-=2) { if (listeners[i]==TableColumnModelExtListener.class) { ((TableColumnModelExtListener)listeners[i+1]). columnPropertyChange(evt); } } } /** * {@inheritDoc}

* * * Overridden to install enhanced notification of listeners of type. * TableColumnModelListenerExt about property changes of contained columns. * */ @Override public void addColumnModelListener(TableColumnModelListener x) { super.addColumnModelListener(x); if (x instanceof TableColumnModelExtListener) { listenerList.add(TableColumnModelExtListener.class, (TableColumnModelExtListener) x); } } /** * {@inheritDoc}

* * Overridden to uninstall enhanced notification of listeners of type. * TableColumnModelListenerExt about property changes of contained columns. */ @Override public void removeColumnModelListener(TableColumnModelListener x) { super.removeColumnModelListener(x); if (x instanceof TableColumnModelExtListener) { listenerList.remove(TableColumnModelExtListener.class, (TableColumnModelExtListener) x); } } /** * @return array of all registered listeners */ public TableColumnModelExtListener[] getTableColumnModelExtListeners() { return listenerList.getListeners(TableColumnModelExtListener.class); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy