001: package net.sf.jftp.gui.base.dir;
002:
003: import java.awt.BorderLayout;
004: import java.awt.Component;
005: import java.lang.reflect.Constructor;
006: import java.lang.reflect.Method;
007: import java.util.Vector;
008:
009: import javax.swing.DefaultListModel;
010: import javax.swing.ImageIcon;
011: import javax.swing.JComponent;
012: import javax.swing.JLabel;
013: import javax.swing.JList;
014: import javax.swing.JTable;
015: import javax.swing.table.JTableHeader;
016: import javax.swing.table.TableCellRenderer;
017: import javax.swing.table.TableColumn;
018: import javax.swing.table.TableColumnModel;
019: import javax.swing.table.TableModel;
020:
021: import net.sf.jftp.config.Settings;
022:
023: public class TableUtils {
024:
025: /**
026: * Setzt die Breite der TableColumns.
027: *
028: * Quelle: http://www.chka.de/swing/table/cell-sizes.html
029: *
030: * @param table
031: */
032: public static void calcColumnWidths(JTable table) {
033: JTableHeader header = table.getTableHeader();
034:
035: TableCellRenderer defaultHeaderRenderer = null;
036:
037: if (header != null)
038: defaultHeaderRenderer = header.getDefaultRenderer();
039:
040: TableColumnModel columns = table.getColumnModel();
041: TableModel data = table.getModel();
042:
043: int margin = columns.getColumnMargin(); // only JDK1.3
044:
045: int rowCount = data.getRowCount();
046:
047: int totalWidth = 0;
048:
049: for (int i = columns.getColumnCount() - 1; i >= 0; --i) {
050: TableColumn column = columns.getColumn(i);
051:
052: int columnIndex = column.getModelIndex();
053:
054: int width = -1;
055:
056: TableCellRenderer h = column.getHeaderRenderer();
057:
058: if (h == null)
059: h = defaultHeaderRenderer;
060:
061: if (h != null) // Not explicitly impossible
062: {
063: Component c = h.getTableCellRendererComponent(table,
064: column.getHeaderValue(), false, false, -1, i);
065:
066: width = c.getPreferredSize().width;
067: }
068:
069: for (int row = rowCount - 1; row >= 0; --row) {
070: TableCellRenderer r = table.getCellRenderer(row, i);
071:
072: Component c = r.getTableCellRendererComponent(table,
073: data.getValueAt(row, columnIndex), false,
074: false, row, i);
075:
076: width = Math.max(width, c.getPreferredSize().width);
077: }
078:
079: if (width >= 0)
080: column.setPreferredWidth(width + margin); // <1.3: without margin
081: else
082: ; // ???
083:
084: totalWidth += column.getPreferredWidth();
085: }
086:
087: // only <1.3: totalWidth += columns.getColumnCount() * columns.getColumnMargin();
088:
089: /* If you like; This does not make sense for two many columns!
090: Dimension size = table.getPreferredScrollableViewportSize();
091:
092: size.width = totalWidth;
093:
094: table.setPreferredScrollableViewportSize(size);
095: */
096:
097: // table.sizeColumnsToFit(-1); <1.3; possibly even table.revalidate()
098: // if (header != null)
099: // header.repaint(); only makes sense when the header is visible (only <1.3)
100: }
101:
102: public static void setFixedWidths(JTable table) {
103: JTableHeader header = table.getTableHeader();
104:
105: TableCellRenderer defaultHeaderRenderer = null;
106:
107: if (header != null)
108: defaultHeaderRenderer = header.getDefaultRenderer();
109:
110: TableColumnModel columns = table.getColumnModel();
111: TableModel data = table.getModel();
112:
113: int rowCount = data.getRowCount();
114:
115: for (int i = 0; i < columns.getColumnCount(); i++) {
116: TableColumn column = columns.getColumn(i);
117: int columnIndex = column.getModelIndex();
118: int width = -1;
119:
120: if (i == 0) {
121: column.setPreferredWidth(20);
122: column.setMaxWidth(20);
123: } else if (i == 1) {
124: column.setMinWidth(100);
125: column.setPreferredWidth(400);
126: } else if (i == 2) {
127: column.setMinWidth(60);
128: column.setPreferredWidth(80);
129: //column.setMaxWidth(90);
130: } else if (i == 3) {
131: column.setMinWidth(25);
132: column.setPreferredWidth(25);
133: //column.setMaxWidth(90);
134: }
135: }
136: }
137:
138: /**
139: * Synchronisiert eine JList mit einem JTable.
140: *
141: * Die Selections werden von dem Table auf die List kopiert.
142: *
143: * @param list
144: * @param listTbl
145: */
146: public static void copyTableSelectionsToJList(JList list,
147: JTable listTbl) {
148:
149: list.setSelectedIndices(new int[0]);
150:
151: int rows = listTbl.getRowCount();
152: Vector sel = new Vector();
153:
154: for (int i = 0; i < rows; i++) {
155: if (listTbl.getSelectionModel().isSelectedIndex(i))
156: sel.add(new Integer(i));
157: }
158:
159: int tmp[] = new int[sel.size()];
160: for (int i = 0; i < sel.size(); i++)
161: tmp[i] = ((Integer) sel.get(i)).intValue();
162:
163: list.setSelectedIndices(tmp);
164: }
165:
166: /**
167: * Generisches Modell erzeugen.
168: *
169: * JList muss Vektoren von im JTable anzeigbaren Objekten enthalten.
170: *
171: * @param l
172: * @return
173: */
174: private static synchronized TableModel generateTableModel(JList l) {
175:
176: TableModel dataModel = new MaterializedTableModel(l) {
177:
178: public Class getColumnClass(int columnIndex) {
179: if (columnIndex == 0)
180: return ImageIcon.class;
181: else if (columnIndex == 3)
182: return JLabel.class;
183: else
184: return String.class;
185: }
186:
187: public int getColumnCount() {
188: //return (list.getModel().getSize() > 0 ? ((Vector)list.getModel().getElementAt(0)).size() : 0);
189: return 4;
190: }
191:
192: public int getRowCount() {
193: return list.getModel().getSize();
194: }
195:
196: public Object getValueAt(int row, int col) {
197:
198: if (list.getModel().getSize() == 0)
199: return "" + null;
200:
201: DirEntry ret = (DirEntry) list.getModel().getElementAt(
202: row);
203:
204: if (col == 0)
205: return ret.getImageIcon();
206: else if (col == 1)
207: return ret.toString();
208: else if (col == 2) {
209: String tmp = "" + ret.getFileSize();
210: String r = tmp.replaceAll(" >", "");
211: return r;
212: } else if (col == 3) {
213: return ret;
214: }
215:
216: //System.out.println(">>> "+ret.get(col)+" -> "+(ret.get(col) instanceof Status));
217:
218: //return ret.size() > col ? ret.get(col) : "<ERROR>";
219: return ret;
220: }
221: };
222:
223: return dataModel;
224: }
225:
226: /**
227: * F?hrt Updates auf einen beliebigen JTable durch.
228: *
229: * list muss hierzu vom Typ Vector<String> sein.
230: *
231: * @param list
232: * @param listTbl
233: */
234: public static void layoutTable(JList list, JTable listTbl) {
235: layoutTable(list, listTbl, null);
236: }
237:
238: /**
239: * F?hrt Updates auf einen beliebigen JTable durch.
240: *
241: * list muss hierzu vom Typ Vector<String> sein.
242: */
243: public static void layoutTable(JList list, JTable listTbl,
244: Vector names) {
245: listTbl.setModel(generateTableModel(list));
246:
247: if (Settings.useFixedTableWidths) {
248: setFixedWidths(listTbl);
249: } else {
250: calcColumnWidths(listTbl);
251: }
252:
253: if (names != null)
254: modifyTableHeader(listTbl.getTableHeader(), names);
255:
256: // 1.6+ only
257: tryToEnableRowSorting(listTbl);
258:
259: //listTbl.doLayout();
260: }
261:
262: /**
263: * Versucht ?ber die Java-Reflection-API das automatische JTable-sort zu aktivieren.
264: *
265: * Das Feature ist neu in JDK1.6 und erlaubt es dem Benutzer durch Clicks auf die
266: * jeweiligen Tabellenspalten Zeilen automatisch zu sortieren.
267: *
268: * @param listTbl JTable
269: */
270: public static void tryToEnableRowSorting(JTable listTbl) {
271: /*
272: try {
273: TableModel mdl = listTbl.getModel();
274: Class c = Class.forName("javax.swing.table.TableRowSorter");
275: Class c2 = Class.forName("javax.swing.RowSorter");
276:
277: Constructor con = c.getConstructor(TableModel.class);
278:
279: Object args[] = new Object[1];
280: args[0] = mdl;
281:
282: Method meth = listTbl.getClass().getMethod("setRowSorter", c2);
283: Object retobj = meth.invoke(listTbl, con.newInstance(args));
284:
285: Settings.IS_JAVA_1_6 = true;
286:
287: // System.out.println("JTable-Sortierung wurde aktiviert.");
288: }
289: catch(Exception e) {
290: // System.out.println("JTable-Sortierung konnte nicht aktiviert werden.");
291: }
292: catch(Error ex) {
293: // System.out.println("JTable-Sortierung konnte nicht aktiviert werden.");
294: }
295: */
296: }
297:
298: /**
299: * Setzt den Header einer JTable
300: * @param head
301: * @param columnNames
302: */
303: public static void modifyTableHeader(JTableHeader head,
304: Vector columnNames) {
305:
306: TableColumnModel m = head.getColumnModel();
307:
308: if (m.getColumnCount() != columnNames.size()) {
309: System.out.println("Column mismatch: " + m.getColumnCount()
310: + "/" + columnNames.size());
311: return;
312: }
313:
314: for (int i = 0; i < columnNames.size(); i++) {
315: TableColumn c = m.getColumn(i);
316: c.sizeWidthToFit();
317: c.setHeaderValue(columnNames.get(i));
318: }
319: }
320:
321: /**
322: * Erzeugt einen Panel mit View und Header eines JTables.
323: *
324: */
325: public static JComponent makeTable(JTable table, JComponent cont) {
326: JTableHeader header = table.getTableHeader();
327:
328: cont.setLayout(new BorderLayout());
329: cont.add(header, BorderLayout.NORTH);
330: cont.add(table, BorderLayout.CENTER);
331:
332: return cont;
333: }
334:
335: }
|