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