FWTableColumnModel.java
| Index Score | ||
|---|---|---|
![]() |
![]() |
phex.gui.common.table |
![]() |
![]() |
Phex |
View: Reasons, Metrics, Source Code
These are the metrics that contribute to the Enerjy Score for this file, ranked by impact. So the metrics listed at the top influence the score to a greater extent that the metrics listed at the bottom.
/*
* PHEX - The pure-java Gnutella-servent.
* Copyright (C) 2001 - 2007 Phex Development Group
*
* This program 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 of the License, or
* (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* --- SVN Information ---
* $Id: FWTableColumnModel.java 3803 2007-05-19 14:13:56Z gregork $
*/
package phex.gui.common.table;
// This is a modified version of the SwingLabs class
// org.jdesktop.swingx.table.DefaultTableColumnModelExt
/*
* Id: DefaultTableColumnModelExt.java,v 1.20 2006/12/01 12:32:49 kleopatra Exp
*
* 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
*/
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.swing.event.EventListenerList;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.TableColumn;
/**
* A default implementation of <code>FWTableColumnModel</code>.
* <p>
*
* 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.)
*/
public class FWTableColumnModel extends DefaultTableColumnModel
{
/**
* 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";
/**
* contains a list of all columns, in the order in which were added to the
* model.
*/
private List<TableColumn> initialColumns = new ArrayList<TableColumn>();
/**
* contains a list of all column, in the order they would appear if all were
* visible.
*/
private List<TableColumn> currentColumns = new ArrayList<TableColumn>();
/**
* Set of invisible columns.
*/
private Set<FWTableColumn> invisibleColumns = new HashSet<FWTableColumn>();
/**
* used to distinguish a real remove from hiding.
*/
private Map<FWTableColumn, Integer> oldIndexes = new HashMap<FWTableColumn, Integer>();
/**
* 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 FWTableColumnModel()
{
super();
}
// ----------------------- implement TableColumnModelExt
/**
* {@inheritDoc}
*/
public List<TableColumn> getColumns(boolean includeHidden)
{
if ( includeHidden )
{
return new ArrayList<TableColumn>( initialColumns );
}
return Collections.list( getColumns() );
}
/**
* {@inheritDoc}
*/
public int getColumnCount(boolean includeHidden)
{
if ( includeHidden )
{
return initialColumns.size();
}
return getColumnCount();
}
/**
* {@inheritDoc}
*/
public FWTableColumn getFWColumn(Object identifier)
{
for ( Iterator<TableColumn> iter = initialColumns.iterator(); iter
.hasNext(); )
{
TableColumn column = iter.next();
if ( (column instanceof FWTableColumn)
&& (identifier.equals( column.getIdentifier() )) )
{
return (FWTableColumn) column;
}
}
return null;
}
/**
* {@inheritDoc}
*/
public FWTableColumn getFWColumn(int columnIndex)
{
TableColumn column = getColumn( columnIndex );
if ( column instanceof FWTableColumn )
{
return (FWTableColumn) 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 oldIndexes.containsValue( oldIndex );
}
// /**
// * 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)
// {
// if ( !(getColumn( newIndex ) instanceof FWTableColumn) )
// return false;
// return Boolean.TRUE.equals( ((FWTableColumn) getColumn( newIndex ))
// .getClientProperty( IGNORE_EVENT ) );
// }
// ------------------------ TableColumnModel
/**
* {@inheritDoc}
*/
@Override
public void removeColumn(TableColumn column)
{
// remove the visibility listener if appropriate
if ( column instanceof FWTableColumn )
{
((FWTableColumn) column)
.removePropertyChangeListener( visibilityListener );
}
// remove from the invisible columns set and the initialColumns list
// first
invisibleColumns.remove( column );
currentColumns.remove( column );
initialColumns.remove( column );
oldIndexes.remove( column );
// let the superclass handle notification etc
super.removeColumn( column );
}
/**
* {@inheritDoc}
*/
@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 FWTableColumn )
{
FWTableColumn xColumn = (FWTableColumn) aColumn;
oldVisible = xColumn.isVisible();
xColumn.setVisible( true );
xColumn.addPropertyChangeListener( visibilityListener );
}
// append the column to the end of "initialColumns". If the column is
// visible, let super add it to the list of columns. If not, then
// add it to the set of invisible columns and return.
// In the case of an invisible column being added to the model,
// I still do event notification for the model having
// been changed so that the ColumnControlButton or other similar
// code interacting with invisible columns knows that a new invisible
// column has been added
currentColumns.add( aColumn );
initialColumns.add( aColumn );
super.addColumn( aColumn );
if ( aColumn instanceof FWTableColumn )
{
((FWTableColumn) aColumn).setVisible( oldVisible );
}
}
/**
* {@inheritDoc}
*/
@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(FWTableColumn col)
{
// make invisible
invisibleColumns.add( col );
oldIndexes.put( col, tableColumns.indexOf( col ) );
super.removeColumn( col );
}
/**
* 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( FWTableColumn col )
{
invisibleColumns.remove( col );
// Integer oldIndex = oldIndexes.get(col);
// if (oldIndex == null) {
// oldIndex = getColumnCount();
// }
oldIndexes.remove( col );
// col.putClientProperty( IGNORE_EVENT, Boolean.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;
}
}
// col.putClientProperty( IGNORE_EVENT, null );
}
/**
* TODO move into propertyChanged! No need for a dedicated listener.
*/
private final class VisibilityListener implements PropertyChangeListener,
Serializable
{
public void propertyChange(PropertyChangeEvent evt)
{
if ( evt.getPropertyName().equals( "visible" ) )
{
boolean oldValue = ((Boolean) evt.getOldValue()).booleanValue();
boolean newValue = ((Boolean) evt.getNewValue()).booleanValue();
FWTableColumn col = (FWTableColumn) evt.getSource();
if ( oldValue && !newValue )
{
moveToInvisible( col );
} else if ( !oldValue && newValue )
{
moveToVisible( col );
}
}
}
}
// enhanced listener notification
/**
* Exposed for testing only - don't use! Will be removed again!
*
* @return super's listenerlist
*/
protected EventListenerList getEventListenerList()
{
return listenerList;
}
/**
* {@inheritDoc}
*/
@Override
public void propertyChange(PropertyChangeEvent evt)
{
super.propertyChange( evt );
// fireColumnPropertyChange( evt );
}
// /**
// * Notifies <code>TableColumnModelExtListener</code>s about property
// * changes of contained columns. The event instance is the original as fired
// * by the <code>TableColumn</code>.
// *
// * @param evt
// * the event received
// * @see EventListenerList
// */
// protected void fireColumnPropertyChange(PropertyChangeEvent evt)
// {
// // 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}
// */
// @Override
// public void addColumnModelListener(TableColumnModelListener x)
// {
// super.addColumnModelListener( x );
// if ( x instanceof TableColumnModelExtListener )
// {
// listenerList.add( TableColumnModelExtListener.class,
// (TableColumnModelExtListener) x );
// }
// }
//
// /**
// * {@inheritDoc}
// */
// @Override
// public void removeColumnModelListener(TableColumnModelListener x)
// {
// super.removeColumnModelListener( x );
// if ( x instanceof TableColumnModelExtListener )
// {
// listenerList.remove( TableColumnModelExtListener.class,
// (TableColumnModelExtListener) x );
// }
// }
}
The table below shows all metrics for FWTableColumnModel.java.




