1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49:
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62: import ;
63:
64:
67: public class BasicTableHeaderUI extends TableHeaderUI
68: {
69:
73: static int COLUMN_BOUNDARY_TOLERANCE = 3;
74:
75: public static ComponentUI createUI(JComponent h)
76: {
77: return new BasicTableHeaderUI();
78: }
79:
80:
83: protected JTableHeader header;
84:
85:
89: protected MouseInputListener mouseInputListener;
90:
91:
94: protected CellRendererPane rendererPane;
95:
96:
99: private Border cellBorder;
100:
101:
104: private Cursor originalCursor;
105:
106:
109: Rectangle draggingHeaderRect;
110:
111:
115: public class MouseInputHandler
116: implements MouseInputListener
117: {
118:
122: boolean showingResizeCursor;
123:
124:
129: int draggingFrom = - 1;
130:
131:
134: int draggingColumnNumber;
135:
136:
139: int prevPrefWidth = - 1;
140:
141:
144: Timer timer;
145:
146:
149: public void mouseClicked(MouseEvent e)
150: {
151:
152: }
153:
154:
157: public void mouseDragged(MouseEvent e)
158: {
159: TableColumn resizeIt = header.getResizingColumn();
160: if (resizeIt != null && header.getResizingAllowed())
161: {
162:
163: if (timer == null)
164: {
165:
166:
167: timer = new Timer(1, new ActionListener()
168: {
169: public void actionPerformed(ActionEvent e)
170: {
171: header.getTable().doLayout();
172: }
173: });
174: timer.setRepeats(false);
175: timer.setCoalesce(true);
176: }
177: resizeIt.setPreferredWidth(prevPrefWidth + e.getX() - draggingFrom);
178: timer.restart();
179: }
180: else if (draggingHeaderRect != null && header.getReorderingAllowed())
181: {
182: draggingHeaderRect.x = e.getX() + draggingFrom;
183: header.repaint();
184: }
185: }
186:
187:
190: public void mouseEntered(MouseEvent e)
191: {
192:
193: }
194:
195:
198: public void mouseExited(MouseEvent e)
199: {
200:
201: }
202:
203:
206: public void mouseMoved(MouseEvent e)
207: {
208:
209: if (e.getButton() == 0 && header.getResizingAllowed())
210: {
211: TableColumnModel model = header.getColumnModel();
212: int n = model.getColumnCount();
213: if (n < 2)
214:
215:
216: return;
217:
218: boolean onBoundary = false;
219:
220: int x = e.getX();
221: int a = x - COLUMN_BOUNDARY_TOLERANCE;
222: int b = x + COLUMN_BOUNDARY_TOLERANCE;
223:
224: int p = 0;
225:
226: Scan: for (int i = 0; i < n - 1; i++)
227: {
228: p += model.getColumn(i).getWidth();
229:
230: if (p >= a && p <= b)
231: {
232: TableColumn column = model.getColumn(i);
233: onBoundary = true;
234:
235: draggingFrom = x;
236: prevPrefWidth = column.getWidth();
237: header.setResizingColumn(column);
238: break Scan;
239: }
240: }
241:
242: if (onBoundary != showingResizeCursor)
243: {
244:
245: if (onBoundary)
246: {
247:
248: originalCursor = header.getCursor();
249: if (p < x)
250: header.setCursor(Cursor.getPredefinedCursor(
251: Cursor.W_RESIZE_CURSOR));
252: else
253: header.setCursor(Cursor.getPredefinedCursor(
254: Cursor.E_RESIZE_CURSOR));
255: }
256: else
257: {
258: header.setCursor(originalCursor);
259: header.setResizingColumn(null);
260: }
261:
262: showingResizeCursor = onBoundary;
263: }
264: }
265: }
266:
267:
270: public void mousePressed(MouseEvent e)
271: {
272: if (header.getResizingAllowed())
273: {
274: TableColumn resizingColumn = header.getResizingColumn();
275: if (resizingColumn != null)
276: {
277: resizingColumn.setPreferredWidth(resizingColumn.getWidth());
278: return;
279: }
280: }
281:
282: if (header.getReorderingAllowed())
283: {
284: TableColumnModel model = header.getColumnModel();
285: int n = model.getColumnCount();
286: if (n < 2)
287:
288: return;
289:
290: boolean onBoundary = false;
291:
292: int x = e.getX();
293: int p = 0;
294: int col = - 1;
295:
296: Scan: for (int i = 0; i < n; i++)
297: {
298: p += model.getColumn(i).getWidth();
299: if (p > x)
300: {
301: col = i;
302: break Scan;
303: }
304: }
305: if (col < 0)
306: return;
307:
308: TableColumn dragIt = model.getColumn(col);
309: header.setDraggedColumn(dragIt);
310:
311: draggingFrom = (p - dragIt.getWidth()) - x;
312: draggingHeaderRect = new Rectangle(header.getHeaderRect(col));
313: draggingColumnNumber = col;
314: }
315: }
316:
317:
321: public void mouseReleased(MouseEvent e)
322: {
323: if (header.getResizingColumn() != null && header.getResizingAllowed())
324: endResizing();
325: if (header.getDraggedColumn() != null && header.getReorderingAllowed())
326: endDragging(e);
327: }
328:
329:
332: void endResizing()
333: {
334: TableColumnModel model = header.getColumnModel();
335: int n = model.getColumnCount();
336: if (n > 2)
337: {
338: TableColumn c;
339: for (int i = 0; i < n; i++)
340: {
341: c = model.getColumn(i);
342: c.setPreferredWidth(c.getWidth());
343: }
344: }
345: header.setResizingColumn(null);
346: showingResizeCursor = false;
347: if (timer != null)
348: timer.stop();
349: header.setCursor(originalCursor);
350: }
351:
352:
358: void endDragging(MouseEvent e)
359: {
360: header.setDraggedColumn(null);
361: draggingHeaderRect = null;
362:
363: TableColumnModel model = header.getColumnModel();
364:
365:
366: int x = e.getX();
367: int p = 0;
368:
369: int col = model.getColumnCount() - 1;
370: int n = model.getColumnCount();
371:
372:
373:
374:
375: Scan: for (int i = 0; i < n; i++)
376: {
377: p += model.getColumn(i).getWidth();
378: if (p > x)
379: {
380: col = i;
381: break Scan;
382: }
383: }
384:
385: header.getTable().moveColumn(draggingColumnNumber, col);
386: }
387: }
388:
389:
394: protected MouseInputListener createMouseInputListener()
395: {
396: return new MouseInputHandler();
397: }
398:
399:
402: public BasicTableHeaderUI()
403: {
404: mouseInputListener = createMouseInputListener();
405: }
406:
407: protected void installDefaults()
408: {
409: LookAndFeel.installColorsAndFont(header, "TableHeader.background",
410: "TableHeader.foreground",
411: "TableHeader.font");
412: cellBorder = UIManager.getBorder("TableHeader.cellBorder");
413: }
414:
415: protected void installKeyboardActions()
416: {
417:
418: }
419:
420:
425: protected void installListeners()
426: {
427: header.addMouseListener(mouseInputListener);
428: header.addMouseMotionListener(mouseInputListener);
429: }
430:
431: public void installUI(JComponent c)
432: {
433: header = (JTableHeader) c;
434: rendererPane = new CellRendererPane();
435: installDefaults();
436: installKeyboardActions();
437: installListeners();
438: }
439:
440: protected void uninstallDefaults()
441: {
442: header.setBackground(null);
443: header.setForeground(null);
444: header.setFont(null);
445: }
446:
447: protected void uninstallKeyboardActions()
448: {
449:
450: }
451:
452:
455: protected void uninstallListeners()
456: {
457: header.removeMouseListener(mouseInputListener);
458: header.removeMouseMotionListener(mouseInputListener);
459: }
460:
461: public void uninstallUI(JComponent c)
462: {
463: uninstallListeners();
464: uninstallKeyboardActions();
465: uninstallDefaults();
466: }
467:
468:
471: public void paint(Graphics gfx, JComponent c)
472: {
473: TableColumnModel cmod = header.getColumnModel();
474: int ncols = cmod.getColumnCount();
475: if (ncols == 0)
476: return;
477:
478: Rectangle clip = gfx.getClipBounds();
479: TableCellRenderer defaultRend = header.getDefaultRenderer();
480:
481: for (int i = 0; i < ncols; ++i)
482: {
483: Rectangle bounds = header.getHeaderRect(i);
484: if (bounds.intersects(clip))
485: {
486: Rectangle oldClip = gfx.getClipBounds();
487: TableColumn col = cmod.getColumn(i);
488: TableCellRenderer rend = col.getHeaderRenderer();
489: if (rend == null)
490: rend = defaultRend;
491: Object val = col.getHeaderValue();
492: Component comp = rend.getTableCellRendererComponent(header.getTable(),
493: val,
494: false,
495: false,
496: -1, i);
497:
498:
499: comp.setFont(header.getFont());
500: comp.setBackground(header.getBackground());
501: comp.setForeground(header.getForeground());
502: if (comp instanceof JComponent)
503: ((JComponent) comp).setBorder(cellBorder);
504: rendererPane.paintComponent(gfx, comp, header, bounds.x, bounds.y,
505: bounds.width, bounds.height);
506: }
507: }
508:
509:
510:
511:
512: if (draggingHeaderRect != null)
513: {
514: gfx.setColor(header.getForeground());
515: gfx.drawRect(draggingHeaderRect.x, draggingHeaderRect.y + 2,
516: draggingHeaderRect.width - 1, draggingHeaderRect.height - 6);
517: }
518: }
519:
520:
527: public Dimension getPreferredSize(JComponent ignored)
528: {
529: TableColumnModel cmod = header.getColumnModel();
530: TableCellRenderer defaultRend = header.getDefaultRenderer();
531: int ncols = cmod.getColumnCount();
532: Dimension ret = new Dimension(0, 0);
533: int spacing = 0;
534:
535: if (header.getTable() != null
536: && header.getTable().getIntercellSpacing() != null)
537: spacing = header.getTable().getIntercellSpacing().width;
538:
539: for (int i = 0; i < ncols; ++i)
540: {
541: TableColumn col = cmod.getColumn(i);
542: TableCellRenderer rend = col.getHeaderRenderer();
543: if (rend == null)
544: rend = defaultRend;
545: Object val = col.getHeaderValue();
546: Component comp = rend.getTableCellRendererComponent(header.getTable(),
547: val,
548: false,
549: false,
550: -1, i);
551: comp.setFont(header.getFont());
552: comp.setBackground(header.getBackground());
553: comp.setForeground(header.getForeground());
554: if (comp instanceof JComponent)
555: ((JComponent) comp).setBorder(cellBorder);
556:
557: Dimension d = comp.getPreferredSize();
558: ret.width += spacing;
559: ret.height = Math.max(d.height, ret.height);
560: }
561: ret.width = cmod.getTotalColumnWidth();
562: return ret;
563: }
564:
565:
566: }