View Javadoc
1 /*
2 * Copyright (c) 2003 Scott Howlett & Paul Libbrecht.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. The end-user documentation included with the redistribution,
18 * if any, must include the following acknowledgment:
19 * "This product includes software developed by the Xwing
20 * Project ( http://xwing.sourceforge.net/ )."
21 * Alternately, this acknowledgment may appear in the software itself,
22 * if and wherever such third-party acknowledgments normally appear.
23 *
24 * 4. The name "Xwing" must not be used to endorse or promote products
25 * derived from this software without prior written permission. For
26 * written permission, please contact the project authors via
27 * the Xwing project site, http://xwing.sourceforge.net/ .
28 *
29 * 5. Products derived from this software may not be called "Xwing",
30 * nor may "Xwing" appear in their name, without prior written
31 * permission of the Xwing project.
32 *
33 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
34 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
35 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
36 * DISCLAIMED. IN NO EVENT SHALL THE XWING AUTHORS OR THE PROJECT
37 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
38 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
39 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
40 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
41 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
42 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
43 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44 * SUCH DAMAGE.
45 *
46 * For more information on Xwing, please see
47 * < http://xwing.sourceforge.net/ >.
48 */
49
50 package net.sourceforge.xwing.swing;
51
52 import java.util.Vector;
53
54 import javax.swing.ListModel;
55 import javax.swing.event.ChangeEvent;
56 import javax.swing.event.ChangeListener;
57 import javax.swing.event.ListDataEvent;
58 import javax.swing.event.ListDataListener;
59 import javax.swing.table.AbstractTableModel;
60
61 import net.sourceforge.xwing.SourceSink;
62
63 import org.apache.commons.logging.LogFactory;
64
65 public class XTableModel extends AbstractTableModel {
66
67 private ListModel rowContextList;
68 private ListModel columns;
69
70 private ListDataListener columnListener;
71
72 private Vector data;
73
74 class Row implements ChangeListener {
75 private Vector cells;
76
77 public Row(Vector cells) {
78 this.cells = cells;
79 }
80
81 public Vector getCells() {
82 return cells;
83 }
84
85 public void stateChanged(ChangeEvent e) {
86 int rowIndex = data.indexOf(this);
87 int colIndex = cells.indexOf(e.getSource());
88 fireTableCellUpdated(rowIndex, colIndex);
89 }
90 }
91
92 public XTableModel(ListModel pRows, ListModel pCols) throws Exception {
93 rowContextList = pRows;
94 columns = pCols;
95
96 int rc = getRowCount();
97 data = new Vector(rc);
98
99 for (int rowIndex = 0; rowIndex < rc; ++rowIndex) {
100 data.add(createRow(getRowContext(rowIndex)));
101 }
102
103 rowContextList.addListDataListener(new ListDataListener() {
104 public void contentsChanged(ListDataEvent e) {
105 try {
106 data.clear();
107 int numRows = getRowCount();
108
109 for (int rowIndex = 0; rowIndex < numRows; ++rowIndex) {
110 Row row = createRow(getRowContext(rowIndex));
111 data.add(rowIndex, row);
112 }
113 fireTableDataChanged();
114 } catch (Exception exc) {
115 exc.printStackTrace();
116 }
117 }
118
119 public void intervalAdded(ListDataEvent e) {
120 try {
121 int start = e.getIndex0();
122 int finish = e.getIndex1();
123
124 for (int rowIndex = start;
125 rowIndex <= finish;
126 ++rowIndex) {
127 Row row = createRow(getRowContext(rowIndex));
128 data.add(rowIndex, row);
129 }
130 fireTableRowsInserted(start, finish);
131 } catch (Exception exc) {
132 exc.printStackTrace();
133 }
134 }
135
136 public void intervalRemoved(ListDataEvent e) {
137 int start = e.getIndex0();
138 int finish = e.getIndex1();
139 for (int i = finish; i >= start; --i) {
140 Row row = (Row) data.remove(i);
141 }
142 fireTableRowsDeleted(start, finish);
143 }
144 });
145
146 columns.addListDataListener(new ListDataListener() {
147 public void contentsChanged(ListDataEvent e) {
148 try {
149 data.clear();
150 int numRows = getRowCount();
151
152 for (int rowIndex = 0; rowIndex < numRows; ++rowIndex) {
153 Row row = createRow(getRowContext(rowIndex));
154 data.add(rowIndex, row);
155 }
156 fireTableStructureChanged();
157 } catch (Exception exc) {
158 exc.printStackTrace();
159 }
160 }
161
162 public void intervalAdded(ListDataEvent e) {
163 try {
164 int start = e.getIndex0();
165 int finish = e.getIndex1();
166
167 int numRows = getRowCount();
168 for (int rowIndex = 0; rowIndex < numRows; ++rowIndex) {
169 Object context = getRowContext(rowIndex);
170 Row row = getRow(rowIndex);
171 Vector rd = row.getCells();
172 for (int colIndex = start;
173 colIndex <= finish;
174 ++colIndex) {
175 XTableColumn col = getColumn(colIndex);
176 Object val = col.getValue(context);
177 rd.add(colIndex, val);
178 }
179 }
180 fireTableStructureChanged();
181 } catch (Exception exc) {
182 exc.printStackTrace();
183 }
184 }
185
186 public void intervalRemoved(ListDataEvent e) {
187 int start = e.getIndex0();
188 int finish = e.getIndex1();
189
190 int numRows = data.size();
191 for (int rowIndex = 0; rowIndex < numRows; ++rowIndex) {
192 Row row = getRow(rowIndex);
193 Vector cells = row.getCells();
194 for (int i = finish; i >= start; --i) {
195 SourceSink ss = (SourceSink) cells.remove(i);
196 ss.removeChangeListener(row);
197 }
198 }
199 fireTableStructureChanged();
200 }
201 });
202 }
203
204 public int getColumnCount() {
205 return columns.getSize();
206 }
207
208 public int getRowCount() {
209 return rowContextList.getSize();
210 }
211
212 public Object getValueAt(int rowIndex, int columnIndex) {
213 try {
214 return getCell(rowIndex, columnIndex).get();
215 } catch (Exception e) {
216 e.printStackTrace();
217 return null;
218 }
219 }
220
221 public Class getColumnClass(int columnIndex) {
222 return getColumn(columnIndex).getColumnClass();
223 }
224
225 public boolean isCellEditable(int rowIndex, int columnIndex) {
226 return getColumn(columnIndex).isEditable();
227 }
228
229 public Object getRowContext(int index) {
230 return rowContextList.getElementAt(index);
231 }
232
233 public XTableColumn getColumn(int index) {
234 return (XTableColumn) columns.getElementAt(index);
235 }
236
237 public String getColumnName(int column) {
238 try {
239 return getColumn(column).getLabel();
240 } catch (Exception exc) {
241 LogFactory.getLog(getClass()).error("Error in getColumnName", exc);
242 return "";
243 }
244 }
245
246 private Row getRow(int rowIndex) {
247 return (Row) data.get(rowIndex);
248 }
249
250 private Row createRow(Object context) throws Exception {
251 int cc = getColumnCount();
252 Vector rowData = new Vector(cc);
253 Row row = new Row(rowData);
254 for (int c = 0; c < cc; ++c) {
255 SourceSink value = getColumn(c).getValue(context);
256 value.addChangeListener(row);
257 rowData.add(value);
258 }
259 return row;
260 }
261
262 private void destroyRow(Row row) {
263 int cc = getColumnCount();
264 Vector rowData = row.getCells();
265 for (int c = 0; c < cc; ++c) {
266 SourceSink value = (SourceSink) rowData.elementAt(c);
267 value.removeChangeListener(row);
268 }
269 rowData.clear();
270 }
271
272 public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
273 try {
274 getCell(rowIndex, columnIndex).set(aValue);
275 } catch (Exception exc) {
276 exc.printStackTrace();
277 }
278 }
279
280 private SourceSink getCell(int rowIndex, int columnIndex) {
281 return (SourceSink) getRow(rowIndex).getCells().get(columnIndex);
282 }
283 }
This page was automatically generated by Maven