blob: e3951cef31010ab5edb3aea1a8fad0e9e9960192 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package com.sun.java.swing.plaf.motif;
27
28import sun.swing.SwingUtilities2;
29import java.awt.*;
30import java.awt.event.*;
31import javax.swing.*;
32import javax.swing.border.*;
33import javax.swing.plaf.*;
34import javax.swing.plaf.basic.*;
35import java.beans.*;
36import java.util.EventListener;
37import java.io.Serializable;
38
39
40/**
41 * Motif rendition of the component.
42 *
43 * @author Thomas Ball
44 * @author Rich Schiavi
45 */
46public class MotifDesktopIconUI extends BasicDesktopIconUI
47{
48 protected DesktopIconActionListener desktopIconActionListener;
49 protected DesktopIconMouseListener desktopIconMouseListener;
50
51 protected Icon defaultIcon;
52 protected IconButton iconButton;
53 protected IconLabel iconLabel;
54
55 // This is only used for its system menu, but we need a reference to it so
56 // we can remove its listeners.
57 private MotifInternalFrameTitlePane sysMenuTitlePane;
58
59 JPopupMenu systemMenu;
60 EventListener mml;
61
62 final static int LABEL_HEIGHT = 18;
63 final static int LABEL_DIVIDER = 4; // padding between icon and label
64
65 final static Font defaultTitleFont =
66 new Font(Font.SANS_SERIF, Font.PLAIN, 12);
67
68 public static ComponentUI createUI(JComponent c) {
69 return new MotifDesktopIconUI();
70 }
71
72 public MotifDesktopIconUI() {
73 }
74
75 protected void installDefaults(){
76 super.installDefaults();
77 setDefaultIcon(UIManager.getIcon("DesktopIcon.icon"));
78 iconButton = createIconButton(defaultIcon);
79 // An underhanded way of creating a system popup menu.
80 sysMenuTitlePane = new MotifInternalFrameTitlePane(frame);
81 systemMenu = sysMenuTitlePane.getSystemMenu();
82
83 MotifBorders.FrameBorder border = new MotifBorders.FrameBorder(desktopIcon);
84 desktopIcon.setLayout(new BorderLayout());
85 iconButton.setBorder(border);
86 desktopIcon.add(iconButton, BorderLayout.CENTER);
87 iconLabel = createIconLabel(frame);
88 iconLabel.setBorder(border);
89 desktopIcon.add(iconLabel, BorderLayout.SOUTH);
90 desktopIcon.setSize(desktopIcon.getPreferredSize());
91 desktopIcon.validate();
92 JLayeredPane.putLayer(desktopIcon, JLayeredPane.getLayer(frame));
93 }
94
95 protected void installComponents(){
96 }
97
98 protected void uninstallComponents(){
99 }
100
101 protected void installListeners(){
102 super.installListeners();
103 desktopIconActionListener = createDesktopIconActionListener();
104 desktopIconMouseListener = createDesktopIconMouseListener();
105 iconButton.addActionListener(desktopIconActionListener);
106 iconButton.addMouseListener(desktopIconMouseListener);
107 iconLabel.addMouseListener(desktopIconMouseListener);
108 }
109
110 JInternalFrame.JDesktopIcon getDesktopIcon(){
111 return desktopIcon;
112 }
113
114 void setDesktopIcon(JInternalFrame.JDesktopIcon d){
115 desktopIcon = d;
116 }
117
118 JInternalFrame getFrame(){
119 return frame;
120 }
121
122 void setFrame(JInternalFrame f){
123 frame = f ;
124 }
125
126 protected void showSystemMenu(){
127 systemMenu.show(iconButton, 0, getDesktopIcon().getHeight());
128 }
129
130 protected void hideSystemMenu(){
131 systemMenu.setVisible(false);
132 }
133
134 protected IconLabel createIconLabel(JInternalFrame frame){
135 return new IconLabel(frame);
136 }
137
138 protected IconButton createIconButton(Icon i){
139 return new IconButton(i);
140 }
141
142 protected DesktopIconActionListener createDesktopIconActionListener(){
143 return new DesktopIconActionListener();
144 }
145
146 protected DesktopIconMouseListener createDesktopIconMouseListener(){
147 return new DesktopIconMouseListener();
148 }
149
150 protected void uninstallDefaults(){
151 super.uninstallDefaults();
152 desktopIcon.setLayout(null);
153 desktopIcon.remove(iconButton);
154 desktopIcon.remove(iconLabel);
155 }
156
157 protected void uninstallListeners(){
158 super.uninstallListeners();
159 iconButton.removeActionListener(desktopIconActionListener);
160 iconButton.removeMouseListener(desktopIconMouseListener);
161 sysMenuTitlePane.uninstallListeners();
162 }
163
164 public Dimension getMinimumSize(JComponent c) {
165 JInternalFrame iframe = desktopIcon.getInternalFrame();
166
167 int w = defaultIcon.getIconWidth();
168 int h = defaultIcon.getIconHeight() + LABEL_HEIGHT + LABEL_DIVIDER;
169
170 Border border = iframe.getBorder();
171 if(border != null) {
172 w += border.getBorderInsets(iframe).left +
173 border.getBorderInsets(iframe).right;
174 h += border.getBorderInsets(iframe).bottom +
175 border.getBorderInsets(iframe).top;
176 }
177
178 return new Dimension(w, h);
179 }
180
181 public Dimension getPreferredSize(JComponent c) {
182 return getMinimumSize(c);
183 }
184
185 public Dimension getMaximumSize(JComponent c){
186 return getMinimumSize(c);
187 }
188
189 /**
190 * Returns the default desktop icon.
191 */
192 public Icon getDefaultIcon() {
193 return defaultIcon;
194 }
195
196 /**
197 * Sets the icon used as the default desktop icon.
198 */
199 public void setDefaultIcon(Icon newIcon) {
200 defaultIcon = newIcon;
201 }
202
203 protected class IconLabel extends JPanel {
204 JInternalFrame frame;
205
206 IconLabel(JInternalFrame f) {
207 super();
208 this.frame = f;
209 setFont(defaultTitleFont);
210
211 // Forward mouse events to titlebar for moves.
212 addMouseMotionListener(new MouseMotionListener() {
213 public void mouseDragged(MouseEvent e) {
214 forwardEventToParent(e);
215 }
216 public void mouseMoved(MouseEvent e) {
217 forwardEventToParent(e);
218 }
219 });
220 addMouseListener(new MouseListener() {
221 public void mouseClicked(MouseEvent e) {
222 forwardEventToParent(e);
223 }
224 public void mousePressed(MouseEvent e) {
225 forwardEventToParent(e);
226 }
227 public void mouseReleased(MouseEvent e) {
228 forwardEventToParent(e);
229 }
230 public void mouseEntered(MouseEvent e) {
231 forwardEventToParent(e);
232 }
233 public void mouseExited(MouseEvent e) {
234 forwardEventToParent(e);
235 }
236 });
237 }
238
239 void forwardEventToParent(MouseEvent e) {
240 getParent().dispatchEvent(new MouseEvent(
241 getParent(), e.getID(), e.getWhen(), e.getModifiers(),
242 e.getX(), e.getY(), e.getXOnScreen(),
243 e.getYOnScreen(), e.getClickCount(),
244 e.isPopupTrigger(), MouseEvent.NOBUTTON));
245 }
246
247 public boolean isFocusTraversable() {
248 return false;
249 }
250
251 public Dimension getMinimumSize() {
252 return new Dimension(defaultIcon.getIconWidth() + 1,
253 LABEL_HEIGHT + LABEL_DIVIDER);
254 }
255
256 public Dimension getPreferredSize() {
257 String title = frame.getTitle();
258 FontMetrics fm = frame.getFontMetrics(defaultTitleFont);
259 int w = 4;
260 if (title != null) {
261 w += SwingUtilities2.stringWidth(frame, fm, title);
262 }
263 return new Dimension(w, LABEL_HEIGHT + LABEL_DIVIDER);
264 }
265
266 public void paint(Graphics g) {
267 super.paint(g);
268
269 // touch-up frame
270 int maxX = getWidth() - 1;
271 Color shadow =
272 UIManager.getColor("inactiveCaptionBorder").darker().darker();
273 g.setColor(shadow);
274 g.setClip(0, 0, getWidth(), getHeight());
275 g.drawLine(maxX - 1, 1, maxX - 1, 1);
276 g.drawLine(maxX, 0, maxX, 0);
277
278 // fill background
279 g.setColor(UIManager.getColor("inactiveCaption"));
280 g.fillRect(2, 1, maxX - 3, LABEL_HEIGHT + 1);
281
282 // draw text -- clipping to truncate text like CDE/Motif
283 g.setClip(2, 1, maxX - 4, LABEL_HEIGHT);
284 int y = LABEL_HEIGHT - SwingUtilities2.getFontMetrics(frame, g).
285 getDescent();
286 g.setColor(UIManager.getColor("inactiveCaptionText"));
287 String title = frame.getTitle();
288 if (title != null) {
289 SwingUtilities2.drawString(frame, g, title, 4, y);
290 }
291 }
292 }
293
294 protected class IconButton extends JButton {
295 Icon icon;
296
297 IconButton(Icon icon) {
298 super(icon);
299 this.icon = icon;
300 // Forward mouse events to titlebar for moves.
301 addMouseMotionListener(new MouseMotionListener() {
302 public void mouseDragged(MouseEvent e) {
303 forwardEventToParent(e);
304 }
305 public void mouseMoved(MouseEvent e) {
306 forwardEventToParent(e);
307 }
308 });
309 addMouseListener(new MouseListener() {
310 public void mouseClicked(MouseEvent e) {
311 forwardEventToParent(e);
312 }
313 public void mousePressed(MouseEvent e) {
314 forwardEventToParent(e);
315 }
316 public void mouseReleased(MouseEvent e) {
317 if (!systemMenu.isShowing()) {
318 forwardEventToParent(e);
319 }
320 }
321 public void mouseEntered(MouseEvent e) {
322 forwardEventToParent(e);
323 }
324 public void mouseExited(MouseEvent e) {
325 forwardEventToParent(e);
326 }
327 });
328 }
329
330 void forwardEventToParent(MouseEvent e) {
331 getParent().dispatchEvent(new MouseEvent(
332 getParent(), e.getID(), e.getWhen(), e.getModifiers(),
333 e.getX(), e.getY(), e.getXOnScreen(), e.getYOnScreen(),
334 e.getClickCount(), e.isPopupTrigger(), MouseEvent.NOBUTTON ));
335 }
336
337 public boolean isFocusTraversable() {
338 return false;
339 }
340 }
341
342
343 protected class DesktopIconActionListener implements ActionListener {
344 public void actionPerformed(ActionEvent e){
345 systemMenu.show(iconButton, 0, getDesktopIcon().getHeight());
346 }
347 }
348
349 protected class DesktopIconMouseListener extends MouseAdapter {
350 // if we drag or move we should deengage the popup
351 public void mousePressed(MouseEvent e){
352 if (e.getClickCount() > 1) {
353 try {
354 getFrame().setIcon(false);
355 } catch (PropertyVetoException e2){ }
356 systemMenu.setVisible(false);
357 /* the mouse release will not get reported correctly,
358 because the icon will no longer be in the hierarchy;
359 maybe that should be fixed, but until it is, we need
360 to do the required cleanup here. */
361 getFrame().getDesktopPane().getDesktopManager().endDraggingFrame((JComponent)e.getSource());
362 }
363 }
364 }
365}