001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /**
019: * @author Anton Avtamonov
020: * @version $Revision$
021: */package javax.swing.table;
022:
023: import java.beans.PropertyChangeEvent;
024: import java.beans.PropertyChangeListener;
025: import java.io.Serializable;
026: import java.util.Collections;
027: import java.util.Enumeration;
028: import java.util.EventListener;
029: import java.util.Vector;
030:
031: import javax.swing.DefaultListSelectionModel;
032: import javax.swing.ListSelectionModel;
033: import javax.swing.event.ChangeEvent;
034: import javax.swing.event.EventListenerList;
035: import javax.swing.event.ListSelectionEvent;
036: import javax.swing.event.ListSelectionListener;
037: import javax.swing.event.TableColumnModelEvent;
038: import javax.swing.event.TableColumnModelListener;
039:
040: import org.apache.harmony.x.swing.internal.nls.Messages;
041:
042: public class DefaultTableColumnModel implements TableColumnModel,
043: PropertyChangeListener, ListSelectionListener, Serializable {
044: protected Vector<TableColumn> tableColumns = new Vector<TableColumn>();
045: protected ListSelectionModel selectionModel;
046: protected int columnMargin = 1;
047: protected EventListenerList listenerList = new EventListenerList();
048: protected transient ChangeEvent changeEvent;
049: protected boolean columnSelectionAllowed;
050: protected int totalColumnWidth = -1;
051:
052: public DefaultTableColumnModel() {
053: selectionModel = createSelectionModel();
054: selectionModel.addListSelectionListener(this );
055: alignSelectionModelToColumns();
056: }
057:
058: public void addColumn(final TableColumn column) {
059: if (column == null) {
060: throw new IllegalArgumentException(Messages
061: .getString("swing.78")); //$NON-NLS-1$
062: }
063: tableColumns.add(column);
064: totalColumnWidth = -1;
065: column.addPropertyChangeListener(this );
066: alignSelectionModelToColumns();
067: fireColumnAdded(new TableColumnModelEvent(this , tableColumns
068: .size() - 2 >= 0 ? tableColumns.size() - 2
069: : tableColumns.size() - 1, tableColumns.size() - 1));
070: }
071:
072: public void removeColumn(final TableColumn column) {
073: int index = tableColumns.indexOf(column);
074: if (tableColumns.remove(column)) {
075: totalColumnWidth = -1;
076: column.removePropertyChangeListener(this );
077: }
078: alignSelectionModelToColumns();
079: fireColumnRemoved(new TableColumnModelEvent(this , index, index));
080: }
081:
082: public void moveColumn(final int columnIndex, final int newIndex) {
083: if (columnIndex < 0 || columnIndex >= getColumnCount()
084: || newIndex < 0 || newIndex > getColumnCount()) {
085:
086: throw new IllegalArgumentException(Messages
087: .getString("swing.79")); //$NON-NLS-1$
088: }
089:
090: if (columnIndex != newIndex) {
091: TableColumn firstColumn = getColumn(columnIndex);
092: tableColumns.remove(columnIndex);
093: tableColumns.add(newIndex, firstColumn);
094:
095: boolean oldIsSelected = selectionModel
096: .isSelectedIndex(columnIndex);
097: selectionModel
098: .removeIndexInterval(columnIndex, columnIndex);
099: selectionModel.insertIndexInterval(newIndex, 1, true);
100: if (oldIsSelected) {
101: selectionModel.addSelectionInterval(newIndex, newIndex);
102: } else {
103: selectionModel.removeSelectionInterval(newIndex,
104: newIndex);
105: }
106: }
107:
108: fireColumnMoved(new TableColumnModelEvent(this , columnIndex,
109: newIndex));
110: }
111:
112: public void setColumnMargin(final int margin) {
113: if (columnMargin != margin) {
114: columnMargin = margin;
115: fireColumnMarginChanged();
116: }
117: }
118:
119: public int getColumnMargin() {
120: return columnMargin;
121: }
122:
123: public int getColumnCount() {
124: return tableColumns.size();
125: }
126:
127: public Enumeration<TableColumn> getColumns() {
128: return Collections.enumeration(tableColumns);
129: }
130:
131: public int getColumnIndex(final Object identifier) {
132: if (identifier == null) {
133: throw new IllegalArgumentException(Messages
134: .getString("swing.7A")); //$NON-NLS-1$
135: }
136:
137: for (int i = 0; i < getColumnCount(); i++) {
138: TableColumn next = getColumn(i);
139: if (identifier.equals(next.getIdentifier())) {
140: return i;
141: }
142: }
143:
144: throw new IllegalArgumentException(Messages
145: .getString("swing.7B")); //$NON-NLS-1$
146: }
147:
148: public TableColumn getColumn(final int columnIndex) {
149: return (TableColumn) tableColumns.get(columnIndex);
150: }
151:
152: public int getColumnIndexAtX(final int x) {
153: int cumulativeWidth = 0;
154: for (int i = 0; i < getColumnCount(); i++) {
155: int width = getColumn(i).width;
156: if (cumulativeWidth <= x && cumulativeWidth + width > x) {
157: return i;
158: }
159: cumulativeWidth += width;
160: }
161:
162: return -1;
163: }
164:
165: public int getTotalColumnWidth() {
166: if (totalColumnWidth == -1) {
167: recalcWidthCache();
168: }
169:
170: return totalColumnWidth;
171: }
172:
173: public void setSelectionModel(final ListSelectionModel model) {
174: if (model == null) {
175: throw new IllegalArgumentException(Messages
176: .getString("swing.7C")); //$NON-NLS-1$
177: }
178: selectionModel.removeListSelectionListener(this );
179:
180: selectionModel = model;
181: selectionModel.addListSelectionListener(this );
182: alignSelectionModelToColumns();
183: }
184:
185: public ListSelectionModel getSelectionModel() {
186: return selectionModel;
187: }
188:
189: public void setColumnSelectionAllowed(final boolean allowed) {
190: columnSelectionAllowed = allowed;
191: }
192:
193: public boolean getColumnSelectionAllowed() {
194: return columnSelectionAllowed;
195: }
196:
197: public int[] getSelectedColumns() {
198: int[] result = new int[getSelectedColumnCount()];
199: int index = 0;
200: for (int i = 0; i < getColumnCount(); i++) {
201: if (selectionModel.isSelectedIndex(i)) {
202: result[index++] = i;
203: }
204: }
205:
206: return result;
207: }
208:
209: public int getSelectedColumnCount() {
210: if (selectionModel.isSelectionEmpty()) {
211: return 0;
212: }
213:
214: int result = 0;
215: for (int i = 0; i < getColumnCount(); i++) {
216: if (selectionModel.isSelectedIndex(i)) {
217: result++;
218: }
219: }
220:
221: return result;
222: }
223:
224: public void addColumnModelListener(
225: final TableColumnModelListener listener) {
226: listenerList.add(TableColumnModelListener.class, listener);
227: }
228:
229: public void removeColumnModelListener(
230: final TableColumnModelListener listener) {
231: listenerList.remove(TableColumnModelListener.class, listener);
232: }
233:
234: public TableColumnModelListener[] getColumnModelListeners() {
235: return (TableColumnModelListener[]) listenerList
236: .getListeners(TableColumnModelListener.class);
237: }
238:
239: public <T extends EventListener> T[] getListeners(
240: final Class<T> listenerType) {
241: return listenerList.getListeners(listenerType);
242: }
243:
244: public void propertyChange(final PropertyChangeEvent e) {
245: if (TableColumn.WIDTH_PROPERTY.equals(e.getPropertyName())
246: || TableColumn.PREFERRED_WIDTH_PROPERTY.equals(e
247: .getPropertyName())) {
248:
249: totalColumnWidth = -1;
250: fireColumnMarginChanged();
251: }
252: }
253:
254: public void valueChanged(final ListSelectionEvent e) {
255: fireColumnSelectionChanged(e);
256: }
257:
258: protected void fireColumnAdded(final TableColumnModelEvent e) {
259: TableColumnModelListener[] listeners = getColumnModelListeners();
260: for (int i = 0; i < listeners.length; i++) {
261: listeners[i].columnAdded(e);
262: }
263: }
264:
265: protected void fireColumnRemoved(final TableColumnModelEvent e) {
266: TableColumnModelListener[] listeners = getColumnModelListeners();
267: for (int i = 0; i < listeners.length; i++) {
268: listeners[i].columnRemoved(e);
269: }
270: }
271:
272: protected void fireColumnMoved(final TableColumnModelEvent e) {
273: TableColumnModelListener[] listeners = getColumnModelListeners();
274: for (int i = 0; i < listeners.length; i++) {
275: listeners[i].columnMoved(e);
276: }
277: }
278:
279: protected void fireColumnSelectionChanged(final ListSelectionEvent e) {
280: TableColumnModelListener[] listeners = getColumnModelListeners();
281: for (int i = 0; i < listeners.length; i++) {
282: listeners[i].columnSelectionChanged(e);
283: }
284: }
285:
286: protected void fireColumnMarginChanged() {
287: TableColumnModelListener[] listeners = getColumnModelListeners();
288: for (int i = 0; i < listeners.length; i++) {
289: listeners[i].columnMarginChanged(getChangeEvent());
290: }
291: }
292:
293: protected ListSelectionModel createSelectionModel() {
294: return new DefaultListSelectionModel();
295: }
296:
297: protected void recalcWidthCache() {
298: if (getColumnCount() == 0) {
299: totalColumnWidth = -1;
300: }
301: totalColumnWidth = 0;
302: for (int i = 0; i < getColumnCount(); i++) {
303: totalColumnWidth += getColumn(i).width;
304: }
305: }
306:
307: private ChangeEvent getChangeEvent() {
308: if (changeEvent == null) {
309: changeEvent = new ChangeEvent(this );
310: }
311:
312: return changeEvent;
313: }
314:
315: private void alignSelectionModelToColumns() {
316: if (getColumnCount() == 0) {
317: if (selectionModel.getAnchorSelectionIndex() >= 0) {
318: selectionModel.setValueIsAdjusting(true);
319: selectionModel.setAnchorSelectionIndex(-1);
320: selectionModel.setLeadSelectionIndex(-1);
321: selectionModel.setValueIsAdjusting(false);
322: }
323: } else if (selectionModel.getLeadSelectionIndex() < 0) {
324: selectionModel.removeSelectionInterval(0, 0);
325: }
326: }
327: }
|