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

net.sf.cuf.ui.table.ColumnVisibilitySupport Maven / Gradle / Ivy

The newest version!
package net.sf.cuf.ui.table;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.JTable;
import javax.swing.event.EventListenerList;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;


/**
 * Support showing/hiding columns in a {@link JTable}. It has to be bound to a table instance upon creation.
 * 
* It assumes that there is a 1:1 mapping from model columns to view columns (each model column must be displayed in * exactly one view column). *
* Be careful when manipulating the column model of the table from the application. * There might be conflicts with the column showing/hiding. Especially two points have * to be observed: do not try to remove any hidden columns from the column model and do * not break the 1:1 mapping between model and view columns. *

* This class notifies listeners about each showing/hiding of columns. *

* This class listens for changes of the column model of the table. Whenever the column model is replaced * by another instance all the invisible columns are forgotten. Unfortunately we are not able to notice * all changes. So the application may have to explicitly call {@link #clearInvisibleColumns}. * See {@link SortingTable#createDefaultColumnsFromModel} for a possible solution of this problem. * * @author Hendrik Wördehoff, sd&m AG */ public class ColumnVisibilitySupport implements PropertyChangeListener { /** Property name from {@link JTable}. */ private static final String TABLE_PROPERTY_COLUMN_MODEL = "columnModel"; /** Property name from {@link JTable}. */ private static final String TABLE_PROPERTY_MODEL = "model"; /** Property name from {@link JTable}. */ private static final String TABLE_PROPERTY_AUTO_CREATE_COLUMNS_FROM_MODEL = "autoCreateColumnsFromModel"; /** Table to operate on. */ protected JTable mTable; /** * List of currently invisible table columns. * The removed {@link TableColumn} objects are stored in this list. */ protected List mInvisibleColumns = new ArrayList<>(); /** * List of {@link ColumnVisibilityChangeListener}s. */ protected EventListenerList mListenerList = new EventListenerList(); /** * Constructor. * We install ourselves as property change listener on the table. * * @param pTable table to operate on (must not be null) */ public ColumnVisibilitySupport(final JTable pTable) { if ( pTable == null ) throw new IllegalArgumentException("table must not be null"); this.mTable = pTable; pTable.addPropertyChangeListener(this); } /** * Access the table we work on. * * @return table this instance operates on */ public JTable getTable() { return mTable; } /** * Hide a column of our table. * Listeners are notified after the column is hidden. * * @param pModelIndex column index in the table model */ protected void hideColumn(final int pModelIndex) { int viewIndex = mTable.convertColumnIndexToView(pModelIndex); if (viewIndex >= 0) { // make table column invisible TableColumnModel tcm = mTable.getColumnModel(); TableColumn col = tcm.getColumn(viewIndex); tcm.removeColumn(col); mInvisibleColumns.add(col); // notify listeners fireColumnVisibilityEventHidden(col); } } /** * Show a column of this table. * Listeners are notified after the column is shown. * * @param pModelIndex column index in the table model */ protected void showColumn(final int pModelIndex) { for (Iterator i = mInvisibleColumns.iterator(); i.hasNext();) { TableColumn col = i.next(); if (col.getModelIndex() == pModelIndex) { // make table column visible mTable.getColumnModel().addColumn(col); i.remove(); // notify listeners fireColumnVisibilityEventShown(col); // finished return; } } } /** * Test whether a table column is currently visible. * * @param pModelIndex column index in the table model * @return true if table column is visible */ public boolean isColumnVisible(final int pModelIndex) { return mTable.convertColumnIndexToView(pModelIndex) >= 0; } /** * Show or hide a table column. * * @param pModelIndex column index in the table model * @param pVisible true to make the column visible */ public void setColumnVisible(final int pModelIndex, final boolean pVisible) { if (pVisible) showColumn(pModelIndex); else hideColumn(pModelIndex); // will resize one or more of the columns in the table // so that the total width of all of the JTable's columns will be equal to the width of the table mTable.sizeColumnsToFit(-1); } /** * Get the visibility of all table columns at once. * The visibility is modeled as a boolean[]. There is an * entry in this array for each table model column. true * means the respective column is visible. false makes the * column hidden. * * @return visiblity information for each column in the table model */ public boolean[] getColumnsVisible() { boolean[] visible = new boolean[mTable.getModel().getColumnCount()]; for (int i = 0; i < visible.length; i++) { visible[i] = isColumnVisible(i); } return visible; } /** * Set the visibility of all table columns at once. * The visibility is modeled as a boolean[]. There must be an * entry in this array for each table model column. true * means the respective column is visible. false makes the * column hidden. * * @param pVisible visiblity information for each column in the table model * @throws IllegalArgumentException if visible is null or has a different number of entries than the table model */ public void setColumnsVisible(final boolean[] pVisible) { int columnCount = mTable.getModel().getColumnCount(); if (pVisible == null || pVisible.length != columnCount) throw new IllegalArgumentException("visible must not be null and must contain the same number of columns as the table model"); for (int i = 0; i < columnCount; i++) { if (isColumnVisible(i) != pVisible[i]) { setColumnVisible(i, pVisible[i]); } } } /** * Make all table columns visible. */ public void setAllColumnsVisible() { int columnCount = mTable.getModel().getColumnCount(); for (int i = 0; i < columnCount; i++) { if (!isColumnVisible(i)) { setColumnVisible(i, true); } } } /** * Test if all columns are visible. * * @return true if there are currently no invisible columns */ public boolean isAllColumnsVisible() { return mInvisibleColumns.isEmpty(); } /** * Fetch the hidden table column for a model index. * If the table column with the index is not hidden this method will return null. * @param pModelIndex the model index * @return table column object with the fitting model index or null */ public TableColumn getInvisibleColumn(final int pModelIndex) { for (final Object invisibleColumn : mInvisibleColumns) { TableColumn t = (TableColumn) invisibleColumn; if (t.getModelIndex() == pModelIndex) return t; } return null; } /** * Clear the list of invisible columns. *

* This method must be called whenever the table column model is changed completely. * We do our best to catch this in {@link #propertyChange(java.beans.PropertyChangeEvent)}. But we cannot notice all * changes. So you have to call this e.g. whenever {@link JTable#createDefaultColumnsFromModel} * is called explicitely. */ public void clearInvisibleColumns() { mInvisibleColumns.clear(); } /*** Property change listener *********************************************/ /** * Forget all invisible columns if the column model of the table is changed. * This may happen either by an explicitly {@link JTable#setColumnModel(TableColumnModel)} or * implicitly by any action that calls {@link JTable#createDefaultColumnsFromModel}. * * @param pEvent information about the changed property */ public void propertyChange(final PropertyChangeEvent pEvent) { String propertyName = pEvent.getPropertyName(); if ( TABLE_PROPERTY_COLUMN_MODEL.equals(propertyName) ) // setColumnModel { //noinspection ObjectEquality if ( pEvent.getNewValue() != pEvent.getOldValue() ) { clearInvisibleColumns(); } } else if ( TABLE_PROPERTY_AUTO_CREATE_COLUMNS_FROM_MODEL.equals(propertyName) || // setAutoCreateColumnsFromModel TABLE_PROPERTY_MODEL .equals(propertyName) ) // setModel { if ( mTable.getAutoCreateColumnsFromModel() ) { // setAutoCreateColumnsFromModel and setModel call createDefaultColumnsFromModel if autoCreateColumnsFromModel is true clearInvisibleColumns(); } } } /*** Listener support *****************************************************/ /** * Add a listener for showing/hiding of columns. * * @param pListener listener to add */ public void addColumnVisibilityChangeListener(final ColumnVisibilityChangeListener pListener) { mListenerList.add(ColumnVisibilityChangeListener.class, pListener); } /** * Remove a listener for showing/hiding of columns. * * @param pListener listener to remove */ public void removeColumnVisibilityChangeListener(final ColumnVisibilityChangeListener pListener) { mListenerList.remove(ColumnVisibilityChangeListener.class, pListener); } /** * Notify our listeners that a table column was shown. * * @param pColumn column that was shown */ protected void fireColumnVisibilityEventShown(final TableColumn pColumn) { ColumnVisibilityChangeEvent event = new ColumnVisibilityChangeEvent(this, mTable, pColumn); // Process the listeners last to first, notifying those that are interested in this event Object[] listeners = mListenerList.getListenerList(); // could be improved with getListeners() under 1.3 for ( int i = listeners.length-2; i>=0; i-=2 ) { if ( listeners[i] == ColumnVisibilityChangeListener.class ) { ((ColumnVisibilityChangeListener)listeners[i+1]).columnShown(event); } } } /** * Notify our listeners that a table column was hidden. * * @param pColumn column that was hidden */ protected void fireColumnVisibilityEventHidden(final TableColumn pColumn) { ColumnVisibilityChangeEvent event = new ColumnVisibilityChangeEvent(this, mTable, pColumn); // Process the listeners last to first, notifying those that are interested in this event Object[] listeners = mListenerList.getListenerList(); // could be improved with getListeners() under 1.3 for ( int i = listeners.length-2; i>=0; i-=2 ) { if ( listeners[i] == ColumnVisibilityChangeListener.class ) { ((ColumnVisibilityChangeListener)listeners[i+1]).columnHidden(event); } } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy