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