1:
37:
38:
39: package ;
40:
41: import ;
42:
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51:
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62: import ;
63: import ;
64: import ;
65:
66:
69: public class BasicTableHeaderUI extends TableHeaderUI
70: {
71:
75: static int COLUMN_BOUNDARY_TOLERANCE = 3;
76:
77: public static ComponentUI createUI(JComponent h)
78: {
79: return new BasicTableHeaderUI();
80: }
81:
82:
85: protected JTableHeader header;
86:
87:
91: protected MouseInputListener mouseInputListener;
92:
93:
96: protected CellRendererPane rendererPane;
97:
98:
101: private Border cellBorder;
102:
103:
106: private Cursor originalCursor;
107:
108:
111: Rectangle draggingHeaderRect;
112:
113:
117: public class MouseInputHandler
118: implements MouseInputListener
119: {
120:
124: boolean showingResizeCursor;
125:
126:
131: int draggingFrom = - 1;
132:
133:
136: int draggingColumnNumber;
137:
138:
141: int prevPrefWidth = - 1;
142:
143:
146: Timer timer;
147:
148:
151: public void mouseClicked(MouseEvent e)
152: {
153:
154: }
155:
156:
159: public void mouseDragged(MouseEvent e)
160: {
161: TableColumn resizeIt = header.getResizingColumn();
162: if (resizeIt != null && header.getResizingAllowed())
163: {
164:
165: if (timer == null)
166: {
167:
168:
169: timer = new Timer(1, new ActionListener()
170: {
171: public void actionPerformed(ActionEvent e)
172: {
173: header.getTable().doLayout();
174: }
175: });
176: timer.setRepeats(false);
177: timer.setCoalesce(true);
178: }
179: resizeIt.setPreferredWidth(prevPrefWidth + e.getX() - draggingFrom);
180: timer.restart();
181: }
182: else if (draggingHeaderRect != null && header.getReorderingAllowed())
183: {
184: draggingHeaderRect.x = e.getX() + draggingFrom;
185: header.repaint();
186: }
187: }
188:
189:
192: public void mouseEntered(MouseEvent e)
193: {
194:
195: }
196:
197:
200: public void mouseExited(MouseEvent e)
201: {
202: if (header.getResizingColumn() != null && header.getResizingAllowed())
203: endResizing();
204: if (header.getDraggedColumn() != null && header.getReorderingAllowed())
205: endDragging(null);
206: }
207:
208:
211: public void mouseMoved(MouseEvent e)
212: {
213:
214: if (e.getButton() == 0 && header.getResizingAllowed())
215: {
216: TableColumnModel model = header.getColumnModel();
217: int n = model.getColumnCount();
218: if (n < 2)
219:
220:
221: return;
222:
223: boolean onBoundary = false;
224:
225: int x = e.getX();
226: int a = x - COLUMN_BOUNDARY_TOLERANCE;
227: int b = x + COLUMN_BOUNDARY_TOLERANCE;
228:
229: int p = 0;
230:
231: Scan: for (int i = 0; i < n - 1; i++)
232: {
233: p += model.getColumn(i).getWidth();
234:
235: if (p >= a && p <= b)
236: {
237: TableColumn column = model.getColumn(i);
238: onBoundary = true;
239:
240: draggingFrom = x;
241: prevPrefWidth = column.getWidth();
242: header.setResizingColumn(column);
243: break Scan;
244: }
245: }
246:
247: if (onBoundary != showingResizeCursor)
248: {
249:
250: if (onBoundary)
251: {
252:
253: originalCursor = header.getCursor();
254: if (p < x)
255: header.setCursor(Cursor.getPredefinedCursor
256: (Cursor.W_RESIZE_CURSOR));
257: else
258: header.setCursor(Cursor.getPredefinedCursor
259: (Cursor.E_RESIZE_CURSOR));
260: }
261: else
262: {
263: header.setCursor(originalCursor);
264: header.setResizingColumn(null);
265: }
266:
267: showingResizeCursor = onBoundary;
268: }
269: }
270: }
271:
272:
275: public void mousePressed(MouseEvent e)
276: {
277: if (header.getResizingAllowed())
278: {
279: TableColumn resizingColumn = header.getResizingColumn();
280: if (resizingColumn != null)
281: {
282: resizingColumn.setPreferredWidth(resizingColumn.getWidth());
283: return;
284: }
285: }
286:
287: if (header.getReorderingAllowed())
288: {
289: TableColumnModel model = header.getColumnModel();
290: int n = model.getColumnCount();
291: if (n < 2)
292:
293: return;
294:
295: boolean onBoundary = false;
296:
297: int x = e.getX();
298: int p = 0;
299: int col = - 1;
300:
301: Scan: for (int i = 0; i < n; i++)
302: {
303: p += model.getColumn(i).getWidth();
304: if (p > x)
305: {
306: col = i;
307: break Scan;
308: }
309: }
310: if (col < 0)
311: return;
312:
313: TableColumn dragIt = model.getColumn(col);
314: header.setDraggedColumn(dragIt);
315:
316: draggingFrom = (p - dragIt.getWidth()) - x;
317: draggingHeaderRect = new Rectangle(header.getHeaderRect(col));
318: draggingColumnNumber = col;
319: }
320: }
321:
322:
326: public void mouseReleased(MouseEvent e)
327: {
328: if (header.getResizingColumn() != null && header.getResizingAllowed())
329: endResizing();
330: if (header.getDraggedColumn() != null && header.getReorderingAllowed())
331: endDragging(e);
332: }
333:
334:
337: void endResizing()
338: {
339: TableColumnModel model = header.getColumnModel();
340: int n = model.getColumnCount();
341: if (n > 2)
342: {
343: TableColumn c;
344: for (int i = 0; i < n; i++)
345: {
346: c = model.getColumn(i);
347: c.setPreferredWidth(c.getWidth());
348: }
349: }
350: header.setResizingColumn(null);
351: showingResizeCursor = false;
352: if (timer != null)
353: timer.stop();
354: header.setCursor(originalCursor);
355: }
356:
357:
363: void endDragging(MouseEvent e)
364: {
365: header.setDraggedColumn(null);
366:
367:
368: if (e == null)
369: {
370: header.repaint(draggingHeaderRect);
371: draggingHeaderRect = null;
372: return;
373: }
374: else
375: draggingHeaderRect = null;
376:
377: TableColumnModel model = header.getColumnModel();
378:
379:
380: int x = e.getX();
381: int p = 0;
382: int col = - 1;
383: int n = model.getColumnCount();
384:
385: Scan: for (int i = 0; i < n; i++)
386: {
387: p += model.getColumn(i).getWidth();
388: if (p > x)
389: {
390: col = i;
391: break Scan;
392: }
393: }
394: if (col >= 0)
395: header.getTable().moveColumn(draggingColumnNumber, col);
396: }
397: }
398:
399:
404: protected MouseInputListener createMouseInputListener()
405: {
406: return new MouseInputHandler();
407: }
408:
409:
412: public BasicTableHeaderUI()
413: {
414: mouseInputListener = createMouseInputListener();
415: }
416:
417: protected void installDefaults()
418: {
419: LookAndFeel.installColorsAndFont(header, "TableHeader.background",
420: "TableHeader.foreground",
421: "TableHeader.font");
422: cellBorder = UIManager.getBorder("TableHeader.cellBorder");
423: }
424:
425: protected void installKeyboardActions()
426: throws NotImplementedException
427: {
428:
429: }
430:
431:
436: protected void installListeners()
437: {
438: header.addMouseListener(mouseInputListener);
439: header.addMouseMotionListener(mouseInputListener);
440: }
441:
442: public void installUI(JComponent c)
443: {
444: header = (JTableHeader) c;
445: rendererPane = new CellRendererPane();
446: installDefaults();
447: installKeyboardActions();
448: installListeners();
449: }
450:
451: protected void uninstallDefaults()
452: {
453: header.setBackground(null);
454: header.setForeground(null);
455: header.setFont(null);
456: }
457:
458: protected void uninstallKeyboardActions()
459: throws NotImplementedException
460: {
461:
462: }
463:
464:
467: protected void uninstallListeners()
468: {
469: header.removeMouseListener(mouseInputListener);
470: header.removeMouseMotionListener(mouseInputListener);
471: }
472:
473: public void uninstallUI(JComponent c)
474: {
475: uninstallListeners();
476: uninstallKeyboardActions();
477: uninstallDefaults();
478: }
479:
480:
483: public void paint(Graphics gfx, JComponent c)
484: {
485: TableColumnModel cmod = header.getColumnModel();
486: int ncols = cmod.getColumnCount();
487: if (ncols == 0)
488: return;
489:
490: Rectangle clip = gfx.getClipBounds();
491: TableCellRenderer defaultRend = header.getDefaultRenderer();
492:
493: for (int i = 0; i < ncols; ++i)
494: {
495: Rectangle bounds = header.getHeaderRect(i);
496: if (bounds.intersects(clip))
497: {
498: Rectangle oldClip = gfx.getClipBounds();
499: TableColumn col = cmod.getColumn(i);
500: TableCellRenderer rend = col.getHeaderRenderer();
501: if (rend == null)
502: rend = defaultRend;
503: Object val = col.getHeaderValue();
504: Component comp = rend.getTableCellRendererComponent(header.getTable(),
505: val,
506: false,
507: false,
508: -1, i);
509:
510:
511: comp.setFont(header.getFont());
512: comp.setBackground(header.getBackground());
513: comp.setForeground(header.getForeground());
514: if (comp instanceof JComponent)
515: ((JComponent)comp).setBorder(cellBorder);
516: rendererPane.paintComponent(gfx, comp, header, bounds.x, bounds.y,
517: bounds.width, bounds.height);
518: }
519: }
520:
521:
522:
523:
524: if (draggingHeaderRect!=null)
525: {
526: gfx.setColor(header.getForeground());
527: gfx.drawRect(draggingHeaderRect.x, draggingHeaderRect.y+2,
528: draggingHeaderRect.width-1, draggingHeaderRect.height-6);
529: }
530: }
531:
532:
539: public Dimension getPreferredSize(JComponent ignored)
540: {
541: TableColumnModel cmod = header.getColumnModel();
542: TableCellRenderer defaultRend = header.getDefaultRenderer();
543: int ncols = cmod.getColumnCount();
544: Dimension ret = new Dimension(0,0);
545: int spacing = 0;
546:
547: if (header.getTable() != null
548: && header.getTable().getIntercellSpacing() != null)
549: spacing = header.getTable().getIntercellSpacing().width;
550:
551: for (int i = 0; i < ncols; ++i)
552: {
553: TableColumn col = cmod.getColumn(i);
554: TableCellRenderer rend = col.getHeaderRenderer();
555: if (rend == null)
556: rend = defaultRend;
557: Object val = col.getHeaderValue();
558: Component comp = rend.getTableCellRendererComponent(header.getTable(),
559: val,
560: false,
561: false,
562: -1, i);
563: comp.setFont(header.getFont());
564: comp.setBackground(header.getBackground());
565: comp.setForeground(header.getForeground());
566: if (comp instanceof JComponent)
567: ((JComponent)comp).setBorder(cellBorder);
568:
569: Dimension d = comp.getPreferredSize();
570: ret.width += spacing;
571: ret.height = Math.max(d.height, ret.height);
572: }
573: ret.width = cmod.getTotalColumnWidth();
574: return ret;
575: }
576:
577:
578: }