1 /*
2 J-Bird net/sourceforge/jbird/swing/JRCTable.java
3
4 Copyright 2001, 2002, 2003 Dick Repasky
5 */
6 package net.sourceforge.jbird.swing;
7
8 import java.util.Enumeration;
9
10 import java.awt.Dimension;
11 import java.awt.Toolkit;
12
13 import java.awt.event.ComponentAdapter;
14 import java.awt.event.ComponentEvent;
15
16 import javax.swing.JScrollPane;
17 import javax.swing.JTable;
18 import javax.swing.JViewport;
19 import javax.swing.SwingConstants;
20
21 import javax.swing.table.DefaultTableColumnModel;
22 import javax.swing.table.JTableHeader;
23 import javax.swing.table.TableColumn;
24 import javax.swing.table.TableColumnModel;
25 import javax.swing.table.TableModel;
26
27 import net.sourceforge.jbird.iface.Nullify;
28
29 /**
30 * A JTable class that provides a reference column on the lefthand side.
31 * Inspired by Eckstein, Loy and Wood.
32 * The class is a subclass of JScrollPane and can be used as a
33 * JScrollPane would be used.
34 * Overridable methods are provided for customizing the JTables that
35 * are created from the TableModel passed to the constructor.
36 * @author Dick Repasky
37 * @since J-Bird 0.1.3
38 */
39
40 public class JRCTable extends JScrollPane implements Nullify {
41
42 /** Reference column. */
43 protected JTable ref_table;
44 /** Main body. */
45 protected JTable body_table;
46 /** JViewport for reference column. */
47 protected JViewport view_port;
48 /** TableColumnModel of main body. */
49 protected TableColumnModel bodycol_model;
50 /** TableColumnModel of reference column. */
51 protected TableColumnModel refcol_model;
52 /** TableColumn of reference column. */
53 protected TableColumn first_column;
54
55 public JRCTable(TableModel tablemodel) {
56 super();
57 bodycol_model = new DefaultTableColumnModel() {
58 boolean first = true;
59 public void addColumn(TableColumn column) {
60 if (first) {
61 first = false;
62 return;
63 }
64 super.addColumn(column);
65 }
66 };
67 refcol_model = new DefaultTableColumnModel() {
68 boolean first = true;
69 public void addColumn(TableColumn column) {
70 if (first) {
71 first = false;
72 super.addColumn(column);
73 first_column = column;
74 }
75 }
76 };
77 body_table = buildBodyTable(tablemodel, bodycol_model);
78 ref_table = buildRefColTable(tablemodel, refcol_model);
79 body_table.createDefaultColumnsFromModel();
80 ref_table.createDefaultColumnsFromModel();
81 body_table.setSelectionModel(ref_table.getSelectionModel());
82 body_table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
83 ref_table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
84 //sizeBodycolWidthsToFit();
85 JTableHeader header = ref_table.getTableHeader();
86 ref_table.addComponentListener(new ComponentAdapter() {
87 public void componentResized(ComponentEvent e) {
88 view_port.setPreferredSize(ref_table.getSize());
89 }
90 });
91 setCorner(UPPER_LEFT_CORNER, ref_table.getTableHeader());
92 view_port = new JViewport();
93 view_port.setView(ref_table);
94 setRowHeader(view_port);
95 setRefcolWidth(100); // arbitrary default
96 setViewportView(body_table);
97 }
98
99 /**
100 * Calculate a preferred size that shows the whole table
101 * until the table exceeds the screen size and a size that
102 * is returned becomes 80 % of the screen size.
103 *
104 */
105 public final Dimension getPreferredSize() {
106 // get width and height of reference columns
107 Dimension dim = ref_table.getPreferredSize();
108 double prefwidth = dim.getWidth();
109 double prefheight = dim.getHeight();
110 // add width of table body
111 dim = body_table.getPreferredSize();
112 prefwidth += dim.getWidth();
113 // add height of header
114 dim = body_table.getTableHeader().getPreferredSize();
115 prefheight += dim.getHeight() * 4.0; // * 4 for menubar
116 prefwidth += 10; // scrollbar width
117 Dimension screendim = Toolkit.getDefaultToolkit()
118 .getScreenSize();
119 double max = screendim.getWidth() * 0.8;
120 if (prefwidth > max) {
121 prefwidth = max;
122 }
123 max = screendim.getHeight() * 0.8;
124 if (prefheight > max) {
125 prefheight = max;
126 }
127 dim.setSize(prefwidth, prefheight);
128 return dim;
129 }
130
131 /**
132 * Return the JTable of the ReferenceColumn.
133 * I use this to pass something to SavableTableDialog.
134 *
135 */
136
137 public final JTable getRefcolTable() {
138 return ref_table;
139 }
140
141 /**
142 * Dump out various preferred sizes. DEBUG.
143 *
144 */
145 public final void getSizes() {
146 Dimension dim = ref_table.getPreferredSize();
147 System.out.println("ref_table " + dim.getWidth() + " " + dim.getHeight());
148 dim = body_table.getPreferredSize();
149 System.out.println("body_table " + dim.getWidth() + " " + dim.getHeight());
150 dim = body_table.getTableHeader().getPreferredSize();
151 System.out.println("body_header " + dim.getWidth() + " " + dim.getHeight());
152 dim = getPreferredSize();
153 System.out.println("scroller preferred " + dim.getWidth() + " " + dim.getHeight());
154 dim = getPreferredSize();
155 System.out.println("scroller size " + dim.getWidth() + " " + dim.getHeight());
156 }
157
158 /** @since J-Bird 0.3.0 */
159
160 public void nullify() {
161 ref_table = null;
162 body_table = null;
163 view_port = null;
164 bodycol_model = null;
165 refcol_model = null;
166 first_column = null;
167 }
168
169 /**
170 * Set the width of the reference column and readjust
171 * overall size accordingly.
172 */
173
174 public final void setRefcolWidth(int width) {
175 first_column.setMinWidth(width);
176 ref_table.setMaximumSize(new Dimension(width, 100000));
177 view_port.setPreferredSize(ref_table.getMaximumSize());
178 }
179
180 /**
181 * Set widths of all columns in body of table to the
182 * width provided.
183 * @since J-Bird 0.1.4
184 */
185
186 public final void setBodycolWidths(int width) {
187 Enumeration columns = bodycol_model.getColumns();
188 while (columns.hasMoreElements()) {
189 TableColumn column = (TableColumn)columns.nextElement();
190 column.setPreferredWidth(width);
191 }
192 }
193
194 /**
195 * Set widths of columns in the body of the table
196 * using the widths provided. Subscript 0 refers to
197 * the first column of the body - not to the reference column.
198 */
199
200 public final void setBodycolWidths(int[] widths) {
201 int widthslen = widths.length;
202 int widthidx = 0;
203 Enumeration columns = bodycol_model.getColumns();
204 while (columns.hasMoreElements() && widthidx < widthslen) {
205 TableColumn column = (TableColumn)columns.nextElement();
206 column.setPreferredWidth(widths[widthidx]);
207 widthidx ++;
208 }
209 }
210
211 /** This doesn't seem to work. */
212 public final void sizeBodycolWidthsToFit() {
213 Enumeration columns = bodycol_model.getColumns();
214 while (columns.hasMoreElements()) {
215 TableColumn column = (TableColumn)columns.nextElement();
216 int preresize = column.getPreferredWidth();
217 column.sizeWidthToFit();
218 System.out.println(preresize + " -> " + column.getWidth());
219 }
220 }
221
222 /////////////////////// protected below ///////////////////////////
223
224 /**
225 * A method that can be overwridden with to customize
226 * the table a bit.
227 *
228 */
229
230 protected JTable buildBodyTable(TableModel tablemodel,
231 TableColumnModel columnmodel) {
232 return new JTable(tablemodel, columnmodel);
233 }
234
235 /**
236 * A method that can be overwridden with to customize
237 * the table a bit.
238 * <p>
239 * I'll probably override it to make use of a SpeciesTable.
240 *
241 */
242
243 protected JTable buildRefColTable(TableModel tablemodel,
244 TableColumnModel columnmodel) {
245 JTable answer = new JTable(tablemodel, columnmodel);
246 //answer.setColumnSelectionAllowed(false);
247 //answer.setRowSelectionAllowed(false);
248 //answer.setCellSelectionEnabled(false);
249 return answer;
250 }
251
252 }
253