1. /*
  2. * @(#)MotifDesktopIconUI.java 1.24 04/04/15
  3. *
  4. * Copyright 2004 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 com.sun.java.swing.SwingUtilities2;
  9. import java.awt.*;
  10. import java.awt.event.*;
  11. import javax.swing.*;
  12. import javax.swing.border.*;
  13. import javax.swing.plaf.*;
  14. import javax.swing.plaf.basic.*;
  15. import java.beans.*;
  16. import java.util.EventListener;
  17. import java.io.Serializable;
  18. /**
  19. * Motif rendition of the component.
  20. *
  21. * @version 1.24 04/15/04
  22. * @author Thomas Ball
  23. * @author Rich Schiavi
  24. */
  25. public class MotifDesktopIconUI extends BasicDesktopIconUI
  26. {
  27. protected DesktopIconActionListener desktopIconActionListener;
  28. protected DesktopIconMouseListener desktopIconMouseListener;
  29. protected Icon defaultIcon;
  30. protected IconButton iconButton;
  31. protected IconLabel iconLabel;
  32. // This is only used for its system menu, but we need a reference to it so
  33. // we can remove its listeners.
  34. private MotifInternalFrameTitlePane sysMenuTitlePane;
  35. JPopupMenu systemMenu;
  36. EventListener mml;
  37. final static int LABEL_HEIGHT = 18;
  38. final static int LABEL_DIVIDER = 4; // padding between icon and label
  39. final static Font defaultTitleFont = new Font("SansSerif", Font.PLAIN, 12);
  40. public static ComponentUI createUI(JComponent c) {
  41. return new MotifDesktopIconUI();
  42. }
  43. public MotifDesktopIconUI() {
  44. }
  45. protected void installDefaults(){
  46. super.installDefaults();
  47. setDefaultIcon(UIManager.getIcon("DesktopIcon.icon"));
  48. iconButton = createIconButton(defaultIcon);
  49. // An underhanded way of creating a system popup menu.
  50. sysMenuTitlePane = new MotifInternalFrameTitlePane(frame);
  51. systemMenu = sysMenuTitlePane.getSystemMenu();
  52. MotifBorders.FrameBorder border = new MotifBorders.FrameBorder(desktopIcon);
  53. desktopIcon.setLayout(new BorderLayout());
  54. iconButton.setBorder(border);
  55. desktopIcon.add(iconButton, BorderLayout.CENTER);
  56. iconLabel = createIconLabel(frame);
  57. iconLabel.setBorder(border);
  58. desktopIcon.add(iconLabel, BorderLayout.SOUTH);
  59. desktopIcon.setSize(desktopIcon.getPreferredSize());
  60. desktopIcon.validate();
  61. JLayeredPane.putLayer(desktopIcon, JLayeredPane.getLayer(frame));
  62. }
  63. protected void installComponents(){
  64. }
  65. protected void uninstallComponents(){
  66. }
  67. protected void installListeners(){
  68. super.installListeners();
  69. desktopIconActionListener = createDesktopIconActionListener();
  70. desktopIconMouseListener = createDesktopIconMouseListener();
  71. iconButton.addActionListener(desktopIconActionListener);
  72. iconButton.addMouseListener(desktopIconMouseListener);
  73. }
  74. JInternalFrame.JDesktopIcon getDesktopIcon(){
  75. return desktopIcon;
  76. }
  77. void setDesktopIcon(JInternalFrame.JDesktopIcon d){
  78. desktopIcon = d;
  79. }
  80. JInternalFrame getFrame(){
  81. return frame;
  82. }
  83. void setFrame(JInternalFrame f){
  84. frame = f ;
  85. }
  86. protected void showSystemMenu(){
  87. systemMenu.show(iconButton, 0, getDesktopIcon().getHeight());
  88. }
  89. protected void hideSystemMenu(){
  90. systemMenu.setVisible(false);
  91. }
  92. protected IconLabel createIconLabel(JInternalFrame frame){
  93. return new IconLabel(frame);
  94. }
  95. protected IconButton createIconButton(Icon i){
  96. return new IconButton(i);
  97. }
  98. protected DesktopIconActionListener createDesktopIconActionListener(){
  99. return new DesktopIconActionListener();
  100. }
  101. protected DesktopIconMouseListener createDesktopIconMouseListener(){
  102. return new DesktopIconMouseListener();
  103. }
  104. protected void uninstallDefaults(){
  105. super.uninstallDefaults();
  106. desktopIcon.setLayout(null);
  107. desktopIcon.remove(iconButton);
  108. desktopIcon.remove(iconLabel);
  109. }
  110. protected void uninstallListeners(){
  111. super.uninstallListeners();
  112. iconButton.removeActionListener(desktopIconActionListener);
  113. iconButton.removeMouseListener(desktopIconMouseListener);
  114. sysMenuTitlePane.uninstallListeners();
  115. }
  116. public Dimension getMinimumSize(JComponent c) {
  117. JInternalFrame iframe = desktopIcon.getInternalFrame();
  118. int w = defaultIcon.getIconWidth();
  119. int h = defaultIcon.getIconHeight() + LABEL_HEIGHT + LABEL_DIVIDER;
  120. Border border = iframe.getBorder();
  121. if(border != null) {
  122. w += border.getBorderInsets(iframe).left +
  123. border.getBorderInsets(iframe).right;
  124. h += border.getBorderInsets(iframe).bottom +
  125. border.getBorderInsets(iframe).top;
  126. }
  127. return new Dimension(w, h);
  128. }
  129. public Dimension getPreferredSize(JComponent c) {
  130. return getMinimumSize(c);
  131. }
  132. public Dimension getMaximumSize(JComponent c){
  133. return getMinimumSize(c);
  134. }
  135. /**
  136. * Returns the default desktop icon.
  137. */
  138. public Icon getDefaultIcon() {
  139. return defaultIcon;
  140. }
  141. /**
  142. * Sets the icon used as the default desktop icon.
  143. */
  144. public void setDefaultIcon(Icon newIcon) {
  145. defaultIcon = newIcon;
  146. }
  147. protected class IconLabel extends JPanel {
  148. JInternalFrame frame;
  149. IconLabel(JInternalFrame f) {
  150. super();
  151. this.frame = f;
  152. setFont(defaultTitleFont);
  153. // Forward mouse events to titlebar for moves.
  154. addMouseMotionListener(new MouseMotionListener() {
  155. public void mouseDragged(MouseEvent e) {
  156. forwardEventToParent(e);
  157. }
  158. public void mouseMoved(MouseEvent e) {
  159. forwardEventToParent(e);
  160. }
  161. });
  162. addMouseListener(new MouseListener() {
  163. public void mouseClicked(MouseEvent e) {
  164. forwardEventToParent(e);
  165. }
  166. public void mousePressed(MouseEvent e) {
  167. forwardEventToParent(e);
  168. }
  169. public void mouseReleased(MouseEvent e) {
  170. forwardEventToParent(e);
  171. }
  172. public void mouseEntered(MouseEvent e) {
  173. forwardEventToParent(e);
  174. }
  175. public void mouseExited(MouseEvent e) {
  176. forwardEventToParent(e);
  177. }
  178. });
  179. }
  180. void forwardEventToParent(MouseEvent e) {
  181. getParent().dispatchEvent(new MouseEvent(
  182. getParent(), e.getID(), e.getWhen(), e.getModifiers(),
  183. e.getX(), e.getY(), e.getClickCount(), e.isPopupTrigger()));
  184. }
  185. public boolean isFocusTraversable() {
  186. return false;
  187. }
  188. public Dimension getMinimumSize() {
  189. return new Dimension(defaultIcon.getIconWidth() + 1,
  190. LABEL_HEIGHT + LABEL_DIVIDER);
  191. }
  192. public Dimension getPreferredSize() {
  193. String title = frame.getTitle();
  194. FontMetrics fm = frame.getFontMetrics(defaultTitleFont);
  195. int w = 4;
  196. if (title != null) {
  197. w += SwingUtilities2.stringWidth(frame, fm, title);
  198. }
  199. return new Dimension(w, LABEL_HEIGHT + LABEL_DIVIDER);
  200. }
  201. public void paint(Graphics g) {
  202. super.paint(g);
  203. // touch-up frame
  204. int maxX = getWidth() - 1;
  205. Color shadow =
  206. UIManager.getColor("inactiveCaptionBorder").darker().darker();
  207. g.setColor(shadow);
  208. g.setClip(0, 0, getWidth(), getHeight());
  209. g.drawLine(maxX - 1, 1, maxX - 1, 1);
  210. g.drawLine(maxX, 0, maxX, 0);
  211. // fill background
  212. g.setColor(UIManager.getColor("inactiveCaption"));
  213. g.fillRect(2, 1, maxX - 3, LABEL_HEIGHT + 1);
  214. // draw text -- clipping to truncate text like CDE/Motif
  215. g.setClip(2, 1, maxX - 4, LABEL_HEIGHT);
  216. int y = LABEL_HEIGHT - SwingUtilities2.getFontMetrics(frame, g).
  217. getDescent();
  218. g.setColor(UIManager.getColor("inactiveCaptionText"));
  219. String title = frame.getTitle();
  220. if (title != null) {
  221. SwingUtilities2.drawString(frame, g, title, 4, y);
  222. }
  223. }
  224. }
  225. protected class IconButton extends JButton {
  226. Icon icon;
  227. IconButton(Icon icon) {
  228. super(icon);
  229. this.icon = icon;
  230. // Forward mouse events to titlebar for moves.
  231. addMouseMotionListener(new MouseMotionListener() {
  232. public void mouseDragged(MouseEvent e) {
  233. forwardEventToParent(e);
  234. }
  235. public void mouseMoved(MouseEvent e) {
  236. forwardEventToParent(e);
  237. }
  238. });
  239. addMouseListener(new MouseListener() {
  240. public void mouseClicked(MouseEvent e) {
  241. forwardEventToParent(e);
  242. }
  243. public void mousePressed(MouseEvent e) {
  244. forwardEventToParent(e);
  245. }
  246. public void mouseReleased(MouseEvent e) {
  247. if (!systemMenu.isShowing()) {
  248. forwardEventToParent(e);
  249. }
  250. }
  251. public void mouseEntered(MouseEvent e) {
  252. forwardEventToParent(e);
  253. }
  254. public void mouseExited(MouseEvent e) {
  255. forwardEventToParent(e);
  256. }
  257. });
  258. }
  259. void forwardEventToParent(MouseEvent e) {
  260. getParent().dispatchEvent(new MouseEvent(
  261. getParent(), e.getID(), e.getWhen(), e.getModifiers(),
  262. e.getX(), e.getY(), e.getClickCount(), e.isPopupTrigger()));
  263. }
  264. public boolean isFocusTraversable() {
  265. return false;
  266. }
  267. }
  268. protected class DesktopIconActionListener implements ActionListener {
  269. public void actionPerformed(ActionEvent e){
  270. systemMenu.show(iconButton, 0, getDesktopIcon().getHeight());
  271. }
  272. }
  273. protected class DesktopIconMouseListener extends MouseAdapter {
  274. // if we drag or move we should deengage the popup
  275. public void mousePressed(MouseEvent e){
  276. if (e.getClickCount() == 2){
  277. try {
  278. getFrame().setIcon(false);
  279. } catch (PropertyVetoException e2){ }
  280. systemMenu.setVisible(false);
  281. /* the mouse release will not get reported correctly,
  282. because the icon will no longer be in the hierarchy;
  283. maybe that should be fixed, but until it is, we need
  284. to do the required cleanup here. */
  285. getFrame().getDesktopPane().getDesktopManager().endDraggingFrame((JComponent)e.getSource());
  286. }
  287. }
  288. }
  289. }