1. /*
  2. * @(#)WindowsTabbedPaneUI.java 1.16 03/12/19
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package com.sun.java.swing.plaf.windows;
  8. import java.awt.*;
  9. import javax.swing.plaf.basic.*;
  10. import javax.swing.plaf.*;
  11. import javax.swing.*;
  12. import java.util.Set;
  13. import java.util.TreeSet;
  14. import java.awt.event.*;
  15. /**
  16. * Windows rendition of the component.
  17. * <p>
  18. * <strong>Warning:</strong>
  19. * Serialized objects of this class will not be compatible with
  20. * future Swing releases. The current serialization support is appropriate
  21. * for short term storage or RMI between applications running the same
  22. * version of Swing. A future release of Swing will provide support for
  23. * long term persistence.
  24. */
  25. public class WindowsTabbedPaneUI extends BasicTabbedPaneUI {
  26. /**
  27. * Keys to use for forward focus traversal when the JComponent is
  28. * managing focus.
  29. */
  30. private static Set managingFocusForwardTraversalKeys;
  31. /**
  32. * Keys to use for backward focus traversal when the JComponent is
  33. * managing focus.
  34. */
  35. private static Set managingFocusBackwardTraversalKeys;
  36. private boolean contentOpaque = true;
  37. protected void installDefaults() {
  38. super.installDefaults();
  39. contentOpaque = UIManager.getBoolean("TabbedPane.contentOpaque");
  40. // focus forward traversal key
  41. if (managingFocusForwardTraversalKeys==null) {
  42. managingFocusForwardTraversalKeys = new TreeSet();
  43. managingFocusForwardTraversalKeys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));
  44. }
  45. tabPane.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, managingFocusForwardTraversalKeys);
  46. // focus backward traversal key
  47. if (managingFocusBackwardTraversalKeys==null) {
  48. managingFocusBackwardTraversalKeys = new TreeSet();
  49. managingFocusBackwardTraversalKeys.add( KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_MASK));
  50. }
  51. tabPane.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, managingFocusBackwardTraversalKeys);
  52. }
  53. protected void uninstallDefaults() {
  54. // sets the focus forward and backward traversal keys to null
  55. // to restore the defaults
  56. tabPane.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, null);
  57. tabPane.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, null);
  58. super.uninstallDefaults();
  59. }
  60. public static ComponentUI createUI(JComponent c) {
  61. return new WindowsTabbedPaneUI();
  62. }
  63. protected void setRolloverTab(int index) {
  64. // Rollover is only supported on XP
  65. if (XPStyle.getXP() != null) {
  66. int oldRolloverTab = getRolloverTab();
  67. super.setRolloverTab(index);
  68. Rectangle r1 = null;
  69. Rectangle r2 = null;
  70. if (oldRolloverTab >= 0) {
  71. r1 = getTabBounds(tabPane, oldRolloverTab);
  72. }
  73. if (index >= 0) {
  74. r2 = getTabBounds(tabPane, index);
  75. }
  76. if (r1 != null) {
  77. if (r2 != null) {
  78. tabPane.repaint(r1.union(r2));
  79. } else {
  80. tabPane.repaint(r1);
  81. }
  82. } else if (r2 != null) {
  83. tabPane.repaint(r2);
  84. }
  85. }
  86. }
  87. protected void paintContentBorder(Graphics g, int tabPlacement, int selectedIndex) {
  88. XPStyle xp = XPStyle.getXP();
  89. if (xp != null && (contentOpaque || tabPane.isOpaque())) {
  90. XPStyle.Skin skin = xp.getSkin("tab.pane");
  91. if (skin != null) {
  92. Insets insets = tabPane.getInsets();
  93. // Note: don't call getTabAreaInsets(), because it causes rotation.
  94. // Make sure "TabbedPane.tabsOverlapBorder" is set to true in WindowsLookAndFeel
  95. Insets tabAreaInsets = UIManager.getInsets("TabbedPane.tabAreaInsets");
  96. int x = insets.left;
  97. int y = insets.top;
  98. int w = tabPane.getWidth() - insets.right - insets.left;
  99. int h = tabPane.getHeight() - insets.top - insets.bottom;
  100. // Expand area by tabAreaInsets.bottom to allow tabs to overlap onto the border.
  101. if (tabPlacement == LEFT || tabPlacement == RIGHT) {
  102. int tabWidth = calculateTabAreaWidth(tabPlacement, runCount, maxTabWidth);
  103. if (tabPlacement == LEFT) {
  104. x += (tabWidth - tabAreaInsets.bottom);
  105. }
  106. w -= (tabWidth - tabAreaInsets.bottom);
  107. } else {
  108. int tabHeight = calculateTabAreaHeight(tabPlacement, runCount, maxTabHeight);
  109. if (tabPlacement == TOP) {
  110. y += (tabHeight - tabAreaInsets.bottom);
  111. }
  112. h -= (tabHeight - tabAreaInsets.bottom);
  113. }
  114. Color borderColor = xp.getColor("tab.pane.bordercolorhint", null);
  115. if (borderColor != null) {
  116. g.setColor(borderColor);
  117. g.fillRect(x, y, w, h);
  118. }
  119. paintRotatedSkin(g, skin, tabPlacement, x, y, w, h, 0);
  120. return;
  121. }
  122. }
  123. super.paintContentBorder(g, tabPlacement, selectedIndex);
  124. }
  125. protected void paintTabBackground(Graphics g, int tabPlacement, int tabIndex,
  126. int x, int y, int w, int h, boolean isSelected ) {
  127. if (XPStyle.getXP() == null) {
  128. super.paintTabBackground(g, tabPlacement, tabIndex, x, y, w, h, isSelected);
  129. }
  130. }
  131. protected void paintTabBorder(Graphics g, int tabPlacement, int tabIndex,
  132. int x, int y, int w, int h, boolean isSelected ) {
  133. XPStyle xp = XPStyle.getXP();
  134. if (xp != null) {
  135. String category;
  136. int tabCount = tabPane.getTabCount();
  137. int tabRun = getRunForTab(tabCount, tabIndex);
  138. if (tabRuns[tabRun] == tabIndex) {
  139. category = "tab.tabitemleftedge";
  140. } else if (tabCount > 1 && lastTabInRun(tabCount, tabRun) == tabIndex) {
  141. category = "tab.tabitemrightedge";
  142. if (isSelected) {
  143. // Align with right edge
  144. if (tabPlacement == TOP || tabPlacement == BOTTOM) {
  145. w++;
  146. } else {
  147. h++;
  148. }
  149. }
  150. } else {
  151. category = "tab.tabitem";
  152. }
  153. int index = 0;
  154. if (isSelected) {
  155. index = 2;
  156. } else if (tabIndex == getRolloverTab()) {
  157. index = 1;
  158. }
  159. paintRotatedSkin(g, xp.getSkin(category), tabPlacement, x, y, w, h, index);
  160. } else {
  161. super.paintTabBorder(g, tabPlacement, tabIndex, x, y, w, h, isSelected);
  162. }
  163. }
  164. private void paintRotatedSkin(Graphics g, XPStyle.Skin skin, int tabPlacement,
  165. int x, int y, int w, int h, int index) {
  166. Graphics2D g2d = (Graphics2D)g.create();
  167. g2d.translate(x, y);
  168. switch (tabPlacement) {
  169. case RIGHT: g2d.translate(w, 0);
  170. g2d.rotate(Math.toRadians(90.0));
  171. skin.paintSkin(g2d, 0, 0, h, w, index);
  172. break;
  173. case LEFT: g2d.scale(-1.0, 1.0);
  174. g2d.rotate(Math.toRadians(90.0));
  175. skin.paintSkin(g2d, 0, 0, h, w, index);
  176. break;
  177. case BOTTOM: g2d.translate(0, h);
  178. g2d.scale(-1.0, 1.0);
  179. g2d.rotate(Math.toRadians(180.0));
  180. skin.paintSkin(g2d, 0, 0, w, h, index);
  181. break;
  182. case TOP:
  183. default: skin.paintSkin(g2d, 0, 0, w, h, index);
  184. }
  185. g2d.dispose();
  186. }
  187. }