1. /*
  2. * @(#)WindowsInternalFrameTitlePane.java 1.12 03/01/23
  3. *
  4. * Copyright 2003 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 javax.swing.*;
  9. import javax.swing.border.*;
  10. import javax.swing.UIManager;
  11. import javax.swing.plaf.basic.BasicInternalFrameTitlePane;
  12. import java.awt.*;
  13. import java.awt.event.*;
  14. import java.beans.PropertyChangeEvent;
  15. import java.beans.PropertyChangeListener;
  16. public class WindowsInternalFrameTitlePane extends BasicInternalFrameTitlePane {
  17. private Color selectedTitleGradientColor;
  18. private Color notSelectedTitleGradientColor;
  19. private JPopupMenu systemPopupMenu;
  20. private JLabel systemLabel;
  21. private Font titleFont;
  22. private int shadowOffset;
  23. private Color shadowColor;
  24. public WindowsInternalFrameTitlePane(JInternalFrame f) {
  25. super(f);
  26. }
  27. protected void addSubComponents() {
  28. add(systemLabel);
  29. add(iconButton);
  30. add(maxButton);
  31. add(closeButton);
  32. }
  33. protected void installDefaults() {
  34. super.installDefaults();
  35. if (XPStyle.getXP() == null) {
  36. selectedTitleGradientColor =
  37. UIManager.getColor("InternalFrame.activeTitleGradient");
  38. notSelectedTitleGradientColor =
  39. UIManager.getColor("InternalFrame.inactiveTitleGradient");
  40. Color activeBorderColor =
  41. UIManager.getColor("InternalFrame.activeBorderColor");
  42. setBorder(BorderFactory.createLineBorder(activeBorderColor, 1));
  43. }
  44. }
  45. protected void createButtons() {
  46. super.createButtons();
  47. if (XPStyle.getXP() != null) {
  48. iconButton.setContentAreaFilled(false);
  49. maxButton.setContentAreaFilled(false);
  50. closeButton.setContentAreaFilled(false);
  51. }
  52. }
  53. public void paintComponent(Graphics g) {
  54. paintTitleBackground(g);
  55. String title = frame.getTitle();
  56. if (title != null) {
  57. boolean isSelected = frame.isSelected();
  58. Font oldFont = g.getFont();
  59. Font newFont = (titleFont != null) ? titleFont : getFont();
  60. g.setFont(newFont);
  61. // Center text vertically.
  62. FontMetrics fm = g.getFontMetrics();
  63. int baseline = (getHeight() + fm.getAscent() - fm.getLeading() -
  64. fm.getDescent()) / 2;
  65. int titleX;
  66. Rectangle r = new Rectangle(0, 0, 0, 0);
  67. if (frame.isIconifiable()) r = iconButton.getBounds();
  68. else if (frame.isMaximizable()) r = maxButton.getBounds();
  69. else if (frame.isClosable()) r = closeButton.getBounds();
  70. int titleW;
  71. if(WindowsGraphicsUtils.isLeftToRight(frame) ) {
  72. if (r.x == 0) r.x = frame.getWidth()-frame.getInsets().right;
  73. titleX = systemLabel.getX() + systemLabel.getWidth() + 2;
  74. titleW = r.x - titleX - 3;
  75. title = getTitle(frame.getTitle(), fm, titleW);
  76. } else {
  77. titleX = systemLabel.getX() - 2
  78. - SwingUtilities.computeStringWidth(fm,title);
  79. }
  80. if (shadowOffset != 0 && shadowColor != null) {
  81. g.setColor(shadowColor);
  82. g.drawString(title, titleX + shadowOffset, baseline + shadowOffset);
  83. }
  84. g.setColor(isSelected ? selectedTextColor : notSelectedTextColor);
  85. g.drawString(title, titleX, baseline);
  86. g.setFont(oldFont);
  87. }
  88. }
  89. public Dimension getPreferredSize() {
  90. return getMinimumSize();
  91. }
  92. public Dimension getMinimumSize() {
  93. Dimension d = super.getMinimumSize();
  94. XPStyle xp = XPStyle.getXP();
  95. if (xp != null) {
  96. // Note: Don't know how to calculate height on XP,
  97. // the captionbarheight is 25 but native caption is 30 (maximized 26)
  98. d.height = xp.getInt("sysmetrics.captionbarheight", d.height);
  99. if (frame.isMaximum()) {
  100. d.height += 1;
  101. } else {
  102. d.height += 5;
  103. }
  104. }
  105. return d;
  106. }
  107. protected void paintTitleBackground(Graphics g) {
  108. XPStyle xp = XPStyle.getXP();
  109. if (xp != null) {
  110. XPStyle.Skin skin = xp.getSkin(frame.isIcon() ? "window.mincaption"
  111. : (frame.isMaximum() ? "window.maxcaption"
  112. : "window.caption"));
  113. skin.paintSkin(g, 0, 0, getSize().width, getSize().height, frame.isSelected() ? 0 : 1);
  114. } else {
  115. Boolean gradientsOn = (Boolean)LookAndFeel.getDesktopPropertyValue(
  116. "win.frame.captionGradientsOn", Boolean.valueOf(false));
  117. if (gradientsOn.booleanValue() && g instanceof Graphics2D) {
  118. Graphics2D g2 = (Graphics2D)g;
  119. Paint savePaint = g2.getPaint();
  120. boolean isSelected = frame.isSelected();
  121. int w = getWidth();
  122. if (isSelected) {
  123. GradientPaint titleGradient = new GradientPaint(0,0,
  124. selectedTitleColor,
  125. (int)(w*.75),0,
  126. selectedTitleGradientColor);
  127. g2.setPaint(titleGradient);
  128. } else {
  129. GradientPaint titleGradient = new GradientPaint(0,0,
  130. notSelectedTitleColor,
  131. (int)(w*.75),0,
  132. notSelectedTitleGradientColor);
  133. g2.setPaint(titleGradient);
  134. }
  135. g2.fillRect(0, 0, getWidth(), getHeight());
  136. g2.setPaint(savePaint);
  137. } else {
  138. super.paintTitleBackground(g);
  139. }
  140. }
  141. }
  142. protected void assembleSystemMenu() {
  143. systemPopupMenu = new JPopupMenu();
  144. addSystemMenuItems(systemPopupMenu);
  145. enableActions();
  146. systemLabel = new JLabel(frame.getFrameIcon());
  147. systemLabel.addMouseListener(new MouseAdapter() {
  148. public void mousePressed(MouseEvent e) {
  149. showSystemPopupMenu(e.getComponent());
  150. }
  151. });
  152. }
  153. protected void addSystemMenuItems(JPopupMenu menu) {
  154. JMenuItem mi = (JMenuItem)menu.add(restoreAction);
  155. mi.setMnemonic('R');
  156. mi = (JMenuItem)menu.add(moveAction);
  157. mi.setMnemonic('M');
  158. mi = (JMenuItem)menu.add(sizeAction);
  159. mi.setMnemonic('S');
  160. mi = (JMenuItem)menu.add(iconifyAction);
  161. mi.setMnemonic('n');
  162. mi = (JMenuItem)menu.add(maximizeAction);
  163. mi.setMnemonic('x');
  164. systemPopupMenu.add(new JSeparator());
  165. mi = (JMenuItem)menu.add(closeAction);
  166. mi.setMnemonic('C');
  167. }
  168. protected void showSystemMenu(){
  169. showSystemPopupMenu(systemLabel);
  170. }
  171. private void showSystemPopupMenu(Component invoker){
  172. Dimension dim = new Dimension();
  173. Border border = frame.getBorder();
  174. if (border != null) {
  175. dim.width += border.getBorderInsets(frame).left +
  176. border.getBorderInsets(frame).right;
  177. dim.height += border.getBorderInsets(frame).bottom +
  178. border.getBorderInsets(frame).top;
  179. }
  180. if (!frame.isIcon()) {
  181. systemPopupMenu.show(invoker,
  182. getX() - dim.width,
  183. getY() + getHeight() - dim.height);
  184. } else {
  185. systemPopupMenu.show(invoker,
  186. getX() - dim.width,
  187. getY() - systemPopupMenu.getPreferredSize().height -
  188. dim.height);
  189. }
  190. }
  191. protected PropertyChangeListener createPropertyChangeListener() {
  192. return new WindowsPropertyChangeHandler();
  193. }
  194. protected LayoutManager createLayout() {
  195. return new WindowsTitlePaneLayout();
  196. }
  197. public class WindowsTitlePaneLayout extends BasicInternalFrameTitlePane.TitlePaneLayout {
  198. private Insets captionMargin = null;
  199. private Insets contentMargin = null;
  200. private XPStyle xp = XPStyle.getXP();
  201. WindowsTitlePaneLayout() {
  202. if (xp != null) {
  203. captionMargin = xp.getMargin("window.caption.captionmargins");
  204. contentMargin = xp.getMargin("window.caption.contentmargins");
  205. }
  206. if (captionMargin == null) {
  207. captionMargin = new Insets(0, 2, 0, 2);
  208. }
  209. if (contentMargin == null) {
  210. contentMargin = new Insets(0, 0, 0, 0);
  211. }
  212. }
  213. private int layoutButton(JComponent button, String category,
  214. int x, int y, int w, int h, boolean leftToRight) {
  215. if (xp != null) {
  216. // Ignore offset parameters, because Windows does, and some third party
  217. // themes have bad values for them.
  218. XPStyle.Skin skin = xp.getSkin(category);
  219. if (skin.getImage() != null) {
  220. w = skin.getWidth();
  221. h = skin.getHeight();
  222. }
  223. }
  224. if (!leftToRight) {
  225. x -= w;
  226. }
  227. button.setBounds(x, y, w, h);
  228. if (leftToRight) {
  229. x += w + 2;
  230. } else {
  231. x -= 2;
  232. }
  233. return x;
  234. }
  235. public void layoutContainer(Container c) {
  236. boolean leftToRight = WindowsGraphicsUtils.isLeftToRight(frame);
  237. int x, y;
  238. int w = getWidth();
  239. int h = getHeight();
  240. // System button
  241. Icon icon = frame.getFrameIcon();
  242. int iconHeight = (icon != null) ? icon.getIconHeight() : 0;
  243. x = (leftToRight) ? captionMargin.left : w - captionMargin.right;
  244. y = (h - iconHeight) / 2 + 1;
  245. layoutButton(systemLabel, "window.sysbutton", x, y, 16, 16, leftToRight);
  246. // Right hand buttons
  247. if (xp != null) {
  248. x = (leftToRight) ? w - captionMargin.right - 2 : captionMargin.left + 2;
  249. y = contentMargin.top + captionMargin.top;
  250. if (frame.isMaximum()) {
  251. y += 1;
  252. } else {
  253. y += 5;
  254. }
  255. } else {
  256. x = (leftToRight) ? w - captionMargin.right : captionMargin.left;
  257. // The +1 is due to the way the line border is drawn and modifies
  258. // the look of the title pane.
  259. y = (h - 16) / 2 + 1;
  260. }
  261. if(frame.isClosable()) {
  262. x = layoutButton(closeButton, "window.closebutton", x, y, 16, 14, !leftToRight);
  263. }
  264. if(frame.isMaximizable()) {
  265. x = layoutButton(maxButton, "window.maxbutton", x, y, 16, 14, !leftToRight);
  266. }
  267. if(frame.isIconifiable()) {
  268. layoutButton(iconButton, "window.minbutton", x, y, 16, 14, !leftToRight);
  269. }
  270. }
  271. } // end WindowsTitlePaneLayout
  272. public class WindowsPropertyChangeHandler extends PropertyChangeHandler {
  273. public void propertyChange(PropertyChangeEvent evt) {
  274. String prop = (String)evt.getPropertyName();
  275. // Update the internal frame icon for the system menu.
  276. if (JInternalFrame.FRAME_ICON_PROPERTY.equals(prop) &&
  277. systemLabel != null) {
  278. systemLabel.setIcon(frame.getFrameIcon());
  279. }
  280. super.propertyChange(evt);
  281. }
  282. }
  283. }