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:
203: }
204:
205:
208: public void mouseMoved(MouseEvent e)
209: {
210:
211: if (e.getButton() == 0 && header.getResizingAllowed())
212: {
213: TableColumnModel model = header.getColumnModel();
214: int n = model.getColumnCount();
215: if (n < 2)
216:
217:
218: return;
219:
220: boolean onBoundary = false;
221:
222: int x = e.getX();
223: int a = x - COLUMN_BOUNDARY_TOLERANCE;
224: int b = x + COLUMN_BOUNDARY_TOLERANCE;
225:
226: int p = 0;
227:
228: Scan: for (int i = 0; i < n - 1; i++)
229: {
230: p += model.getColumn(i).getWidth();
231:
232: if (p >= a && p <= b)
233: {
234: TableColumn column = model.getColumn(i);
235: onBoundary = true;
236:
237: draggingFrom = x;
238: prevPrefWidth = column.getWidth();
239: header.setResizingColumn(column);
240: break Scan;
241: }
242: }
243:
244: if (onBoundary != showingResizeCursor)
245: {
246:
247: if (onBoundary)
248: {
249:
250: originalCursor = header.getCursor();
251: if (p < x)
252: header.setCursor(Cursor.getPredefinedCursor(
253: Cursor.W_RESIZE_CURSOR));
254: else
255: header.setCursor(Cursor.getPredefinedCursor(
256: Cursor.E_RESIZE_CURSOR));
257: }
258: else
259: {
260: header.setCursor(originalCursor);
261: header.setResizingColumn(null);
262: }
263:
264: showingResizeCursor = onBoundary;
265: }
266: }
267: }
268:
269:
272: public void mousePressed(MouseEvent e)
273: {
274: if (header.getResizingAllowed())
275: {
276: TableColumn resizingColumn = header.getResizingColumn();
277: if (resizingColumn != null)
278: {
279: resizingColumn.setPreferredWidth(resizingColumn.getWidth());
280: return;
281: }
282: }
283:
284: if (header.getReorderingAllowed())
285: {
286: TableColumnModel model = header.getColumnModel();
287: int n = model.getColumnCount();
288: if (n < 2)
289:
290: return;
291:
292: boolean onBoundary = false;
293:
294: int x = e.getX();
295: int p = 0;
296: int col = - 1;
297:
298: Scan: for (int i = 0; i < n; i++)
299: {
300: p += model.getColumn(i).getWidth();
301: if (p > x)
302: {
303: col = i;
304: break Scan;
305: }
306: }
307: if (col < 0)
308: return;
309:
310: TableColumn dragIt = model.getColumn(col);
311: header.setDraggedColumn(dragIt);
312:
313: draggingFrom = (p - dragIt.getWidth()) - x;
314: draggingHeaderRect = new Rectangle(header.getHeaderRect(col));
315: draggingColumnNumber = col;
316: }
317: }
318:
319:
323: public void mouseReleased(MouseEvent e)
324: {
325: if (header.getResizingColumn() != null && header.getResizingAllowed())
326: endResizing();
327: if (header.getDraggedColumn() != null && header.getReorderingAllowed())
328: endDragging(e);
329: }
330:
331:
334: void endResizing()
335: {
336: TableColumnModel model = header.getColumnModel();
337: int n = model.getColumnCount();
338: if (n > 2)
339: {
340: TableColumn c;
341: for (int i = 0; i < n; i++)
342: {
343: c = model.getColumn(i);
344: c.setPreferredWidth(c.getWidth());
345: }
346: }
347: header.setResizingColumn(null);
348: showingResizeCursor = false;
349: if (timer != null)
350: timer.stop();
351: header.setCursor(originalCursor);
352: }
353:
354:
360: void endDragging(MouseEvent e)
361: {
362: header.setDraggedColumn(null);
363: draggingHeaderRect = null;
364:
365: TableColumnModel model = header.getColumnModel();
366:
367:
368: int x = e.getX();
369: int p = 0;
370:
371: int col = model.getColumnCount() - 1;
372: int n = model.getColumnCount();
373:
374:
375:
376:
377: Scan: for (int i = 0; i < n; i++)
378: {
379: p += model.getColumn(i).getWidth();
380: if (p > x)
381: {
382: col = i;
383: break Scan;
384: }
385: }
386:
387: header.getTable().moveColumn(draggingColumnNumber, col);
388: }
389: }
390:
391:
396: protected MouseInputListener createMouseInputListener()
397: {
398: return new MouseInputHandler();
399: }
400:
401:
404: public BasicTableHeaderUI()
405: {
406: mouseInputListener = createMouseInputListener();
407: }
408:
409: protected void installDefaults()
410: {
411: LookAndFeel.installColorsAndFont(header, "TableHeader.background",
412: "TableHeader.foreground",
413: "TableHeader.font");
414: cellBorder = UIManager.getBorder("TableHeader.cellBorder");
415: }
416:
417: protected void installKeyboardActions()
418: throws NotImplementedException
419: {
420:
421: }
422:
423:
428: protected void installListeners()
429: {
430: header.addMouseListener(mouseInputListener);
431: header.addMouseMotionListener(mouseInputListener);
432: }
433:
434: public void installUI(JComponent c)
435: {
436: header = (JTableHeader) c;
437: rendererPane = new CellRendererPane();
438: installDefaults();
439: installKeyboardActions();
440: installListeners();
441: }
442:
443: protected void uninstallDefaults()
444: {
445: header.setBackground(null);
446: header.setForeground(null);
447: header.setFont(null);
448: }
449:
450: protected void uninstallKeyboardActions()
451: throws NotImplementedException
452: {
453:
454: }
455:
456:
459: protected void uninstallListeners()
460: {
461: header.removeMouseListener(mouseInputListener);
462: header.removeMouseMotionListener(mouseInputListener);
463: }
464:
465: public void uninstallUI(JComponent c)
466: {
467: uninstallListeners();
468: uninstallKeyboardActions();
469: uninstallDefaults();
470: }
471:
472:
475: public void paint(Graphics gfx, JComponent c)
476: {
477: TableColumnModel cmod = header.getColumnModel();
478: int ncols = cmod.getColumnCount();
479: if (ncols == 0)
480: return;
481:
482: Rectangle clip = gfx.getClipBounds();
483: TableCellRenderer defaultRend = header.getDefaultRenderer();
484:
485: for (int i = 0; i < ncols; ++i)
486: {
487: Rectangle bounds = header.getHeaderRect(i);
488: if (bounds.intersects(clip))
489: {
490: Rectangle oldClip = gfx.getClipBounds();
491: TableColumn col = cmod.getColumn(i);
492: TableCellRenderer rend = col.getHeaderRenderer();
493: if (rend == null)
494: rend = defaultRend;
495: Object val = col.getHeaderValue();
496: Component comp = rend.getTableCellRendererComponent(header.getTable(),
497: val,
498: false,
499: false,
500: -1, i);
501:
502:
503: comp.setFont(header.getFont());
504: comp.setBackground(header.getBackground());
505: comp.setForeground(header.getForeground());
506: if (comp instanceof JComponent)
507: ((JComponent) comp).setBorder(cellBorder);
508: rendererPane.paintComponent(gfx, comp, header, bounds.x, bounds.y,
509: bounds.width, bounds.height);
510: }
511: }
512:
513:
514:
515:
516: if (draggingHeaderRect != null)
517: {
518: gfx.setColor(header.getForeground());
519: gfx.drawRect(draggingHeaderRect.x, draggingHeaderRect.y + 2,
520: draggingHeaderRect.width - 1, draggingHeaderRect.height - 6);
521: }
522: }
523:
524:
531: public Dimension getPreferredSize(JComponent ignored)
532: {
533: TableColumnModel cmod = header.getColumnModel();
534: TableCellRenderer defaultRend = header.getDefaultRenderer();
535: int ncols = cmod.getColumnCount();
536: Dimension ret = new Dimension(0, 0);
537: int spacing = 0;
538:
539: if (header.getTable() != null
540: && header.getTable().getIntercellSpacing() != null)
541: spacing = header.getTable().getIntercellSpacing().width;
542:
543: for (int i = 0; i < ncols; ++i)
544: {
545: TableColumn col = cmod.getColumn(i);
546: TableCellRenderer rend = col.getHeaderRenderer();
547: if (rend == null)
548: rend = defaultRend;
549: Object val = col.getHeaderValue();
550: Component comp = rend.getTableCellRendererComponent(header.getTable(),
551: val,
552: false,
553: false,
554: -1, i);
555: comp.setFont(header.getFont());
556: comp.setBackground(header.getBackground());
557: comp.setForeground(header.getForeground());
558: if (comp instanceof JComponent)
559: ((JComponent) comp).setBorder(cellBorder);
560:
561: Dimension d = comp.getPreferredSize();
562: ret.width += spacing;
563: ret.height = Math.max(d.height, ret.height);
564: }
565: ret.width = cmod.getTotalColumnWidth();
566: return ret;
567: }
568:
569:
570: }