1. /*
  2. * @(#)MetalInternalFrameTitlePane.java 1.39 01/02/09
  3. *
  4. * Copyright 1998-2001 Sun Microsystems, Inc. All Rights Reserved.
  5. *
  6. * This software is the proprietary information of Sun Microsystems, Inc.
  7. * Use is subject to license terms.
  8. *
  9. */
  10. package javax.swing.plaf.metal;
  11. import java.awt.*;
  12. import java.awt.event.*;
  13. import javax.swing.*;
  14. import javax.swing.border.*;
  15. import javax.swing.event.InternalFrameEvent;
  16. import java.util.EventListener;
  17. import java.beans.PropertyChangeListener;
  18. import java.beans.PropertyChangeEvent;
  19. import javax.swing.plaf.basic.BasicInternalFrameTitlePane;
  20. /**
  21. * Class that manages a JLF title bar
  22. * @version 1.39 02/09/01
  23. * @author Steve Wilson
  24. * @author Brian Beck
  25. * @since 1.3
  26. */
  27. public class MetalInternalFrameTitlePane extends BasicInternalFrameTitlePane {
  28. protected boolean isPalette = false;
  29. protected Icon paletteCloseIcon;
  30. protected int paletteTitleHeight;
  31. private static final Border handyEmptyBorder = new EmptyBorder(0,0,0,0);
  32. int buttonsWidth = 0;
  33. MetalBumps activeBumps
  34. = new MetalBumps( 0, 0,
  35. MetalLookAndFeel.getPrimaryControlHighlight(),
  36. MetalLookAndFeel.getPrimaryControlDarkShadow(),
  37. MetalLookAndFeel.getPrimaryControl() );
  38. MetalBumps inactiveBumps
  39. = new MetalBumps( 0, 0,
  40. MetalLookAndFeel.getControlHighlight(),
  41. MetalLookAndFeel.getControlDarkShadow(),
  42. MetalLookAndFeel.getControl() );
  43. MetalBumps paletteBumps;
  44. public MetalInternalFrameTitlePane(JInternalFrame f) {
  45. super( f );
  46. }
  47. protected void installDefaults() {
  48. super.installDefaults();
  49. setFont( UIManager.getFont("InternalFrame.font") );
  50. paletteTitleHeight
  51. = UIManager.getInt("InternalFrame.paletteTitleHeight");
  52. paletteCloseIcon = UIManager.getIcon("InternalFrame.paletteCloseIcon");
  53. }
  54. protected void createButtons() {
  55. super.createButtons();
  56. Boolean paintActive = frame.isSelected() ? Boolean.TRUE:Boolean.FALSE;
  57. iconButton.putClientProperty("paintActive", paintActive);
  58. iconButton.setBorder(handyEmptyBorder);
  59. iconButton.getAccessibleContext().setAccessibleName(
  60. UIManager.getString(
  61. "InternalFrameTitlePane.iconifyButtonAccessibleName"));
  62. maxButton.putClientProperty("paintActive", paintActive);
  63. maxButton.setBorder(handyEmptyBorder);
  64. maxButton.getAccessibleContext().setAccessibleName(
  65. UIManager.getString(
  66. "InternalFrameTitlePane.maximizeButtonAccessibleName"));
  67. closeButton.putClientProperty("paintActive", paintActive);
  68. closeButton.setBorder(handyEmptyBorder);
  69. closeButton.getAccessibleContext().setAccessibleName(
  70. UIManager.getString(
  71. "InternalFrameTitlePane.closeButtonAccessibleName"));
  72. // The palette close icon isn't opaque while the regular close icon is.
  73. // This makes sure palette close buttons have the right background.
  74. closeButton.setBackground(MetalLookAndFeel.getPrimaryControlShadow());
  75. }
  76. /**
  77. * Override the parent's method to do nothing. Metal frames do not
  78. * have system menus.
  79. */
  80. protected void assembleSystemMenu() {}
  81. /**
  82. * Override the parent's method to do nothing. Metal frames do not
  83. * have system menus.
  84. */
  85. protected void addSystemMenuItems(JMenu systemMenu) {}
  86. /**
  87. * Override the parent's method avoid creating a menu bar. Metal frames
  88. * do not have system menus.
  89. */
  90. protected void addSubComponents() {
  91. add(iconButton);
  92. add(maxButton);
  93. add(closeButton);
  94. }
  95. protected PropertyChangeListener createPropertyChangeListener() {
  96. return new MetalPropertyChangeHandler();
  97. }
  98. protected LayoutManager createLayout() {
  99. return new MetalTitlePaneLayout();
  100. }
  101. /*
  102. * These accessors allow our inner classes to get at member variables
  103. * they couldn't otherwise access. This work's around a javac bug.
  104. */
  105. private JInternalFrame getFrame() { return frame; }
  106. private JButton getIconButton() { return iconButton; }
  107. private JButton getCloseButton() { return closeButton; }
  108. private JButton getMaxButton() { return maxButton; }
  109. class MetalPropertyChangeHandler
  110. extends BasicInternalFrameTitlePane.PropertyChangeHandler
  111. {
  112. public void propertyChange(PropertyChangeEvent evt) {
  113. String prop = (String)evt.getPropertyName();
  114. if( prop.equals(JInternalFrame.IS_SELECTED_PROPERTY) ) {
  115. Boolean b = (Boolean)evt.getNewValue();
  116. getIconButton().putClientProperty("paintActive", b);
  117. getCloseButton().putClientProperty("paintActive", b);
  118. getMaxButton().putClientProperty("paintActive", b);
  119. repaint();
  120. }
  121. super.propertyChange(evt);
  122. }
  123. }
  124. class MetalTitlePaneLayout implements LayoutManager {
  125. public void addLayoutComponent(String name, Component c) {}
  126. public void removeLayoutComponent(Component c) {}
  127. public Dimension preferredLayoutSize(Container c) {
  128. return getPreferredSize(c);
  129. }
  130. public Dimension getPreferredSize(Container c) {
  131. return new Dimension(c.getSize().width, computeHeight());
  132. }
  133. public Dimension minimumLayoutSize(Container c) {
  134. return preferredLayoutSize(c);
  135. }
  136. protected int computeHeight() {
  137. if ( isPalette ) {
  138. return paletteTitleHeight;
  139. }
  140. FontMetrics fm
  141. = Toolkit.getDefaultToolkit().getFontMetrics(getFont());
  142. int fontHeight = fm.getHeight();
  143. fontHeight += 7;
  144. Icon icon = getFrame().getFrameIcon();
  145. int iconHeight = 0;
  146. if (icon != null) iconHeight = icon.getIconHeight();
  147. iconHeight += 5;
  148. int finalHeight = Math.max( fontHeight, iconHeight );
  149. return finalHeight;
  150. }
  151. public void layoutContainer(Container c) {
  152. JInternalFrame frame = getFrame();
  153. boolean leftToRight = MetalUtils.isLeftToRight(frame);
  154. int w = getWidth();
  155. int x = leftToRight ? w : 0;
  156. int y = 2;
  157. int spacing;
  158. // assumes all buttons have the same dimensions
  159. // these dimensions include the borders
  160. JButton closeButton = getCloseButton();
  161. int buttonHeight = closeButton.getIcon().getIconHeight();
  162. int buttonWidth = closeButton.getIcon().getIconWidth();
  163. if(frame.isClosable()) {
  164. if (isPalette) {
  165. spacing = 3;
  166. x += leftToRight ? -spacing -(buttonWidth+2) : spacing;
  167. closeButton.setBounds(x, y, buttonWidth+2, getHeight()-4);
  168. if( !leftToRight ) x += (buttonWidth+2);
  169. } else {
  170. spacing = 4;
  171. x += leftToRight ? -spacing -buttonWidth : spacing;
  172. closeButton.setBounds(x, y, buttonWidth, buttonHeight);
  173. if( !leftToRight ) x += buttonWidth;
  174. }
  175. }
  176. if(frame.isMaximizable() && !isPalette ) {
  177. JButton maxButton = getMaxButton();
  178. spacing = frame.isClosable() ? 10 : 4;
  179. x += leftToRight ? -spacing -buttonWidth : spacing;
  180. maxButton.setBounds(x, y, buttonWidth, buttonHeight);
  181. if( !leftToRight ) x += buttonWidth;
  182. }
  183. if(frame.isIconifiable() && !isPalette ) {
  184. JButton iconButton = getIconButton();
  185. spacing = frame.isMaximizable() ? 2
  186. : (frame.isClosable() ? 10 : 4);
  187. x += leftToRight ? -spacing -buttonWidth : spacing;
  188. iconButton.setBounds(x, y, buttonWidth, buttonHeight);
  189. if( !leftToRight ) x += buttonWidth;
  190. }
  191. buttonsWidth = leftToRight ? w - x : x;
  192. }
  193. }
  194. public void paintPalette(Graphics g) {
  195. boolean leftToRight = MetalUtils.isLeftToRight(frame);
  196. int width = getWidth();
  197. int height = getHeight();
  198. if (paletteBumps == null) {
  199. paletteBumps
  200. = new MetalBumps(0, 0,
  201. MetalLookAndFeel.getPrimaryControlHighlight(),
  202. MetalLookAndFeel.getPrimaryControlInfo(),
  203. MetalLookAndFeel.getPrimaryControlShadow() );
  204. }
  205. Color background = MetalLookAndFeel.getPrimaryControlShadow();
  206. Color darkShadow = MetalLookAndFeel.getPrimaryControlDarkShadow();
  207. g.setColor(background);
  208. g.fillRect(0, 0, width, height);
  209. g.setColor( darkShadow );
  210. g.drawLine ( 0, height - 1, width, height -1);
  211. int xOffset = leftToRight ? 4 : buttonsWidth + 4;
  212. int bumpLength = width - buttonsWidth -2*4;
  213. int bumpHeight = getHeight() - 4;
  214. paletteBumps.setBumpArea( bumpLength, bumpHeight );
  215. paletteBumps.paintIcon( this, g, xOffset, 2);
  216. }
  217. public void paintComponent(Graphics g) {
  218. if(isPalette) {
  219. paintPalette(g);
  220. return;
  221. }
  222. boolean leftToRight = MetalUtils.isLeftToRight(frame);
  223. boolean isSelected = frame.isSelected();
  224. int width = getWidth();
  225. int height = getHeight();
  226. Color background;
  227. Color foreground;
  228. Color darkShadow;
  229. MetalBumps bumps;
  230. if (isSelected) {
  231. background = MetalLookAndFeel.getWindowTitleBackground();
  232. foreground = MetalLookAndFeel.getWindowTitleForeground();
  233. darkShadow = MetalLookAndFeel.getPrimaryControlDarkShadow();
  234. bumps = activeBumps;
  235. } else {
  236. background = MetalLookAndFeel.getWindowTitleInactiveBackground();
  237. foreground = MetalLookAndFeel.getWindowTitleInactiveForeground();
  238. darkShadow = MetalLookAndFeel.getControlDarkShadow();
  239. bumps = inactiveBumps;
  240. }
  241. g.setColor(background);
  242. g.fillRect(0, 0, width, height);
  243. g.setColor( darkShadow );
  244. g.drawLine ( 0, height - 1, width, height -1);
  245. g.drawLine ( 0, 0, 0 ,0);
  246. g.drawLine ( width - 1, 0 , width -1, 0);
  247. int titleLength = 0;
  248. int xOffset = leftToRight ? 5 : width - 5;
  249. String frameTitle = frame.getTitle();
  250. Icon icon = frame.getFrameIcon();
  251. if ( icon != null ) {
  252. if( !leftToRight )
  253. xOffset -= icon.getIconWidth();
  254. int iconY = ((height / 2) - (icon.getIconHeight() /2));
  255. icon.paintIcon(frame, g, xOffset, iconY);
  256. xOffset += leftToRight ? icon.getIconWidth() + 5 : -5;
  257. }
  258. if(frameTitle != null) {
  259. Font f = getFont();
  260. g.setFont(f);
  261. FontMetrics fm = g.getFontMetrics();
  262. int fHeight = fm.getHeight();
  263. titleLength = fm.stringWidth(frameTitle);
  264. g.setColor(foreground);
  265. int yOffset = ( (height - fm.getHeight() ) / 2 ) + fm.getAscent();
  266. if( !leftToRight )
  267. xOffset -= titleLength;
  268. g.drawString( frameTitle, xOffset, yOffset );
  269. xOffset += leftToRight ? titleLength + 5 : -5;
  270. }
  271. int bumpXOffset;
  272. int bumpLength;
  273. if( leftToRight ) {
  274. bumpLength = width - buttonsWidth - xOffset -5;
  275. bumpXOffset = xOffset;
  276. } else {
  277. bumpLength = xOffset - buttonsWidth - 5;
  278. bumpXOffset = buttonsWidth + 5;
  279. }
  280. int bumpYOffset = 3;
  281. int bumpHeight = getHeight() - (2 * bumpYOffset);
  282. bumps.setBumpArea( bumpLength, bumpHeight );
  283. bumps.paintIcon(this, g, bumpXOffset, bumpYOffset);
  284. }
  285. public void setPalette(boolean b) {
  286. isPalette = b;
  287. if (isPalette) {
  288. closeButton.setIcon(paletteCloseIcon);
  289. if( frame.isMaximizable() )
  290. remove(maxButton);
  291. if( frame.isIconifiable() )
  292. remove(iconButton);
  293. } else {
  294. closeButton.setIcon(closeIcon);
  295. if( frame.isMaximizable() )
  296. add(maxButton);
  297. if( frame.isIconifiable() )
  298. add(iconButton);
  299. }
  300. revalidate();
  301. repaint();
  302. }
  303. }