1. /*
  2. * @(#)MetalInternalFrameTitlePane.java 1.28 01/11/29
  3. *
  4. * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package javax.swing.plaf.metal;
  8. import java.awt.*;
  9. import java.awt.event.*;
  10. import javax.swing.*;
  11. import javax.swing.border.*;
  12. import javax.swing.event.InternalFrameEvent;
  13. import java.util.EventListener;
  14. import java.beans.PropertyChangeListener;
  15. import java.beans.PropertyChangeEvent;
  16. import java.beans.VetoableChangeListener;
  17. import java.beans.PropertyVetoException;
  18. /**
  19. * Package private class that manages a JLF title bar
  20. * @version 1.28 11/29/01
  21. * @author Steve Wilson
  22. */
  23. // Could not extend BasicInternalFrameTitlePane because it's private
  24. class MetalInternalFrameTitlePane extends JComponent
  25. implements LayoutManager,
  26. ActionListener,
  27. PropertyChangeListener {
  28. protected JMenuBar menuBar;
  29. protected boolean isPalette = false;
  30. JInternalFrame frame;
  31. // the three control buttons
  32. protected JButton iconButton;
  33. protected JButton maxButton;
  34. protected JButton closeButton;
  35. private static final Border handyEmptyBorder = new EmptyBorder(0,0,0,0);
  36. // the pictures/icons in these three buttons
  37. Icon maxIcon;
  38. Icon altMaxIcon;
  39. Icon iconIcon;
  40. Icon closeIcon;
  41. int riseWidth = 0;
  42. int interButtonSpacing = 2;
  43. MetalBumps activeBumps = new MetalBumps( 0, 0,
  44. MetalLookAndFeel.getPrimaryControlHighlight(),
  45. MetalLookAndFeel.getPrimaryControlDarkShadow(),
  46. MetalLookAndFeel.getPrimaryControl() );
  47. MetalBumps inactiveBumps = new MetalBumps( 0, 0,
  48. MetalLookAndFeel.getControlHighlight(),
  49. MetalLookAndFeel.getControlDarkShadow(),
  50. MetalLookAndFeel.getControl() );
  51. MetalBumps paletteBumps;
  52. public MetalInternalFrameTitlePane(JInternalFrame f) {
  53. frame = f;
  54. setFont( UIManager.getFont("InternalFrame.font") );
  55. maxIcon = (Icon)UIManager.get("InternalFrame.maximizeIcon");
  56. altMaxIcon = (Icon)UIManager.get("InternalFrame.minimizeIcon");
  57. iconIcon = (Icon)UIManager.get("InternalFrame.iconizeIcon");
  58. closeIcon = (Icon)UIManager.get("InternalFrame.closeIcon");
  59. /* menuBar = new JMenuBar(){
  60. public boolean isFocusTraversable() { return false; }
  61. public void requestFocus() {}
  62. // PENDING(klobad) Should be able to configure Menu + Button instead
  63. public void paint(Graphics g) {}
  64. public boolean isOpaque() { return false; }
  65. };
  66. menuBar.setBorderPainted(false);*/
  67. iconButton = new NoFocusButton( iconIcon );
  68. iconButton.putClientProperty("paintActive", Boolean.TRUE);
  69. iconButton.setFocusPainted(false);
  70. iconButton.setBorder(handyEmptyBorder);
  71. iconButton.setOpaque(false);
  72. iconButton.addActionListener(this);
  73. iconButton.setActionCommand("Iconify");
  74. iconButton.getAccessibleContext().setAccessibleName("Iconify");
  75. maxButton = new NoFocusButton( maxIcon );
  76. maxButton.putClientProperty("paintActive", Boolean.TRUE);
  77. maxButton.setBorder(handyEmptyBorder);
  78. maxButton.setOpaque(false);
  79. maxButton.setFocusPainted(false);
  80. maxButton.addActionListener(this);
  81. maxButton.setActionCommand("Maximize");
  82. maxButton.getAccessibleContext().setAccessibleName("Maximize");
  83. closeButton = new NoFocusButton( closeIcon );
  84. closeButton.putClientProperty("paintActive", Boolean.TRUE);
  85. closeButton.setBorder(handyEmptyBorder);
  86. closeButton.setOpaque(false);
  87. closeButton.setFocusPainted(false);
  88. closeButton.addActionListener(this);
  89. closeButton.setActionCommand("Close");
  90. closeButton.getAccessibleContext().setAccessibleName("Close");
  91. setLayout(this);
  92. // add(menuBar);
  93. add(iconButton);
  94. add(maxButton);
  95. add(closeButton);
  96. // Make sure these are ok to leave on?
  97. frame.addPropertyChangeListener(this);
  98. }
  99. public void paintPalette(Graphics g) {
  100. int width = getWidth();
  101. int height = getHeight();
  102. Color background;
  103. Color foreground;
  104. Color shadow;
  105. Color darkShadow;
  106. Color highlight;
  107. Color black;
  108. if (paletteBumps == null) {
  109. paletteBumps = new MetalBumps( 0, 0,
  110. MetalLookAndFeel.getPrimaryControlHighlight(),
  111. MetalLookAndFeel.getPrimaryControlInfo(),
  112. MetalLookAndFeel.getPrimaryControlShadow() );
  113. }
  114. background = MetalLookAndFeel.getPrimaryControlShadow();
  115. darkShadow = MetalLookAndFeel.getPrimaryControlDarkShadow();
  116. g.setColor(background);
  117. g.fillRect(0, 0, width, height);
  118. g.setColor( darkShadow );
  119. g.drawLine ( 0, height - 1, width, height -1);
  120. int xOffset = 5;
  121. int bumpLength = getWidth() - (xOffset + riseWidth + 2 );
  122. int bumpHeight = getHeight() - 4;
  123. paletteBumps.setBumpArea( bumpLength, bumpHeight );
  124. paletteBumps.paintIcon( this, g, xOffset, 2);
  125. paintChildren(g);
  126. }
  127. public void paint(Graphics g) {
  128. if(isPalette) {
  129. paintPalette(g);
  130. return;
  131. }
  132. boolean isSelected = frame.isSelected();
  133. int width = getWidth();
  134. int height = getHeight();
  135. Color background;
  136. Color foreground;
  137. Color shadow;
  138. Color darkShadow;
  139. Color highlight;
  140. Color black;
  141. MetalBumps bumps;
  142. if (isSelected) {
  143. background = MetalLookAndFeel.getWindowTitleBackground();
  144. foreground = MetalLookAndFeel.getWindowTitleForeground();
  145. shadow = MetalLookAndFeel.getPrimaryControlShadow();
  146. darkShadow = MetalLookAndFeel.getPrimaryControlDarkShadow();
  147. highlight = MetalLookAndFeel.getPrimaryControlHighlight();
  148. black = MetalLookAndFeel.getPrimaryControlInfo();
  149. bumps = activeBumps;
  150. } else {
  151. background = MetalLookAndFeel.getWindowTitleInactiveBackground();
  152. foreground = MetalLookAndFeel.getWindowTitleInactiveForeground();
  153. shadow = MetalLookAndFeel.getControlShadow();
  154. darkShadow = MetalLookAndFeel.getControlDarkShadow();
  155. highlight = MetalLookAndFeel.getControlHighlight();
  156. black = MetalLookAndFeel.getControlInfo();
  157. bumps = inactiveBumps;
  158. }
  159. Color fillColor = darkShadow;
  160. g.setColor(background);
  161. g.fillRect(0, 0, width, height);
  162. g.setColor( darkShadow );
  163. g.drawLine ( 0, height - 1, width, height -1);
  164. g.drawLine ( 0, 0, 0 ,0);
  165. g.drawLine ( width - 1, 0 , width -1, 0);
  166. int titleLength = 0;
  167. int xOffset = 5;
  168. String frameTitle = frame.getTitle();
  169. Icon icon = frame.getFrameIcon();
  170. if ( icon != null ) {
  171. int iconY = ((height / 2) - (icon.getIconHeight() /2));
  172. icon.paintIcon(frame, g, xOffset, iconY);
  173. xOffset += icon.getIconWidth()+2;
  174. }
  175. if(frameTitle != null) {
  176. Font f = getFont();
  177. g.setFont(f);
  178. FontMetrics fm = g.getFontMetrics();
  179. int fHeight = fm.getHeight();
  180. titleLength = fm.stringWidth(frame.getTitle());
  181. g.setColor(foreground);
  182. int yOffset = ( (height - fm.getHeight() ) / 2 ) + fm.getAscent();
  183. g.drawString(frame.getTitle(),
  184. xOffset,
  185. yOffset );
  186. }
  187. int bumpYOffset = 3;
  188. xOffset += titleLength + interButtonSpacing;
  189. int bumpLength = getWidth() - (xOffset + riseWidth + interButtonSpacing + 5 );
  190. int bumpHeight = getHeight() - (2 * bumpYOffset);
  191. bumps.setBumpArea( bumpLength, bumpHeight );
  192. bumps.paintIcon( this, g, xOffset, bumpYOffset);
  193. paintChildren(g);
  194. }
  195. public void actionPerformed(ActionEvent e) {
  196. if("Close".equals(e.getActionCommand()) && frame.isClosable()){
  197. try {
  198. frame.setClosed(true);
  199. } catch (PropertyVetoException e0) { }
  200. }
  201. else if("Iconify".equals(e.getActionCommand()) && frame.isIconifiable()) {
  202. if(!frame.isIcon())
  203. try { frame.setIcon(true); } catch (PropertyVetoException e1) { }
  204. else
  205. try { frame.setIcon(false); } catch (PropertyVetoException e1) { }
  206. ButtonModel model = iconButton.getModel();
  207. if ( model != null ) {
  208. model.setRollover( false );
  209. }
  210. } else if("Minimize".equals(e.getActionCommand()) && frame.isMaximizable()) {
  211. try { frame.setIcon(true); } catch (PropertyVetoException e2) { }
  212. } else if("Maximize".equals(e.getActionCommand()) && frame.isMaximizable()) {
  213. if(!frame.isMaximum()) {
  214. try { frame.setMaximum(true); } catch (PropertyVetoException e5) { }
  215. } else {
  216. try { frame.setMaximum(false); } catch (PropertyVetoException e6) { }
  217. }
  218. } else if("Restore".equals(e.getActionCommand()) &&
  219. frame.isMaximizable() && frame.isMaximum()) {
  220. try { frame.setMaximum(false); } catch (PropertyVetoException e4) { }
  221. } else if("Restore".equals(e.getActionCommand()) &&
  222. frame.isIconifiable() && frame.isIcon()) {
  223. try { frame.setIcon(false); } catch (PropertyVetoException e4) { }
  224. }
  225. }
  226. public void propertyChange(PropertyChangeEvent evt) {
  227. String prop = (String)evt.getPropertyName();
  228. JInternalFrame f = (JInternalFrame)evt.getSource();
  229. boolean value = false;
  230. if ( frame.isSelected() ) {
  231. iconButton.putClientProperty("paintActive", Boolean.TRUE);
  232. closeButton.putClientProperty("paintActive", Boolean.TRUE);
  233. maxButton.putClientProperty("paintActive", Boolean.TRUE);
  234. repaint();
  235. } else {
  236. iconButton.putClientProperty("paintActive", Boolean.FALSE);
  237. closeButton.putClientProperty("paintActive", Boolean.FALSE);
  238. maxButton.putClientProperty("paintActive", Boolean.FALSE);
  239. repaint();
  240. }
  241. if(JInternalFrame.IS_SELECTED_PROPERTY.equals(prop)) {
  242. repaint();
  243. } else if(JInternalFrame.IS_MAXIMUM_PROPERTY.equals(prop)) {
  244. value = ((Boolean)evt.getNewValue()).booleanValue();
  245. if(value)
  246. maxButton.setIcon(altMaxIcon);
  247. else
  248. maxButton.setIcon(maxIcon);
  249. } else if(JInternalFrame.IS_ICON_PROPERTY.equals(prop)) {
  250. value = ((Boolean)evt.getNewValue()).booleanValue();
  251. if(value)
  252. iconButton.setIcon(iconIcon);
  253. else
  254. iconButton.setIcon(iconIcon);
  255. }
  256. }
  257. public void addLayoutComponent(String name, Component c) {}
  258. public void removeLayoutComponent(Component c) {}
  259. public Dimension preferredLayoutSize(Container c) {
  260. return getPreferredSize(c);
  261. }
  262. public Dimension getPreferredSize(Container c) {
  263. return new Dimension(c.getSize().width, computeHeight());
  264. }
  265. public Dimension minimumLayoutSize(Container c) {
  266. return preferredLayoutSize(c);
  267. }
  268. protected int computeHeight() {
  269. if ( isPalette )
  270. return UIManager.getInt("InternalFrame.paletteTitleHeight");
  271. FontMetrics fm = Toolkit.getDefaultToolkit().getFontMetrics(getFont());
  272. int fontHeight = fm.getHeight();
  273. fontHeight += 7;
  274. int iconHeight = frame.getFrameIcon().getIconHeight();
  275. iconHeight += 5;
  276. int finalHeight = Math.max( fontHeight, iconHeight );
  277. return finalHeight;
  278. }
  279. public void layoutContainer(Container c) {
  280. int w = getWidth()-2;
  281. int y = 2;
  282. int extraCloseOffset = 7;
  283. int buttonHeight = closeButton.getIcon().getIconHeight(); // this includes the border
  284. int buttonWidth = closeButton.getIcon().getIconWidth(); // this includes the border
  285. int x = (w);
  286. if(frame.isClosable()) {
  287. if (isPalette) {
  288. x -= (buttonWidth+4);
  289. closeButton.setBounds(x, 2, buttonWidth+2, getHeight()-4);
  290. x -= 3;
  291. } else {
  292. x -= (buttonWidth+interButtonSpacing);
  293. closeButton.setBounds(x , y, buttonWidth, buttonHeight);
  294. x -= extraCloseOffset;
  295. }
  296. } else if(closeButton.getParent() != null) {
  297. closeButton.getParent().remove(closeButton);
  298. }
  299. if(frame.isMaximizable() && !isPalette ) {
  300. x -= (buttonWidth+interButtonSpacing);
  301. maxButton.setBounds(x, y, buttonWidth, buttonHeight);
  302. } else if(maxButton.getParent() != null) {
  303. maxButton.getParent().remove(maxButton);
  304. }
  305. if(frame.isIconifiable() && !isPalette ) {
  306. x -= (buttonWidth+interButtonSpacing);
  307. iconButton.setBounds(x, y, buttonWidth, buttonHeight);
  308. } else if(iconButton.getParent() != null) {
  309. iconButton.getParent().remove(iconButton);
  310. }
  311. riseWidth = w-x;
  312. }
  313. public void setPalette(boolean b) {
  314. isPalette = b;
  315. if (isPalette) {
  316. closeButton.setIcon(UIManager.getIcon("InternalFrame.paletteCloseIcon"));
  317. } else {
  318. closeButton.setIcon(closeIcon);
  319. }
  320. repaint();
  321. revalidate();
  322. }
  323. private static class NoFocusButton extends JButton {
  324. public NoFocusButton(Icon icon) {
  325. super(icon);
  326. setFocusPainted(false);
  327. }
  328. public NoFocusButton() { setFocusPainted(false); }
  329. public boolean isFocusTraversable() { return false; }
  330. public void requestFocus() {};
  331. public boolean isOpaque() { return false; }
  332. public boolean isContentAreaFilled() { return false; }
  333. } // end NoFocusButton
  334. } // End Title Pane Class