1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58: import ;
59: import ;
60: import ;
61:
62: import ;
63: import ;
64: import ;
65: import ;
66: import ;
67: import ;
68: import ;
69: import ;
70: import ;
71: import ;
72: import ;
73: import ;
74: import ;
75: import ;
76: import ;
77: import ;
78: import ;
79: import ;
80: import ;
81: import ;
82:
83:
91: public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants
92: {
93:
94: static class NavigateAction extends AbstractAction
95: {
96: int direction;
97:
98: NavigateAction(String name, int dir)
99: {
100: super(name);
101: direction = dir;
102: }
103:
104: public void actionPerformed(ActionEvent event)
105: {
106: JTabbedPane tp = (JTabbedPane) event.getSource();
107: BasicTabbedPaneUI ui = (BasicTabbedPaneUI) tp.getUI();
108:
109: ui.navigateSelectedTab(direction);
110: }
111:
112: }
113:
114: static class NavigatePageDownAction extends AbstractAction
115: {
116:
117: public NavigatePageDownAction()
118: {
119: super("navigatePageDown");
120: }
121:
122: public void actionPerformed(ActionEvent event)
123: {
124: JTabbedPane tp = (JTabbedPane) event.getSource();
125: BasicTabbedPaneUI ui = (BasicTabbedPaneUI) tp.getUI();
126:
127: int i = tp.getSelectedIndex();
128:
129: if (i < 0)
130: i = 0;
131:
132: ui.selectNextTabInRun(i);
133: }
134:
135: }
136:
137: static class NavigatePageUpAction extends AbstractAction
138: {
139:
140: public NavigatePageUpAction()
141: {
142: super("navigatePageUp");
143: }
144:
145: public void actionPerformed(ActionEvent event)
146: {
147: JTabbedPane tp = (JTabbedPane) event.getSource();
148: BasicTabbedPaneUI ui = (BasicTabbedPaneUI) tp.getUI();
149:
150: int i = tp.getSelectedIndex();
151:
152: if (i < 0)
153: i = 0;
154:
155: ui.selectPreviousTabInRun(i);
156:
157: }
158: }
159:
160: static class RequestFocusAction extends AbstractAction
161: {
162:
163: public RequestFocusAction()
164: {
165: super("requestFocus");
166: }
167:
168: public void actionPerformed(ActionEvent event)
169: {
170: ((JTabbedPane) event.getSource()).requestFocus();
171: }
172:
173: }
174:
175: static class RequestFocusForVisibleComponentAction extends AbstractAction
176: {
177:
178: public RequestFocusForVisibleComponentAction()
179: {
180: super("requestFocusForVisibleComponent");
181: }
182:
183: public void actionPerformed(ActionEvent event)
184: {
185: JTabbedPane tp = (JTabbedPane) event.getSource();
186:
187:
188:
189:
190:
191: tp.getSelectedComponent().requestFocus();
192: }
193:
194: }
195:
196:
211: public class FocusHandler extends FocusAdapter
212: {
213:
218: public void focusGained(FocusEvent e)
219: {
220: Object source = e.getSource();
221: if (source == panel )
222: tabPane.requestFocus();
223: else if (source == tabPane)
224: tabPane.repaint();
225: }
226:
227:
232: public void focusLost(FocusEvent e)
233: {
234: if (e.getOppositeComponent() == tabPane.getSelectedComponent())
235: tabPane.requestFocus();
236: else if (e.getSource() == tabPane)
237: tabPane.repaint();
238: }
239: }
240:
241:
250: public class MouseHandler extends MouseAdapter
251: {
252: public void mouseReleased(MouseEvent e)
253: {
254: Object s = e.getSource();
255:
256:
257:
258:
259: if (tabPane != e.getSource())
260: {
261: redispatchEvent(e);
262: e.setSource(s);
263: }
264: }
265:
266:
272: public void mousePressed(MouseEvent e)
273: {
274: Object s = e.getSource();
275:
276:
277:
278:
279: if (tabPane != e.getSource())
280: {
281: redispatchEvent(e);
282: e.setSource(s);
283: }
284:
285: int placement = tabPane.getTabPlacement();
286:
287: if (s == incrButton)
288: {
289: if(!incrButton.isEnabled())
290: return;
291:
292: currentScrollLocation++;
293:
294: switch (placement)
295: {
296: case JTabbedPane.TOP:
297: case JTabbedPane.BOTTOM:
298: currentScrollOffset = getTabAreaInsets(placement).left;
299: for (int i = 0; i < currentScrollLocation; i++)
300: currentScrollOffset += rects[i].width;
301: break;
302: default:
303: currentScrollOffset = getTabAreaInsets(placement).top;
304: for (int i = 0; i < currentScrollLocation; i++)
305: currentScrollOffset += rects[i].height;
306: break;
307: }
308:
309: updateViewPosition();
310: updateButtons();
311:
312: tabPane.repaint();
313: }
314: else if (s == decrButton)
315: {
316: if(!decrButton.isEnabled())
317: return;
318:
319:
320:
321:
322: if (currentScrollLocation > 0)
323: currentScrollLocation--;
324:
325:
326: currentScrollOffset = 0;
327:
328: switch (placement)
329: {
330: case JTabbedPane.TOP:
331: case JTabbedPane.BOTTOM:
332:
333: if (currentScrollLocation > 0)
334: currentScrollOffset = getTabAreaInsets(placement).left;
335:
336: for (int i = 0; i < currentScrollLocation; i++)
337: currentScrollOffset += rects[i].width;
338: break;
339: default:
340:
341: if (currentScrollLocation > 0)
342: currentScrollOffset = getTabAreaInsets(placement).top;
343:
344: for (int i = 0; i < currentScrollLocation; i++)
345: currentScrollOffset += rects[i].height;
346: }
347:
348: updateViewPosition();
349: updateButtons();
350:
351: tabPane.repaint();
352: }
353: else if (tabPane.isEnabled())
354: {
355: int index = tabForCoordinate(tabPane, e.getX(), e.getY());
356: if (!tabPane.isEnabledAt(index))
357: return;
358:
359: if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT
360: && s == panel)
361: {
362: scrollTab(index, placement);
363:
364: tabPane.setSelectedIndex(index);
365: tabPane.repaint();
366: }
367: else
368: {
369: tabPane.setSelectedIndex(index);
370: tabPane.revalidate();
371: tabPane.repaint();
372: }
373:
374: }
375:
376: }
377:
378:
384: public void mouseEntered(MouseEvent e)
385: {
386: Object s = e.getSource();
387:
388:
389:
390:
391: if (tabPane != e.getSource())
392: {
393: redispatchEvent(e);
394: e.setSource(s);
395: }
396:
397: int tabIndex = tabForCoordinate(tabPane, e.getX(), e.getY());
398: setRolloverTab(tabIndex);
399: }
400:
401:
407: public void mouseExited(MouseEvent e)
408: {
409: Object s = e.getSource();
410:
411:
412:
413:
414: if (tabPane != e.getSource())
415: {
416: redispatchEvent(e);
417: e.setSource(s);
418: }
419:
420: setRolloverTab(-1);
421: }
422:
423:
429: public void mouseMoved(MouseEvent ev)
430: {
431: Object s = ev.getSource();
432:
433: if (tabPane != ev.getSource())
434: {
435: ev.setSource(tabPane);
436: tabPane.dispatchEvent(ev);
437:
438: ev.setSource(s);
439: }
440:
441: int tabIndex = tabForCoordinate(tabPane, ev.getX(), ev.getY());
442: setRolloverTab(tabIndex);
443: }
444:
445:
450: void redispatchEvent(MouseEvent me)
451: {
452: me.setSource(tabPane);
453: Point viewPos = viewport.getViewPosition();
454: viewPos.x -= viewport.getX();
455: viewPos.y -= viewport.getY();
456: me.translatePoint(-viewPos.x, -viewPos.y);
457: tabPane.dispatchEvent(me);
458:
459: me.translatePoint(viewPos.x, viewPos.y);
460: }
461:
462: }
463:
464:
471: public class PropertyChangeHandler implements PropertyChangeListener
472: {
473:
479: public void propertyChange(PropertyChangeEvent e)
480: {
481: out:
482: {
483: if (e.getPropertyName().equals("tabLayoutPolicy"))
484: {
485: currentScrollLocation = currentScrollOffset = 0;
486:
487: layoutManager = createLayoutManager();
488:
489: tabPane.setLayout(layoutManager);
490: }
491: else if (e.getPropertyName().equals("tabPlacement")
492: && tabPane.getTabLayoutPolicy()
493: == JTabbedPane.SCROLL_TAB_LAYOUT)
494: {
495: incrButton = createIncreaseButton();
496: decrButton = createDecreaseButton();
497:
498:
499:
500:
501:
502:
503:
504:
505:
506: int oldPlacement = ((Integer) e.getOldValue()).intValue();
507: int newPlacement = ((Integer) e.getNewValue()).intValue();
508: switch (newPlacement)
509: {
510: case JTabbedPane.TOP:
511: case JTabbedPane.BOTTOM:
512: if (oldPlacement == JTabbedPane.TOP
513: || oldPlacement == JTabbedPane.BOTTOM)
514: break out;
515:
516: currentScrollOffset = getTabAreaInsets(newPlacement).left;
517: break;
518: default:
519: if (oldPlacement == JTabbedPane.LEFT
520: || oldPlacement == JTabbedPane.RIGHT)
521: break out;
522:
523: currentScrollOffset = getTabAreaInsets(newPlacement).top;
524: }
525:
526: updateViewPosition();
527: updateButtons();
528: }
529: }
530:
531: tabPane.revalidate();
532: tabPane.repaint();
533: }
534: }
535:
536:
545: public class TabbedPaneLayout implements LayoutManager
546: {
547:
553: public void addLayoutComponent(String name, Component comp)
554: {
555:
556: }
557:
558:
562: public void calculateLayoutInfo()
563: {
564: int count = tabPane.getTabCount();
565: assureRectsCreated(count);
566: calculateTabRects(tabPane.getTabPlacement(), count);
567: tabRunsDirty = false;
568: }
569:
570:
578: protected Dimension calculateSize(boolean minimum)
579: {
580: int tabPlacement = tabPane.getTabPlacement();
581:
582: int width = 0;
583: int height = 0;
584: Component c;
585: Dimension dims;
586:
587:
588:
589: int count = tabPane.getTabCount();
590: for (int i = 0; i < count; i++)
591: {
592: c = tabPane.getComponentAt(i);
593: if (c == null)
594: continue;
595: dims = minimum ? c.getMinimumSize() : c.getPreferredSize();
596: if (dims != null)
597: {
598: height = Math.max(height, dims.height);
599: width = Math.max(width, dims.width);
600: }
601: }
602:
603: Insets tabAreaInsets = getTabAreaInsets(tabPlacement);
604: if (tabPlacement == SwingConstants.TOP
605: || tabPlacement == SwingConstants.BOTTOM)
606: {
607: width = Math.max(calculateMaxTabWidth(tabPlacement), width);
608:
609: height += preferredTabAreaHeight(tabPlacement,
610: width - tabAreaInsets.left
611: - tabAreaInsets.right);
612: }
613: else
614: {
615: height = Math.max(calculateMaxTabHeight(tabPlacement), height);
616:
617: width += preferredTabAreaWidth(tabPlacement,
618: height - tabAreaInsets.top
619: - tabAreaInsets.bottom);
620: }
621:
622: Insets tabPaneInsets = tabPane.getInsets();
623: return new Dimension(width + tabPaneInsets.left + tabPaneInsets.right,
624: height + tabPaneInsets.top + tabPaneInsets.bottom);
625: }
626:
627:
628:
629:
630:
631:
632:
633:
634:
635:
636:
637:
646: protected void calculateTabRects(int tabPlacement, int tabCount)
647: {
648: Insets insets = tabPane.getInsets();
649: Insets tabAreaInsets = getTabAreaInsets(tabPlacement);
650: Dimension size = tabPane.getSize();
651:
652:
653: int x;
654: int y;
655:
656: int breakAt;
657:
658:
659: switch (tabPlacement)
660: {
661: case LEFT:
662: maxTabWidth = calculateMaxTabWidth(tabPlacement);
663: x = insets.left + tabAreaInsets.left;
664: y = insets.top + tabAreaInsets.top;
665: breakAt = size.height - (insets.bottom + tabAreaInsets.bottom);
666: break;
667: case RIGHT:
668: maxTabWidth = calculateMaxTabWidth(tabPlacement);
669: x = size.width - (insets.right + tabAreaInsets.right)
670: - maxTabWidth - 1;
671: y = insets.top + tabAreaInsets.top;
672: breakAt = size.height - (insets.bottom + tabAreaInsets.bottom);
673: break;
674: case BOTTOM:
675: maxTabHeight = calculateMaxTabHeight(tabPlacement);
676: x = insets.left + tabAreaInsets.left;
677: y = size.height - (insets.bottom + tabAreaInsets.bottom)
678: - maxTabHeight - 1;
679: breakAt = size.width - (insets.right + tabAreaInsets.right);
680: break;
681: case TOP:
682: default:
683: maxTabHeight = calculateMaxTabHeight(tabPlacement);
684: x = insets.left + tabAreaInsets.left;
685: y = insets.top + tabAreaInsets.top;
686: breakAt = size.width - (insets.right + tabAreaInsets.right);
687: break;
688: }
689:
690: if (tabCount == 0)
691: return;
692:
693: FontMetrics fm = getFontMetrics();
694: runCount = 0;
695: selectedRun = -1;
696: int selectedIndex = tabPane.getSelectedIndex();
697: if (selectedIndex < 0)
698: selectedIndex = 0;
699:
700: Rectangle rect;
701:
702:
703: if (tabPlacement == SwingConstants.TOP
704: || tabPlacement == SwingConstants.BOTTOM)
705: {
706: for (int i = 0; i < tabCount; i++)
707: {
708: rect = rects[i];
709: if (i > 0)
710: {
711: rect.x = rects[i - 1].x + rects[i - 1].width;
712: }
713: else
714: {
715: tabRuns[0] = 0;
716: runCount = 1;
717: maxTabWidth = 0;
718: rect.x = x;
719: }
720: rect.width = calculateTabWidth(tabPlacement, i, fm);
721: maxTabWidth = Math.max(maxTabWidth, rect.width);
722:
723: if (rect.x != 2 + insets.left && rect.x + rect.width > breakAt)
724: {
725: if (runCount > tabRuns.length - 1)
726: expandTabRunsArray();
727: tabRuns[runCount] = i;
728: runCount++;
729: rect.x = x;
730: }
731:
732: rect.y = y;
733: rect.height = maxTabHeight;
734: if (i == selectedIndex)
735: selectedRun = runCount - 1;
736: }
737: }
738: else
739: {
740: for (int i = 0; i < tabCount; i++)
741: {
742: rect = rects[i];
743: if (i > 0)
744: {
745: rect.y = rects[i - 1].y + rects[i - 1].height;
746: }
747: else
748: {
749: tabRuns[0] = 0;
750: runCount = 1;
751: maxTabHeight = 0;
752: rect.y = y;
753: }
754: rect.height = calculateTabHeight(tabPlacement, i,
755: fm.getHeight());
756: maxTabHeight = Math.max(maxTabHeight, rect.height);
757:
758: if (rect.y != 2 + insets.top && rect.y + rect.height > breakAt)
759: {
760: if (runCount > tabRuns.length - 1)
761: expandTabRunsArray();
762: tabRuns[runCount] = i;
763: runCount++;
764: rect.y = y;
765: }
766:
767: rect.x = x;
768: rect.width = maxTabWidth;
769:
770: if (i == selectedIndex)
771: selectedRun = runCount - 1;
772: }
773: }
774:
775: if (runCount > 1)
776: {
777: int start;
778: if (tabPlacement == SwingConstants.TOP
779: || tabPlacement == SwingConstants.BOTTOM)
780: start = x;
781: else
782: start = y;
783: normalizeTabRuns(tabPlacement, tabCount, start, breakAt);
784: selectedRun = getRunForTab(tabCount, selectedIndex);
785: if (shouldRotateTabRuns(tabPlacement))
786: {
787: rotateTabRuns(tabPlacement, selectedRun);
788: }
789: }
790:
791:
792: if (runCount == 1)
793: return;
794:
795:
796: int tabRunOverlay = getTabRunOverlay(tabPlacement);
797: for (int i = runCount - 1; i >= 0; --i)
798: {
799: int start = tabRuns[i];
800: int nextIndex;
801: if (i == runCount - 1)
802: nextIndex = 0;
803: else
804: nextIndex = i + 1;
805: int next = tabRuns[nextIndex];
806: int end = next != 0 ? next - 1 : tabCount - 1;
807: if (tabPlacement == SwingConstants.TOP
808: || tabPlacement == SwingConstants.BOTTOM)
809: {
810: for (int j = start; j <= end; ++j)
811: {
812: rect = rects[j];
813: rect.y = y;
814: rect.x += getTabRunIndent(tabPlacement, i);
815: }
816: if (shouldPadTabRun(tabPlacement, i))
817: {
818: padTabRun(tabPlacement, start, end, breakAt);
819: }
820: if (tabPlacement == BOTTOM)
821: y -= maxTabHeight - tabRunOverlay;
822: else
823: y += maxTabHeight - tabRunOverlay;
824: }
825: else
826: {
827: for (int j = start; j <= end; ++j)
828: {
829: rect = rects[j];
830: rect.x = x;
831: rect.y += getTabRunIndent(tabPlacement, i);
832: }
833: if (shouldPadTabRun(tabPlacement, i))
834: {
835: padTabRun(tabPlacement, start, end, breakAt);
836: }
837: if (tabPlacement == RIGHT)
838: x -= maxTabWidth - tabRunOverlay;
839: else
840: x += maxTabWidth - tabRunOverlay;
841:
842: }
843: }
844: padSelectedTab(tabPlacement, selectedIndex);
845: }
846:
847:
854: public void layoutContainer(Container