blob: 88e15c6bcf95779dea7b4cc89e096d6c0bf65d51 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2002-2003 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 javax.swing.plaf.synth;
27
28import javax.swing.*;
29import javax.swing.border.*;
30import javax.swing.plaf.*;
31import javax.swing.plaf.basic.BasicDesktopPaneUI;
32
33import java.beans.*;
34
35import java.awt.event.*;
36import java.awt.Dimension;
37import java.awt.Insets;
38import java.awt.Graphics;
39import java.awt.KeyboardFocusManager;
40import java.awt.*;
41import java.util.Vector;
42import sun.swing.plaf.synth.SynthUI;
43
44/**
45 * Synth L&F for a desktop.
46 *
47 * @author Joshua Outwater
48 * @author Steve Wilson
49 */
50class SynthDesktopPaneUI extends BasicDesktopPaneUI implements
51 PropertyChangeListener, SynthUI {
52 private SynthStyle style;
53 private TaskBar taskBar;
54 private DesktopManager oldDesktopManager;
55
56 public static ComponentUI createUI(JComponent c) {
57 return new SynthDesktopPaneUI();
58 }
59
60 protected void installListeners() {
61 super.installListeners();
62 desktop.addPropertyChangeListener(this);
63 if (taskBar != null) {
64 // Listen for desktop being resized
65 desktop.addComponentListener(taskBar);
66 // Listen for frames being added to desktop
67 desktop.addContainerListener(taskBar);
68 }
69 }
70
71 protected void installDefaults() {
72 updateStyle(desktop);
73
74 if (UIManager.getBoolean("InternalFrame.useTaskBar")) {
75 taskBar = new TaskBar();
76
77 for (Component comp : desktop.getComponents()) {
78 JInternalFrame.JDesktopIcon desktopIcon;
79
80 if (comp instanceof JInternalFrame.JDesktopIcon) {
81 desktopIcon = (JInternalFrame.JDesktopIcon)comp;
82 } else if (comp instanceof JInternalFrame) {
83 desktopIcon = ((JInternalFrame)comp).getDesktopIcon();
84 } else {
85 continue;
86 }
87 // Move desktopIcon from desktop to taskBar
88 if (desktopIcon.getParent() == desktop) {
89 desktop.remove(desktopIcon);
90 }
91 if (desktopIcon.getParent() != taskBar) {
92 taskBar.add(desktopIcon);
93 desktopIcon.getInternalFrame().addComponentListener(
94 taskBar);
95 }
96 }
97 taskBar.setBackground(desktop.getBackground());
98 desktop.add(taskBar,
99 new Integer(JLayeredPane.PALETTE_LAYER.intValue() + 1));
100 if (desktop.isShowing()) {
101 taskBar.adjustSize();
102 }
103 }
104 }
105
106 private void updateStyle(JDesktopPane c) {
107 SynthStyle oldStyle = style;
108 SynthContext context = getContext(c, ENABLED);
109 style = SynthLookAndFeel.updateStyle(context, this);
110 if (oldStyle != null) {
111 uninstallKeyboardActions();
112 installKeyboardActions();
113 }
114 context.dispose();
115 }
116
117 protected void uninstallListeners() {
118 if (taskBar != null) {
119 desktop.removeComponentListener(taskBar);
120 desktop.removeContainerListener(taskBar);
121 }
122 desktop.removePropertyChangeListener(this);
123 super.uninstallListeners();
124 }
125
126 protected void uninstallDefaults() {
127 SynthContext context = getContext(desktop, ENABLED);
128
129 style.uninstallDefaults(context);
130 context.dispose();
131 style = null;
132
133 if (taskBar != null) {
134 for (Component comp : taskBar.getComponents()) {
135 JInternalFrame.JDesktopIcon desktopIcon =
136 (JInternalFrame.JDesktopIcon)comp;
137 taskBar.remove(desktopIcon);
138 desktopIcon.setPreferredSize(null);
139 JInternalFrame f = desktopIcon.getInternalFrame();
140 if (f.isIcon()) {
141 desktop.add(desktopIcon);
142 }
143 f.removeComponentListener(taskBar);
144 }
145 desktop.remove(taskBar);
146 taskBar = null;
147 }
148 }
149
150 protected void installDesktopManager() {
151 if (UIManager.getBoolean("InternalFrame.useTaskBar")) {
152 desktopManager = oldDesktopManager = desktop.getDesktopManager();
153 if (!(desktopManager instanceof SynthDesktopManager)) {
154 desktopManager = new SynthDesktopManager();
155 desktop.setDesktopManager(desktopManager);
156 }
157 } else {
158 super.installDesktopManager();
159 }
160 }
161
162 protected void uninstallDesktopManager() {
163 if (oldDesktopManager != null && !(oldDesktopManager instanceof UIResource)) {
164 desktopManager = desktop.getDesktopManager();
165 if (desktopManager == null || desktopManager instanceof UIResource) {
166 desktop.setDesktopManager(oldDesktopManager);
167 }
168 }
169 oldDesktopManager = null;
170 super.uninstallDesktopManager();
171 }
172
173 static class TaskBar extends JPanel implements ComponentListener, ContainerListener {
174 TaskBar() {
175 setOpaque(true);
176 setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0) {
177 public void layoutContainer(Container target) {
178 // First shrink buttons to fit
179 Component[] comps = target.getComponents();
180 int n = comps.length;
181 if (n > 0) {
182 // Start with the largest preferred width
183 int prefWidth = 0;
184 for (Component c : comps) {
185 c.setPreferredSize(null);
186 Dimension prefSize = c.getPreferredSize();
187 if (prefSize.width > prefWidth) {
188 prefWidth = prefSize.width;
189 }
190 }
191 // Shrink equally to fit if needed
192 Insets insets = target.getInsets();
193 int tw = target.getWidth() - insets.left - insets.right;
194 int w = Math.min(prefWidth, Math.max(10, tw/n));
195 for (Component c : comps) {
196 Dimension prefSize = c.getPreferredSize();
197 c.setPreferredSize(new Dimension(w, prefSize.height));
198 }
199 }
200 super.layoutContainer(target);
201 }
202 });
203
204 // PENDING: This should be handled by the painter
205 setBorder(new BevelBorder(BevelBorder.RAISED) {
206 protected void paintRaisedBevel(Component c, Graphics g,
207 int x, int y, int w, int h) {
208 Color oldColor = g.getColor();
209 g.translate(x, y);
210 g.setColor(getHighlightOuterColor(c));
211 g.drawLine(0, 0, 0, h-2);
212 g.drawLine(1, 0, w-2, 0);
213 g.setColor(getShadowOuterColor(c));
214 g.drawLine(0, h-1, w-1, h-1);
215 g.drawLine(w-1, 0, w-1, h-2);
216 g.translate(-x, -y);
217 g.setColor(oldColor);
218 }
219 });
220 }
221
222 void adjustSize() {
223 JDesktopPane desktop = (JDesktopPane)getParent();
224 if (desktop != null) {
225 int height = getPreferredSize().height;
226 Insets insets = getInsets();
227 if (height == insets.top + insets.bottom) {
228 if (getHeight() <= height) {
229 // Initial size, because we have no buttons yet
230 height += 21;
231 } else {
232 // We already have a good height
233 height = getHeight();
234 }
235 }
236 setBounds(0, desktop.getHeight() - height, desktop.getWidth(), height);
237 revalidate();
238 repaint();
239 }
240 }
241
242 // ComponentListener interface
243
244 public void componentResized(ComponentEvent e) {
245 if (e.getSource() instanceof JDesktopPane) {
246 adjustSize();
247 }
248 }
249
250 public void componentMoved(ComponentEvent e){}
251
252 public void componentShown(ComponentEvent e) {
253 if (e.getSource() instanceof JInternalFrame) {
254 adjustSize();
255 }
256 }
257
258 public void componentHidden(ComponentEvent e) {
259 if (e.getSource() instanceof JInternalFrame) {
260 ((JInternalFrame)e.getSource()).getDesktopIcon().setVisible(false);
261 revalidate();
262 }
263 }
264
265 // ContainerListener interface
266
267 public void componentAdded(ContainerEvent e) {
268 if (e.getChild() instanceof JInternalFrame) {
269 JDesktopPane desktop = (JDesktopPane)e.getSource();
270 JInternalFrame f = (JInternalFrame)e.getChild();
271 JInternalFrame.JDesktopIcon desktopIcon = f.getDesktopIcon();
272 for (Component comp : getComponents()) {
273 if (comp == desktopIcon) {
274 // We have it already
275 return;
276 }
277 }
278 add(desktopIcon);
279 f.addComponentListener(this);
280 if (getComponentCount() == 1) {
281 adjustSize();
282 }
283 }
284 }
285
286 public void componentRemoved(ContainerEvent e) {
287 if (e.getChild() instanceof JInternalFrame) {
288 JInternalFrame f = (JInternalFrame)e.getChild();
289 if (!f.isIcon()) {
290 // Frame was removed without using setClosed(true)
291 remove(f.getDesktopIcon());
292 f.removeComponentListener(this);
293 revalidate();
294 repaint();
295 }
296 }
297 }
298 }
299
300
301 class SynthDesktopManager extends DefaultDesktopManager implements UIResource {
302
303 public void maximizeFrame(JInternalFrame f) {
304 if (f.isIcon()) {
305 try {
306 f.setIcon(false);
307 } catch (PropertyVetoException e2) {
308 }
309 } else {
310 f.setNormalBounds(f.getBounds());
311 Component desktop = f.getParent();
312 setBoundsForFrame(f, 0, 0,
313 desktop.getWidth(),
314 desktop.getHeight() - taskBar.getHeight());
315 }
316
317 try {
318 f.setSelected(true);
319 } catch (PropertyVetoException e2) {
320 }
321 }
322
323 public void iconifyFrame(JInternalFrame f) {
324 JInternalFrame.JDesktopIcon desktopIcon;
325 Container c = f.getParent();
326 JDesktopPane d = f.getDesktopPane();
327 boolean findNext = f.isSelected();
328
329 if (c == null) {
330 return;
331 }
332
333 desktopIcon = f.getDesktopIcon();
334
335 if (!f.isMaximum()) {
336 f.setNormalBounds(f.getBounds());
337 }
338 c.remove(f);
339 c.repaint(f.getX(), f.getY(), f.getWidth(), f.getHeight());
340 try {
341 f.setSelected(false);
342 } catch (PropertyVetoException e2) {
343 }
344
345 // Get topmost of the remaining frames
346 if (findNext) {
347 for (Component comp : c.getComponents()) {
348 if (comp instanceof JInternalFrame) {
349 try {
350 ((JInternalFrame)comp).setSelected(true);
351 } catch (PropertyVetoException e2) {
352 }
353 ((JInternalFrame)comp).moveToFront();
354 return;
355 }
356 }
357 }
358 }
359
360
361 public void deiconifyFrame(JInternalFrame f) {
362 JInternalFrame.JDesktopIcon desktopIcon = f.getDesktopIcon();
363 Container c = desktopIcon.getParent();
364 if (c != null) {
365 c = c.getParent();
366 if (c != null) {
367 c.add(f);
368 if (f.isMaximum()) {
369 int w = c.getWidth();
370 int h = c.getHeight() - taskBar.getHeight();
371 if (f.getWidth() != w || f.getHeight() != h) {
372 setBoundsForFrame(f, 0, 0, w, h);
373 }
374 }
375 if (f.isSelected()) {
376 f.moveToFront();
377 } else {
378 try {
379 f.setSelected(true);
380 } catch (PropertyVetoException e2) {
381 }
382 }
383 }
384 }
385 }
386
387 protected void removeIconFor(JInternalFrame f) {
388 super.removeIconFor(f);
389 taskBar.validate();
390 }
391
392 public void setBoundsForFrame(JComponent f, int newX, int newY, int newWidth, int newHeight) {
393 super.setBoundsForFrame(f, newX, newY, newWidth, newHeight);
394 if (taskBar != null && newY >= taskBar.getY()) {
395 f.setLocation(f.getX(), taskBar.getY()-f.getInsets().top);
396 }
397 }
398 }
399
400
401 public SynthContext getContext(JComponent c) {
402 return getContext(c, getComponentState(c));
403 }
404
405 private SynthContext getContext(JComponent c, int state) {
406 return SynthContext.getContext(SynthContext.class, c,
407 SynthLookAndFeel.getRegion(c), style, state);
408 }
409
410 private Region getRegion(JComponent c) {
411 return SynthLookAndFeel.getRegion(c);
412 }
413
414 private int getComponentState(JComponent c) {
415 return SynthLookAndFeel.getComponentState(c);
416 }
417
418 public void update(Graphics g, JComponent c) {
419 SynthContext context = getContext(c);
420
421 SynthLookAndFeel.update(context, g);
422 context.getPainter().paintDesktopPaneBackground(context, g, 0, 0,
423 c.getWidth(), c.getHeight());
424 paint(context, g);
425 context.dispose();
426 }
427
428 public void paint(Graphics g, JComponent c) {
429 SynthContext context = getContext(c);
430
431 paint(context, g);
432 context.dispose();
433 }
434
435 protected void paint(SynthContext context, Graphics g) {
436 }
437
438 public void paintBorder(SynthContext context, Graphics g, int x,
439 int y, int w, int h) {
440 context.getPainter().paintDesktopPaneBorder(context, g, x, y, w, h);
441 }
442
443 public void propertyChange(PropertyChangeEvent evt) {
444 if (SynthLookAndFeel.shouldUpdateStyle(evt)) {
445 updateStyle((JDesktopPane)evt.getSource());
446 }
447 if (evt.getPropertyName() == "ancestor" && taskBar != null) {
448 taskBar.adjustSize();
449 }
450 }
451}