1. /*
  2. * @(#)MotifInternalFrameTitlePane.java 1.13 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 com.sun.java.swing.plaf.motif;
  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 Motif title bar
  20. * @version 1.13 11/29/01
  21. */
  22. class MotifInternalFrameTitlePane
  23. extends JComponent implements LayoutManager, ActionListener, PropertyChangeListener
  24. {
  25. SystemButton systemButton;
  26. MinimizeButton minimizeButton;
  27. MaximizeButton maximizeButton;
  28. JPopupMenu systemMenu;
  29. Title title;
  30. JInternalFrame iFrame;
  31. Color color;
  32. Color highlight;
  33. Color shadow;
  34. static final Font defaultTitleFont = new Font("SansSerif", Font.PLAIN, 12);
  35. // The width and height of a title pane button
  36. public final static int BUTTON_SIZE = 19; // 17 + 1 pixel border
  37. final int RESTORE_MENU_ITEM = 0;
  38. final int MOVE_MENU_ITEM = 1;
  39. final int SIZE_MENU_ITEM = 2;
  40. final int MINIMIZE_MENU_ITEM = 3;
  41. final int MAXIMIZE_MENU_ITEM = 4;
  42. final int SEPARATOR_MENU_ITEM = 5;
  43. final int CLOSE_MENU_ITEM = 6;
  44. public MotifInternalFrameTitlePane(JInternalFrame f) {
  45. iFrame = f;
  46. setPreferredSize(new Dimension(100, BUTTON_SIZE));
  47. systemMenu = new JPopupMenu() {
  48. public void show(Component invoker, int x, int y) {
  49. if(!iFrame.isIconifiable())
  50. systemMenu.getComponentAtIndex(MINIMIZE_MENU_ITEM).setEnabled(false);
  51. if(!iFrame.isMaximizable())
  52. systemMenu.getComponentAtIndex(MAXIMIZE_MENU_ITEM).setEnabled(false);
  53. if(!iFrame.isMaximizable() && !iFrame.isIconifiable())
  54. systemMenu.getComponentAtIndex(RESTORE_MENU_ITEM).setEnabled(false);
  55. if(!iFrame.isClosable())
  56. systemMenu.getComponentAtIndex(CLOSE_MENU_ITEM).setEnabled(false);
  57. super.show(invoker, x, y);
  58. }
  59. };
  60. JMenuItem mi = (JMenuItem) systemMenu.add(new JMenuItem("Restore"));
  61. mi.setEnabled(false);
  62. mi.addActionListener(this);
  63. /// PENDING(klobad) Move/Size actions on InternalFrame need to be determined
  64. mi = (JMenuItem) systemMenu.add(new JMenuItem("Move"));
  65. mi.setEnabled(false);
  66. mi.addActionListener(this);
  67. mi = (JMenuItem) systemMenu.add(new JMenuItem("Size"));
  68. mi.setEnabled(false);
  69. mi.addActionListener(this);
  70. mi = (JMenuItem) systemMenu.add(new JMenuItem("Minimize"));
  71. mi.addActionListener(this);
  72. mi = (JMenuItem) systemMenu.add(new JMenuItem("Maximize"));
  73. mi.addActionListener(this);
  74. systemMenu.add(new JSeparator());
  75. mi = (JMenuItem) systemMenu.add(new JMenuItem("Close"));
  76. mi.addActionListener(this);
  77. systemButton = new SystemButton();
  78. systemButton.addActionListener(new ActionListener() {
  79. public void actionPerformed(ActionEvent e) {
  80. systemMenu.show(systemButton, 0, BUTTON_SIZE);
  81. }
  82. });
  83. systemButton.addMouseListener(new MouseAdapter() {
  84. public void mousePressed(MouseEvent e) {
  85. if ((e.getClickCount() == 2)){
  86. if (iFrame.isClosable()) {
  87. try{
  88. iFrame.setClosed(true);
  89. } catch (PropertyVetoException e0) { }
  90. }
  91. systemMenu.setVisible(false);
  92. }
  93. }
  94. });
  95. minimizeButton = new MinimizeButton();
  96. minimizeButton.addActionListener(this);
  97. minimizeButton.setActionCommand("Iconify");
  98. maximizeButton = new MaximizeButton();
  99. maximizeButton.addActionListener(this);
  100. maximizeButton.setActionCommand("Maximize");
  101. title = new Title(iFrame.getTitle());
  102. title.setFont(defaultTitleFont);
  103. setLayout(this);
  104. add(systemButton);
  105. add(title);
  106. add(minimizeButton);
  107. add(maximizeButton);
  108. // Make sure these are ok to leave on?
  109. iFrame.addPropertyChangeListener(this);
  110. }
  111. void setColors(Color c, Color h, Color s) {
  112. color = c;
  113. highlight = h;
  114. shadow = s;
  115. }
  116. JPopupMenu getSystemMenu() {
  117. return systemMenu;
  118. }
  119. public void actionPerformed(ActionEvent e) {
  120. try {
  121. if ("Close".equals(e.getActionCommand()) && iFrame.isClosable()) {
  122. iFrame.setClosed(true);
  123. // 4118140
  124. }
  125. else if ((("Iconify".equals(e.getActionCommand())) ||
  126. ("Minimize".equals(e.getActionCommand())))
  127. &&
  128. iFrame.isIconifiable()) {
  129. if (!iFrame.isIcon()) {
  130. iFrame.setIcon(true);
  131. } else {
  132. iFrame.setIcon(false);
  133. }
  134. }
  135. else if ("Maximize".equals(e.getActionCommand()) &&
  136. iFrame.isMaximizable()) {
  137. if(!iFrame.isMaximum()) {
  138. iFrame.setMaximum(true);
  139. } else {
  140. iFrame.setMaximum(false);
  141. }
  142. } else if ("Restore".equals(e.getActionCommand()) &&
  143. iFrame.isMaximizable() && iFrame.isMaximum()) {
  144. iFrame.setMaximum(false);
  145. } else if ("Restore".equals(e.getActionCommand()) &&
  146. iFrame.isIconifiable() && iFrame.isIcon()) {
  147. iFrame.setIcon(false);
  148. }
  149. } catch (PropertyVetoException e0) { }
  150. // Dismiss popup menu if it's displayed
  151. if (systemMenu.isVisible()) {
  152. systemMenu.setVisible(false);
  153. }
  154. }
  155. public void propertyChange(PropertyChangeEvent evt) {
  156. String prop = (String)evt.getPropertyName();
  157. JInternalFrame f = (JInternalFrame)evt.getSource();
  158. boolean value = false;
  159. if(JInternalFrame.IS_SELECTED_PROPERTY.equals(prop)) {
  160. repaint();
  161. } else if(JInternalFrame.IS_MAXIMUM_PROPERTY.equals(prop)) {
  162. value = ((Boolean)evt.getNewValue()).booleanValue();
  163. systemMenu.getComponentAtIndex(RESTORE_MENU_ITEM).setEnabled(value);
  164. systemMenu.getComponentAtIndex(MAXIMIZE_MENU_ITEM).setEnabled(!value);
  165. } else if(JInternalFrame.IS_ICON_PROPERTY.equals(prop)) {
  166. value = ((Boolean)evt.getNewValue()).booleanValue();
  167. systemMenu.getComponentAtIndex(RESTORE_MENU_ITEM).setEnabled(value);
  168. systemMenu.getComponentAtIndex(MAXIMIZE_MENU_ITEM).setEnabled(!value);
  169. systemMenu.getComponentAtIndex(MINIMIZE_MENU_ITEM).setEnabled(!value);
  170. }
  171. }
  172. public void addLayoutComponent(String name, Component c) {}
  173. public void removeLayoutComponent(Component c) {}
  174. public Dimension preferredLayoutSize(Container c) {
  175. return new Dimension(c.getSize().width, BUTTON_SIZE);
  176. }
  177. public Dimension minimumLayoutSize(Container c) {
  178. return new Dimension(c.getSize().width, BUTTON_SIZE);
  179. }
  180. public void layoutContainer(Container c) {
  181. int w = getWidth();
  182. systemButton.setBounds(0, 0, BUTTON_SIZE, BUTTON_SIZE);
  183. int x = w - BUTTON_SIZE;
  184. if(iFrame.isMaximizable()) {
  185. maximizeButton.setBounds(x, 0, BUTTON_SIZE, BUTTON_SIZE);
  186. x -= BUTTON_SIZE;
  187. } else if(maximizeButton.getParent() != null) {
  188. maximizeButton.getParent().remove(maximizeButton);
  189. }
  190. if(iFrame.isIconifiable()) {
  191. minimizeButton.setBounds(x, 0, BUTTON_SIZE, BUTTON_SIZE);
  192. x -= BUTTON_SIZE;
  193. } else if(minimizeButton.getParent() != null) {
  194. minimizeButton.getParent().remove(minimizeButton);
  195. }
  196. title.setBounds(BUTTON_SIZE, 0, x, BUTTON_SIZE);
  197. }
  198. protected void showSystemMenu(){
  199. systemMenu.show(systemButton, 0, BUTTON_SIZE);
  200. }
  201. protected void hideSystemMenu(){
  202. systemMenu.setVisible(false);
  203. }
  204. static Dimension buttonDimension = new Dimension(BUTTON_SIZE, BUTTON_SIZE);
  205. private abstract class FrameButton extends JButton {
  206. FrameButton() {
  207. super();
  208. setFocusPainted(false);
  209. setBorderPainted(false);
  210. }
  211. public boolean isFocusTraversable() {
  212. return false;
  213. }
  214. public void requestFocus() {
  215. // ignore request.
  216. }
  217. public Dimension getMinimumSize() {
  218. return buttonDimension;
  219. }
  220. public Dimension getPreferredSize() {
  221. return buttonDimension;
  222. }
  223. public void paint(Graphics g) {
  224. Dimension d = getSize();
  225. int maxX = d.width - 1;
  226. int maxY = d.height - 1;
  227. // draw background
  228. g.setColor(color);
  229. g.fillRect(1, 1, d.width, d.height);
  230. // draw border
  231. boolean pressed = getModel().isPressed();
  232. g.setColor(pressed ? shadow : highlight);
  233. g.drawLine(0, 0, maxX, 0);
  234. g.drawLine(0, 0, 0, maxY);
  235. g.setColor(pressed ? highlight : shadow);
  236. g.drawLine(1, maxY, maxX, maxY);
  237. g.drawLine(maxX, 1, maxX, maxY);
  238. }
  239. }
  240. private class MinimizeButton extends FrameButton {
  241. public void paint(Graphics g) {
  242. super.paint(g);
  243. g.setColor(highlight);
  244. g.drawLine(7, 8, 7, 11);
  245. g.drawLine(7, 8, 10, 8);
  246. g.setColor(shadow);
  247. g.drawLine(8, 11, 10, 11);
  248. g.drawLine(11, 9, 11, 11);
  249. }
  250. }
  251. private class MaximizeButton extends FrameButton {
  252. public void paint(Graphics g) {
  253. super.paint(g);
  254. int max = BUTTON_SIZE - 5;
  255. boolean isMaxed = iFrame.isMaximum();
  256. g.setColor(isMaxed ? shadow : highlight);
  257. g.drawLine(4, 4, 4, max);
  258. g.drawLine(4, 4, max, 4);
  259. g.setColor(isMaxed ? highlight : shadow);
  260. g.drawLine(5, max, max, max);
  261. g.drawLine(max, 5, max, max);
  262. }
  263. }
  264. private class SystemButton extends FrameButton {
  265. public boolean isFocusTraversable() { return false; }
  266. public void requestFocus() {}
  267. public void paint(Graphics g) {
  268. super.paint(g);
  269. g.setColor(highlight);
  270. g.drawLine(4, 8, 4, 11);
  271. g.drawLine(4, 8, BUTTON_SIZE - 5, 8);
  272. g.setColor(shadow);
  273. g.drawLine(5, 11, BUTTON_SIZE - 5, 11);
  274. g.drawLine(BUTTON_SIZE - 5, 9, BUTTON_SIZE - 5, 11);
  275. }
  276. }
  277. private class Title extends FrameButton {
  278. Title(String title) {
  279. super();
  280. setText(title);
  281. setHorizontalAlignment(SwingConstants.CENTER);
  282. setBorder(BorderFactory.createBevelBorder(
  283. BevelBorder.RAISED,
  284. UIManager.getColor("activeCaptionBorder"),
  285. UIManager.getColor("inactiveCaptionBorder")));
  286. // Forward mouse events to titlebar for moves.
  287. addMouseMotionListener(new MouseMotionListener() {
  288. public void mouseDragged(MouseEvent e) {
  289. forwardEventToParent(e);
  290. }
  291. public void mouseMoved(MouseEvent e) {
  292. forwardEventToParent(e);
  293. }
  294. });
  295. addMouseListener(new MouseListener() {
  296. public void mouseClicked(MouseEvent e) {
  297. forwardEventToParent(e);
  298. }
  299. public void mousePressed(MouseEvent e) {
  300. forwardEventToParent(e);
  301. }
  302. public void mouseReleased(MouseEvent e) {
  303. forwardEventToParent(e);
  304. }
  305. public void mouseEntered(MouseEvent e) {
  306. forwardEventToParent(e);
  307. }
  308. public void mouseExited(MouseEvent e) {
  309. forwardEventToParent(e);
  310. }
  311. });
  312. }
  313. void forwardEventToParent(MouseEvent e) {
  314. getParent().dispatchEvent(new MouseEvent(
  315. getParent(), e.getID(), e.getWhen(), e.getModifiers(),
  316. e.getX(), e.getY(), e.getClickCount(), e.isPopupTrigger()));
  317. }
  318. public void paint(Graphics g) {
  319. super.paint(g);
  320. if (iFrame.isSelected()) {
  321. g.setColor(UIManager.getColor("activeCaptionText"));
  322. } else {
  323. g.setColor(UIManager.getColor("inactiveCaptionText"));
  324. }
  325. Dimension d = getSize();
  326. MotifGraphicsUtils.drawStringInRect(g, iFrame.getTitle(),
  327. 0, 0, d.width, d.height,
  328. SwingConstants.CENTER);
  329. }
  330. }
  331. } /// End Title Pane Class