History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/javax/swing/table/DefaultTableColumnModel.java (1 of 18352 files). Show all

Unified · Split

java/pkg/javax/swing/table/DefaultTableColumnModel.java+739−0
@@ -0,0 +1,739 @@
1+/*
2+ * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package javax.swing.table;
27+
28+import javax.swing.*;
29+import javax.swing.event.*;
30+import java.awt.*;
31+import java.util.Vector;
32+import java.util.Enumeration;
33+import java.util.EventListener;
34+import java.beans.PropertyChangeListener;
35+import java.beans.PropertyChangeEvent;
36+import java.io.Serializable;
37+import sun.swing.SwingUtilities2;
38+
39+/**
40+ * The standard column-handler for a <code>JTable</code>.
41+ * <p>
42+ * <strong>Warning:</strong>
43+ * Serialized objects of this class will not be compatible with
44+ * future Swing releases. The current serialization support is
45+ * appropriate for short term storage or RMI between applications running
46+ * the same version of Swing. As of 1.4, support for long term storage
47+ * of all JavaBeans<sup><font size="-2">TM</font></sup>
48+ * has been added to the <code>java.beans</code> package.
49+ * Please see {@link java.beans.XMLEncoder}.
50+ *
51+ * @author Alan Chung
52+ * @author Philip Milne
53+ * @see JTable
54+ */
55+public class DefaultTableColumnModel implements TableColumnModel,
56+ PropertyChangeListener, ListSelectionListener, Serializable
57+{
58+//
59+// Instance Variables
60+//
61+
62+ /** Array of TableColumn objects in this model */
63+ protected Vector<TableColumn> tableColumns;
64+
65+ /** Model for keeping track of column selections */
66+ protected ListSelectionModel selectionModel;
67+
68+ /** Width margin between each column */
69+ protected int columnMargin;
70+
71+ /** List of TableColumnModelListener */
72+ protected EventListenerList listenerList = new EventListenerList();
73+
74+ /** Change event (only one needed) */
75+ transient protected ChangeEvent changeEvent = null;
76+
77+ /** Column selection allowed in this column model */
78+ protected boolean columnSelectionAllowed;
79+
80+ /** A local cache of the combined width of all columns */
81+ protected int totalColumnWidth;
82+
83+//
84+// Constructors
85+//
86+ /**
87+ * Creates a default table column model.
88+ */
89+ public DefaultTableColumnModel() {
90+ super();
91+
92+ // Initialize local ivars to default
93+ tableColumns = new Vector<TableColumn>();
94+ setSelectionModel(createSelectionModel());
95+ setColumnMargin(1);
96+ invalidateWidthCache();
97+ setColumnSelectionAllowed(false);
98+ }
99+
100+//
101+// Modifying the model
102+//
103+
104+ /**
105+ * Appends <code>aColumn</code> to the end of the
106+ * <code>tableColumns</code> array.
107+ * This method also posts the <code>columnAdded</code>
108+ * event to its listeners.
109+ *
110+ * @param aColumn the <code>TableColumn</code> to be added
111+ * @exception IllegalArgumentException if <code>aColumn</code> is
112+ * <code>null</code>
113+ * @see #removeColumn
114+ */
115+ public void addColumn(TableColumn aColumn) {
116+ if (aColumn == null) {
117+ throw new IllegalArgumentException("Object is null");
118+ }
119+
120+ tableColumns.addElement(aColumn);
121+ aColumn.addPropertyChangeListener(this);
122+ invalidateWidthCache();
123+
124+ // Post columnAdded event notification
125+ fireColumnAdded(new TableColumnModelEvent(this, 0,
126+ getColumnCount() - 1));
127+ }
128+
129+ /**
130+ * Deletes the <code>column</code> from the
131+ * <code>tableColumns</code> array. This method will do nothing if
132+ * <code>column</code> is not in the table's columns list.
133+ * <code>tile</code> is called
134+ * to resize both the header and table views.
135+ * This method also posts a <code>columnRemoved</code>
136+ * event to its listeners.
137+ *
138+ * @param column the <code>TableColumn</code> to be removed
139+ * @see #addColumn
140+ */
141+ public void removeColumn(TableColumn column) {
142+ int columnIndex = tableColumns.indexOf(column);
143+
144+ if (columnIndex != -1) {
145+ // Adjust for the selection
146+ if (selectionModel != null) {
147+ selectionModel.removeIndexInterval(columnIndex,columnIndex);
148+ }
149+
150+ column.removePropertyChangeListener(this);
151+ tableColumns.removeElementAt(columnIndex);
152+ invalidateWidthCache();
153+
154+ // Post columnAdded event notification. (JTable and JTableHeader
155+ // listens so they can adjust size and redraw)
156+ fireColumnRemoved(new TableColumnModelEvent(this,
157+ columnIndex, 0));
158+ }
159+ }
160+
161+ /**
162+ * Moves the column and heading at <code>columnIndex</code> to
163+ * <code>newIndex</code>. The old column at <code>columnIndex</code>
164+ * will now be found at <code>newIndex</code>. The column
165+ * that used to be at <code>newIndex</code> is shifted
166+ * left or right to make room. This will not move any columns if
167+ * <code>columnIndex</code> equals <code>newIndex</code>. This method
168+ * also posts a <code>columnMoved</code> event to its listeners.
169+ *
170+ * @param columnIndex the index of column to be moved
171+ * @param newIndex new index to move the column
172+ * @exception IllegalArgumentException if <code>column</code> or
173+ * <code>newIndex</code>
174+ * are not in the valid range
175+ */
176+ public void moveColumn(int columnIndex, int newIndex) {
177+ if ((columnIndex < 0) || (columnIndex >= getColumnCount()) ||
178+ (newIndex < 0) || (newIndex >= getColumnCount()))
179+ throw new IllegalArgumentException("moveColumn() - Index out of range");
180+
181+ TableColumn aColumn;
182+
183+ // If the column has not yet moved far enough to change positions
184+ // post the event anyway, the "draggedDistance" property of the
185+ // tableHeader will say how far the column has been dragged.
186+ // Here we are really trying to get the best out of an
187+ // API that could do with some rethinking. We preserve backward
188+ // compatibility by slightly bending the meaning of these methods.
189+ if (columnIndex == newIndex) {
190+ fireColumnMoved(new TableColumnModelEvent(this, columnIndex, newIndex));
191+ return;
192+ }
193+ aColumn = tableColumns.elementAt(columnIndex);
194+
195+ tableColumns.removeElementAt(columnIndex);
196+ boolean selected = selectionModel.isSelectedIndex(columnIndex);
197+ selectionModel.removeIndexInterval(columnIndex,columnIndex);
198+
199+ tableColumns.insertElementAt(aColumn, newIndex);
200+ selectionModel.insertIndexInterval(newIndex, 1, true);
201+ if (selected) {
202+ selectionModel.addSelectionInterval(newIndex, newIndex);
203+ }
204+ else {
205+ selectionModel.removeSelectionInterval(newIndex, newIndex);
206+ }
207+
208+ fireColumnMoved(new TableColumnModelEvent(this, columnIndex,
209+ newIndex));
210+ }
211+
212+ /**
213+ * Sets the column margin to <code>newMargin</code>. This method
214+ * also posts a <code>columnMarginChanged</code> event to its
215+ * listeners.
216+ *
217+ * @param newMargin the new margin width, in pixels
218+ * @see #getColumnMargin
219+ * @see #getTotalColumnWidth
220+ */
221+ public void setColumnMargin(int newMargin) {
222+ if (newMargin != columnMargin) {
223+ columnMargin = newMargin;
224+ // Post columnMarginChanged event notification.
225+ fireColumnMarginChanged();
226+ }
227+ }
228+
229+//
230+// Querying the model
231+//
232+
233+ /**
234+ * Returns the number of columns in the <code>tableColumns</code> array.
235+ *
236+ * @return the number of columns in the <code>tableColumns</code> array
237+ * @see #getColumns
238+ */
239+ public int getColumnCount() {
240+ return tableColumns.size();
241+ }
242+
243+ /**
244+ * Returns an <code>Enumeration</code> of all the columns in the model.
245+ * @return an <code>Enumeration</code> of the columns in the model
246+ */
247+ public Enumeration<TableColumn> getColumns() {
248+ return tableColumns.elements();
249+ }
250+
251+ /**
252+ * Returns the index of the first column in the <code>tableColumns</code>
253+ * array whose identifier is equal to <code>identifier</code>,
254+ * when compared using <code>equals</code>.
255+ *
256+ * @param identifier the identifier object
257+ * @return the index of the first column in the
258+ * <code>tableColumns</code> array whose identifier
259+ * is equal to <code>identifier</code>
260+ * @exception IllegalArgumentException if <code>identifier</code>
261+ * is <code>null</code>, or if no
262+ * <code>TableColumn</code> has this
263+ * <code>identifier</code>
264+ * @see #getColumn
265+ */
266+ public int getColumnIndex(Object identifier) {
267+ if (identifier == null) {
268+ throw new IllegalArgumentException("Identifier is null");
269+ }
270+
271+ Enumeration enumeration = getColumns();
272+ TableColumn aColumn;
273+ int index = 0;
274+
275+ while (enumeration.hasMoreElements()) {
276+ aColumn = (TableColumn)enumeration.nextElement();
277+ // Compare them this way in case the column's identifier is null.
278+ if (identifier.equals(aColumn.getIdentifier()))
279+ return index;
280+ index++;
281+ }
282+ throw new IllegalArgumentException("Identifier not found");
283+ }
284+
285+ /**
286+ * Returns the <code>TableColumn</code> object for the column
287+ * at <code>columnIndex</code>.
288+ *
289+ * @param columnIndex the index of the column desired
290+ * @return the <code>TableColumn</code> object for the column
291+ * at <code>columnIndex</code>
292+ */
293+ public TableColumn getColumn(int columnIndex) {
294+ return tableColumns.elementAt(columnIndex);
295+ }
296+
297+ /**
298+ * Returns the width margin for <code>TableColumn</code>.
299+ * The default <code>columnMargin</code> is 1.
300+ *
301+ * @return the maximum width for the <code>TableColumn</code>
302+ * @see #setColumnMargin
303+ */
304+ public int getColumnMargin() {
305+ return columnMargin;
306+ }
307+
308+ /**
309+ * Returns the index of the column that lies at position <code>x</code>,
310+ * or -1 if no column covers this point.
311+ *
312+ * In keeping with Swing's separable model architecture, a
313+ * TableColumnModel does not know how the table columns actually appear on
314+ * screen. The visual presentation of the columns is the responsibility
315+ * of the view/controller object using this model (typically JTable). The
316+ * view/controller need not display the columns sequentially from left to
317+ * right. For example, columns could be displayed from right to left to
318+ * accomodate a locale preference or some columns might be hidden at the
319+ * request of the user. Because the model does not know how the columns
320+ * are laid out on screen, the given <code>xPosition</code> should not be
321+ * considered to be a coordinate in 2D graphics space. Instead, it should
322+ * be considered to be a width from the start of the first column in the
323+ * model. If the column index for a given X coordinate in 2D space is
324+ * required, <code>JTable.columnAtPoint</code> can be used instead.
325+ *
326+ * @param x the horizontal location of interest
327+ * @return the index of the column or -1 if no column is found
328+ * @see javax.swing.JTable#columnAtPoint
329+ */
330+ public int getColumnIndexAtX(int x) {
331+ if (x < 0) {
332+ return -1;
333+ }
334+ int cc = getColumnCount();
335+ for(int column = 0; column < cc; column++) {
336+ x = x - getColumn(column).getWidth();
337+ if (x < 0) {
338+ return column;
339+ }
340+ }
341+ return -1;
342+ }
343+
344+ /**
345+ * Returns the total combined width of all columns.
346+ * @return the <code>totalColumnWidth</code> property
347+ */
348+ public int getTotalColumnWidth() {
349+ if (totalColumnWidth == -1) {
350+ recalcWidthCache();
351+ }
352+ return totalColumnWidth;
353+ }
354+
355+//
356+// Selection model
357+//
358+
359+ /**
360+ * Sets the selection model for this <code>TableColumnModel</code>
361+ * to <code>newModel</code>
362+ * and registers for listener notifications from the new selection
363+ * model. If <code>newModel</code> is <code>null</code>,
364+ * an exception is thrown.
365+ *
366+ * @param newModel the new selection model
367+ * @exception IllegalArgumentException if <code>newModel</code>
368+ * is <code>null</code>
369+ * @see #getSelectionModel
370+ */
371+ public void setSelectionModel(ListSelectionModel newModel) {
372+ if (newModel == null) {
373+ throw new IllegalArgumentException("Cannot set a null SelectionModel");
374+ }
375+
376+ ListSelectionModel oldModel = selectionModel;
377+
378+ if (newModel != oldModel) {
379+ if (oldModel != null) {
380+ oldModel.removeListSelectionListener(this);
381+ }
382+
383+ selectionModel= newModel;
384+ newModel.addListSelectionListener(this);
385+ }
386+ }
387+
388+ /**
389+ * Returns the <code>ListSelectionModel</code> that is used to
390+ * maintain column selection state.
391+ *
392+ * @return the object that provides column selection state. Or
393+ * <code>null</code> if row selection is not allowed.
394+ * @see #setSelectionModel
395+ */
396+ public ListSelectionModel getSelectionModel() {
397+ return selectionModel;
398+ }
399+
400+ // implements javax.swing.table.TableColumnModel
401+ /**
402+ * Sets whether column selection is allowed. The default is false.
403+ * @param flag true if column selection will be allowed, false otherwise
404+ */
405+ public void setColumnSelectionAllowed(boolean flag) {
406+ columnSelectionAllowed = flag;
407+ }
408+
409+ // implements javax.swing.table.TableColumnModel
410+ /**
411+ * Returns true if column selection is allowed, otherwise false.
412+ * The default is false.
413+ * @return the <code>columnSelectionAllowed</code> property
414+ */
415+ public boolean getColumnSelectionAllowed() {
416+ return columnSelectionAllowed;
417+ }
418+
419+ // implements javax.swing.table.TableColumnModel
420+ /**
421+ * Returns an array of selected columns. If <code>selectionModel</code>
422+ * is <code>null</code>, returns an empty array.
423+ * @return an array of selected columns or an empty array if nothing
424+ * is selected or the <code>selectionModel</code> is
425+ * <code>null</code>
426+ */
427+ public int[] getSelectedColumns() {
428+ if (selectionModel != null) {
429+ int iMin = selectionModel.getMinSelectionIndex();
430+ int iMax = selectionModel.getMaxSelectionIndex();
431+
432+ if ((iMin == -1) || (iMax == -1)) {
433+ return new int[0];
434+ }
435+
436+ int[] rvTmp = new int[1+ (iMax - iMin)];
437+ int n = 0;
438+ for(int i = iMin; i <= iMax; i++) {
439+ if (selectionModel.isSelectedIndex(i)) {
440+ rvTmp[n++] = i;
441+ }
442+ }
443+ int[] rv = new int[n];
444+ System.arraycopy(rvTmp, 0, rv, 0, n);
445+ return rv;
446+ }
447+ return new int[0];
448+ }
449+
450+ // implements javax.swing.table.TableColumnModel
451+ /**
452+ * Returns the number of columns selected.
453+ * @return the number of columns selected
454+ */
455+ public int getSelectedColumnCount() {
456+ if (selectionModel != null) {
457+ int iMin = selectionModel.getMinSelectionIndex();
458+ int iMax = selectionModel.getMaxSelectionIndex();
459+ int count = 0;
460+
461+ for(int i = iMin; i <= iMax; i++) {
462+ if (selectionModel.isSelectedIndex(i)) {
463+ count++;
464+ }
465+ }
466+ return count;
467+ }
468+ return 0;
469+ }
470+
471+//
472+// Listener Support Methods
473+//
474+
475+ // implements javax.swing.table.TableColumnModel
476+ /**
477+ * Adds a listener for table column model events.
478+ * @param x a <code>TableColumnModelListener</code> object
479+ */
480+ public void addColumnModelListener(TableColumnModelListener x) {
481+ listenerList.add(TableColumnModelListener.class, x);
482+ }
483+
484+ // implements javax.swing.table.TableColumnModel
485+ /**
486+ * Removes a listener for table column model events.
487+ * @param x a <code>TableColumnModelListener</code> object
488+ */
489+ public void removeColumnModelListener(TableColumnModelListener x) {
490+ listenerList.remove(TableColumnModelListener.class, x);
491+ }
492+
493+ /**
494+ * Returns an array of all the column model listeners
495+ * registered on this model.
496+ *
497+ * @return all of this default table column model's <code>ColumnModelListener</code>s
498+ * or an empty
499+ * array if no column model listeners are currently registered
500+ *
501+ * @see #addColumnModelListener
502+ * @see #removeColumnModelListener
503+ *
504+ * @since 1.4
505+ */
506+ public TableColumnModelListener[] getColumnModelListeners() {
507+ return listenerList.getListeners(TableColumnModelListener.class);
508+ }
509+
510+//
511+// Event firing methods
512+//
513+
514+ /**
515+ * Notifies all listeners that have registered interest for
516+ * notification on this event type. The event instance
517+ * is lazily created using the parameters passed into
518+ * the fire method.
519+ * @param e the event received
520+ * @see EventListenerList
521+ */
522+ protected void fireColumnAdded(TableColumnModelEvent e) {
523+ // Guaranteed to return a non-null array
524+ Object[] listeners = listenerList.getListenerList();
525+ // Process the listeners last to first, notifying
526+ // those that are interested in this event
527+ for (int i = listeners.length-2; i>=0; i-=2) {
528+ if (listeners[i]==TableColumnModelListener.class) {
529+ // Lazily create the event:
530+ // if (e == null)
531+ // e = new ChangeEvent(this);
532+ ((TableColumnModelListener)listeners[i+1]).
533+ columnAdded(e);
534+ }
535+ }
536+ }
537+
538+ /**
539+ * Notifies all listeners that have registered interest for
540+ * notification on this event type. The event instance
541+ * is lazily created using the parameters passed into
542+ * the fire method.
543+ * @param e the event received
544+ * @see EventListenerList
545+ */
546+ protected void fireColumnRemoved(TableColumnModelEvent e) {
547+ // Guaranteed to return a non-null array
548+ Object[] listeners = listenerList.getListenerList();
549+ // Process the listeners last to first, notifying
550+ // those that are interested in this event
551+ for (int i = listeners.length-2; i>=0; i-=2) {
552+ if (listeners[i]==TableColumnModelListener.class) {
553+ // Lazily create the event:
554+ // if (e == null)
555+ // e = new ChangeEvent(this);
556+ ((TableColumnModelListener)listeners[i+1]).
557+ columnRemoved(e);
558+ }
559+ }
560+ }
561+
562+ /**
563+ * Notifies all listeners that have registered interest for
564+ * notification on this event type. The event instance
565+ * is lazily created using the parameters passed into
566+ * the fire method.
567+ * @param e the event received
568+ * @see EventListenerList
569+ */
570+ protected void fireColumnMoved(TableColumnModelEvent e) {
571+ // Guaranteed to return a non-null array
572+ Object[] listeners = listenerList.getListenerList();
573+ // Process the listeners last to first, notifying
574+ // those that are interested in this event
575+ for (int i = listeners.length-2; i>=0; i-=2) {
576+ if (listeners[i]==TableColumnModelListener.class) {
577+ // Lazily create the event:
578+ // if (e == null)
579+ // e = new ChangeEvent(this);
580+ ((TableColumnModelListener)listeners[i+1]).
581+ columnMoved(e);
582+ }
583+ }
584+ }
585+
586+ /**
587+ * Notifies all listeners that have registered interest for
588+ * notification on this event type. The event instance
589+ * is lazily created using the parameters passed into
590+ * the fire method.
591+ * @param e the event received
592+ * @see EventListenerList
593+ */
594+ protected void fireColumnSelectionChanged(ListSelectionEvent e) {
595+ // Guaranteed to return a non-null array
596+ Object[] listeners = listenerList.getListenerList();
597+ // Process the listeners last to first, notifying
598+ // those that are interested in this event
599+ for (int i = listeners.length-2; i>=0; i-=2) {
600+ if (listeners[i]==TableColumnModelListener.class) {
601+ // Lazily create the event:
602+ // if (e == null)
603+ // e = new ChangeEvent(this);
604+ ((TableColumnModelListener)listeners[i+1]).
605+ columnSelectionChanged(e);
606+ }
607+ }
608+ }
609+
610+ /**
611+ * Notifies all listeners that have registered interest for
612+ * notification on this event type. The event instance
613+ * is lazily created using the parameters passed into
614+ * the fire method.
615+ * @see EventListenerList
616+ */
617+ protected void fireColumnMarginChanged() {
618+ // Guaranteed to return a non-null array
619+ Object[] listeners = listenerList.getListenerList();
620+ // Process the listeners last to first, notifying
621+ // those that are interested in this event
622+ for (int i = listeners.length-2; i>=0; i-=2) {
623+ if (listeners[i]==TableColumnModelListener.class) {
624+ // Lazily create the event:
625+ if (changeEvent == null)
626+ changeEvent = new ChangeEvent(this);
627+ ((TableColumnModelListener)listeners[i+1]).
628+ columnMarginChanged(changeEvent);
629+ }
630+ }
631+ }
632+
633+ /**
634+ * Returns an array of all the objects currently registered
635+ * as <code><em>Foo</em>Listener</code>s
636+ * upon this model.
637+ * <code><em>Foo</em>Listener</code>s are registered using the
638+ * <code>add<em>Foo</em>Listener</code> method.
639+ *
640+ * <p>
641+ *
642+ * You can specify the <code>listenerType</code> argument
643+ * with a class literal,
644+ * such as
645+ * <code><em>Foo</em>Listener.class</code>.
646+ * For example, you can query a
647+ * <code>DefaultTableColumnModel</code> <code>m</code>
648+ * for its column model listeners with the following code:
649+ *
650+ * <pre>ColumnModelListener[] cmls = (ColumnModelListener[])(m.getListeners(ColumnModelListener.class));</pre>
651+ *
652+ * If no such listeners exist, this method returns an empty array.
653+ *
654+ * @param listenerType the type of listeners requested; this parameter
655+ * should specify an interface that descends from
656+ * <code>java.util.EventListener</code>
657+ * @return an array of all objects registered as
658+ * <code><em>Foo</em>Listener</code>s on this model,
659+ * or an empty array if no such
660+ * listeners have been added
661+ * @exception ClassCastException if <code>listenerType</code>
662+ * doesn't specify a class or interface that implements
663+ * <code>java.util.EventListener</code>
664+ *
665+ * @see #getColumnModelListeners
666+ * @since 1.3
667+ */
668+ public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
669+ return listenerList.getListeners(listenerType);
670+ }
671+
672+//
673+// Implementing the PropertyChangeListener interface
674+//
675+
676+ // PENDING(alan)
677+ // implements java.beans.PropertyChangeListener
678+ /**
679+ * Property Change Listener change method. Used to track changes
680+ * to the column width or preferred column width.
681+ *
682+ * @param evt <code>PropertyChangeEvent</code>
683+ */
684+ public void propertyChange(PropertyChangeEvent evt) {
685+ String name = evt.getPropertyName();
686+
687+ if (name == "width" || name == "preferredWidth") {
688+ invalidateWidthCache();
689+ // This is a misnomer, we're using this method
690+ // simply to cause a relayout.
691+ fireColumnMarginChanged();
692+ }
693+
694+ }
695+
696+//
697+// Implementing ListSelectionListener interface
698+//
699+
700+ // implements javax.swing.event.ListSelectionListener
701+ /**
702+ * A <code>ListSelectionListener</code> that forwards
703+ * <code>ListSelectionEvents</code> when there is a column
704+ * selection change.
705+ *
706+ * @param e the change event
707+ */
708+ public void valueChanged(ListSelectionEvent e) {
709+ fireColumnSelectionChanged(e);
710+ }
711+
712+//
713+// Protected Methods
714+//
715+
716+ /**
717+ * Creates a new default list selection model.
718+ */
719+ protected ListSelectionModel createSelectionModel() {
720+ return new DefaultListSelectionModel();
721+ }
722+
723+ /**
724+ * Recalculates the total combined width of all columns. Updates the
725+ * <code>totalColumnWidth</code> property.
726+ */
727+ protected void recalcWidthCache() {
728+ Enumeration enumeration = getColumns();
729+ totalColumnWidth = 0;
730+ while (enumeration.hasMoreElements()) {
731+ totalColumnWidth += ((TableColumn)enumeration.nextElement()).getWidth();
732+ }
733+ }
734+
735+ private void invalidateWidthCache() {
736+ totalColumnWidth = -1;
737+ }
738+
739+} // End of class DefaultTableColumnModel