001    /*
002     * $Id: TableColumnModelExt.java 3000 2008-07-30 16:43:15Z kleopatra $
003     *
004     * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
005     * Santa Clara, California 95054, U.S.A. All rights reserved.
006     *
007     * This library is free software; you can redistribute it and/or
008     * modify it under the terms of the GNU Lesser General Public
009     * License as published by the Free Software Foundation; either
010     * version 2.1 of the License, or (at your option) any later version.
011     * 
012     * This library is distributed in the hope that it will be useful,
013     * but WITHOUT ANY WARRANTY; without even the implied warranty of
014     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015     * Lesser General Public License for more details.
016     * 
017     * You should have received a copy of the GNU Lesser General Public
018     * License along with this library; if not, write to the Free Software
019     * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
020     */
021    
022    package org.jdesktop.swingx.table;
023    
024    import java.util.List;
025    
026    import javax.swing.event.TableColumnModelListener;
027    import javax.swing.table.TableColumn;
028    import javax.swing.table.TableColumnModel;
029    
030    import org.jdesktop.swingx.JXTable;
031    import org.jdesktop.swingx.event.TableColumnModelExtListener;
032    
033    /**
034     * An extension of <code>TableColumnModel</code> suitable for use with
035     * <code>JXTable</code>. It extends the notion of columns considered as part
036     * of the view realm to include invisible columns. Conceptually, there are
037     * several sets of "columns":
038     * 
039     * <ol>
040     * <li> model columns: all columns of a <code>TableModel</code>. They are but
041     * a virtual concept, characterizable f.i. by (model) column index, (model)
042     * column name.
043     * <li> view columns: all <code>TableColumnExt</code> objects added to the
044     * <code>TableColumnModelExt</code>, each typically created and configured in
045     * relation to a model column. These can be regarded as a kind of subset of the
046     * model columns (not literally, obviously). Each view column belongs to exactly
047     * one of the following (real) subsets:
048     * <ul>
049     * <li> visible columns: all view columns with the visibility property enabled
050     * <li> hidden columns: all view columns with the visibility property disabled
051     * </ul>
052     * </ol>
053     * 
054     * This class manages the view columns and automatically takes care of keeping
055     * track of their location in the visible/hidden subset, triggering the
056     * corresponding changes in interested views. Typically, a view column's 
057     * visibility can be toggled by user interaction, f.i. via a <code>ColumnControlButton</code>.
058     * <p>
059     * An example to programmatically hide
060     * the first visible column in the column model:
061     * 
062     * <pre><code>
063     * TableColumnExt columnExt = columnModel.getColumnExt(0);
064     * if (columnExt != null) {
065     *     columnExt.setVisible(false);
066     * }
067     * </code></pre>
068     * 
069     * Note that it is principally allowed to add standard <code>TableColumn</code>s.
070     * Practically, it doesn't make much sense to do so - they will always be
071     * visible.
072     * <p>
073     * 
074     * While individual visible columns can be requested by both column identifier
075     * and column index, the latter is not available for hidden columns. An example
076     * to programmatically guarantee that the view column which corresponds to the
077     * first column in the associated <code>TableModel</code>.
078     * 
079     * <pre><code>
080     * List&lt;TableColumn&gt; columns = colModel.getColumns(true);
081     * for (TableColumn column : columns) {
082     *     if (column.getModelIndex() == 0) {
083     *         if (column instanceof TableColumnExt) {
084     *             ((TableColumnExt) column).setVisible(false);
085     *         }
086     *         return;
087     *     }
088     * }
089     * </code></pre>
090     * 
091     * Alternatively, the column could be requested directly by identifier. By
092     * default the column's headerValue is returned as identifier, if none is set.
093     * 
094     * <pre><code>
095     * Object identifier = tableModel.getColumnName(0);
096     * TableColumnExt columnExt = columnModel.getColumnExt(identifier);
097     * if (columnExt != null) {
098     *     columnExt.setVisible(false);
099     * }
100     * </code></pre>
101     * 
102     * Relying on default identifiers is inherently brittle (<code>headerValue</code>s might
103     * change f.i. with <code>Locale</code>s), so explicit configuration of columns with
104     * identifiers is strongly recommended. A custom <code>ColumnFactory</code>
105     * helps to automate column configuration.
106     * <p>
107     * 
108     * 
109     * This class guarantees to notify registered
110     * <code>TableColumnModelListener</code>s of type 
111     * <code>TableColumnModelExtListener</code> about propertyChanges fired by
112     * contained <code>TableColumn</code>s. 
113     * An example of a client which adjusts itself based on
114     * <code>headerValue</code> property of visible columns: 
115     * <pre><code>
116     * TableColumnModelExtListener l = new TableColumnModelExtListener() {
117     * 
118     *     public void columnPropertyChange(PropertyChangeEvent event) {
119     *         if (&quot;headerValue&quot;.equals(event.getPropertyName())) {
120     *             TableColumn column = (TableColumn) event.getSource();
121     *             if ((column instanceof TableColumnExt)
122     *                     &amp;&amp; !((TableColumnExt) column).isVisible()) {
123     *                 return;
124     *             }
125     *             resizeAndRepaint();
126     *         }
127     *     }
128     * 
129     *     public void columnAdded(TableColumnModelEvent e) {
130     *     }
131     * 
132     *     public void columnMarginChanged(ChangeEvent e) {
133     *     }
134     * 
135     *     public void columnMoved(TableColumnModelEvent e) {
136     *     }
137     * 
138     *     public void columnRemoved(TableColumnModelEvent e) {
139     *     }
140     * 
141     *     public void columnSelectionChanged(ListSelectionEvent e) {
142     *     }
143     * 
144     * };
145     * columnModel.addColumnModelListener(l);
146     * </code></pre>
147     * 
148     * 
149     * @author Richard Bair
150     * @author Jeanette Winzenburg
151     * 
152     * @see DefaultTableColumnModelExt
153     * @see TableColumnExt
154     * @see TableColumnModelExtListener
155     * @see ColumnControlButton
156     * @see JXTable#setColumnControlVisible
157     * @see ColumnFactory
158     * 
159     */
160    public interface TableColumnModelExt extends TableColumnModel {
161        
162        /**
163         * Returns the number of contained columns. The count includes or excludes invisible
164         * columns, depending on whether the <code>includeHidden</code> is true or
165         * false, respectively. If false, this method returns the same count as
166         * <code>getColumnCount()</code>.
167         * 
168         * @param includeHidden a boolean to indicate whether invisible columns
169         *        should be included
170         * @return the number of contained columns, including or excluding the
171         *         invisible as specified.
172         */
173        public int getColumnCount(boolean includeHidden);
174    
175        /**
176         * Returns a <code>List</code> of contained <code>TableColumn</code>s.
177         * Includes or excludes invisible columns, depending on whether the
178         * <code>includeHidden</code> is true or false, respectively. If false, an
179         * <code>Iterator</code> over the List is equivalent to the
180         * <code>Enumeration</code> returned by <code>getColumns()</code>.
181         * <p>
182         * 
183         * NOTE: the order of columns in the List depends on whether or not the
184         * invisible columns are included, in the former case it's the insertion
185         * order in the latter it's the current order of the visible columns.
186         * 
187         * @param includeHidden a boolean to indicate whether invisible columns
188         *        should be included
189         * @return a <code>List</code> of contained columns.
190         */
191        public List<TableColumn> getColumns(boolean includeHidden);
192    
193        /**
194         * Returns the first <code>TableColumnExt</code> with the given
195         * <code>identifier</code>. The return value is null if there is no contained
196         * column with <b>identifier</b> or if the column with <code>identifier</code> is not 
197         * of type <code>TableColumnExt</code>. The returned column
198         * may be visible or hidden.
199         * 
200         * @param identifier the object used as column identifier
201         * @return first <code>TableColumnExt</code> with the given identifier or
202         *         null if none is found
203         */
204        public TableColumnExt getColumnExt(Object identifier);
205    
206        /**
207         * Returns the <code>TableColumnExt</code> at view position 
208         * <code>columnIndex</code>. The return value is null, if the
209         * column at position <code>columnIndex</code> is not of type
210         * <code>TableColumnExt</code>.
211         * The returned column is visible.
212         * 
213         * @param columnIndex the index of the column desired
214         * @return the <code>TableColumnExt</code> object that matches the column
215         *         index
216         * @throws ArrayIndexOutOfBoundsException if columnIndex out of allowed
217         *         range, that is if
218         *         <code> (columnIndex < 0) || (columnIndex >= getColumnCount())</code>.
219         */
220        public TableColumnExt getColumnExt(int columnIndex);
221        
222        /**
223         * Adds a listener for table column model events. This enhances super's 
224         * behaviour in that it guarantees to notify listeners of type 
225         * TableColumnModelListenerExt about property changes of contained columns.
226         *  
227         * @param x  a <code>TableColumnModelListener</code> object
228         */
229        public void addColumnModelListener(TableColumnModelListener x);
230    
231        
232    }