KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > java > swing > plaf > windows > WindowsInternalFrameTitlePane


1 /*
2  * @(#)WindowsInternalFrameTitlePane.java 1.19 06/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package com.sun.java.swing.plaf.windows;
9
10 import com.sun.java.swing.SwingUtilities2;
11
12 import javax.swing.*;
13 import javax.swing.border.*;
14 import javax.swing.UIManager JavaDoc;
15 import javax.swing.plaf.*;
16 import javax.swing.plaf.basic.BasicInternalFrameTitlePane JavaDoc;
17 import java.awt.*;
18 import java.awt.event.*;
19 import java.beans.PropertyChangeEvent JavaDoc;
20 import java.beans.PropertyChangeListener JavaDoc;
21
22 import com.sun.java.swing.plaf.windows.TMSchema.*;
23 import com.sun.java.swing.plaf.windows.XPStyle.Skin;
24
25 public class WindowsInternalFrameTitlePane extends BasicInternalFrameTitlePane JavaDoc {
26     private Color selectedTitleGradientColor;
27     private Color notSelectedTitleGradientColor;
28     private JPopupMenu systemPopupMenu;
29     private JLabel systemLabel;
30
31     private Font titleFont;
32     private int titlePaneHeight;
33     private int buttonWidth, buttonHeight;
34
35     public WindowsInternalFrameTitlePane(JInternalFrame f) {
36         super(f);
37     }
38
39     protected void addSubComponents() {
40         add(systemLabel);
41         add(iconButton);
42         add(maxButton);
43         add(closeButton);
44     }
45
46     protected void installDefaults() {
47         super.installDefaults();
48
49     titlePaneHeight = UIManager.getInt("InternalFrame.titlePaneHeight");
50     buttonWidth = UIManager.getInt("InternalFrame.titleButtonWidth") - 4;
51     buttonHeight = UIManager.getInt("InternalFrame.titleButtonHeight") - 4;
52
53     if (XPStyle.getXP() != null) {
54         // Fix for XP bug where sometimes these sizes aren't updated properly
55
// Assume for now that XP buttons are always square
56
buttonWidth = buttonHeight;
57     } else {
58         buttonWidth += 2;
59         selectedTitleGradientColor =
60             UIManager.getColor("InternalFrame.activeTitleGradient");
61         notSelectedTitleGradientColor =
62             UIManager.getColor("InternalFrame.inactiveTitleGradient");
63         Color activeBorderColor =
64             UIManager.getColor("InternalFrame.activeBorderColor");
65         setBorder(BorderFactory.createLineBorder(activeBorderColor, 1));
66     }
67     }
68
69     protected void uninstallListeners() {
70         // Get around protected method in superclass
71
super.uninstallListeners();
72     }
73
74     protected void createButtons() {
75     super.createButtons();
76     if (XPStyle.getXP() != null) {
77         iconButton.setContentAreaFilled(false);
78         maxButton.setContentAreaFilled(false);
79         closeButton.setContentAreaFilled(false);
80     }
81     }
82
83     public void paintComponent(Graphics g) {
84     XPStyle xp = XPStyle.getXP();
85
86         paintTitleBackground(g);
87
88     String JavaDoc title = frame.getTitle();
89         if (title != null) {
90             boolean isSelected = frame.isSelected();
91             Font oldFont = g.getFont();
92             Font newFont = (titleFont != null) ? titleFont : getFont();
93             g.setFont(newFont);
94
95             // Center text vertically.
96
FontMetrics fm = SwingUtilities2.getFontMetrics(frame, g, newFont);
97             int baseline = (getHeight() + fm.getAscent() - fm.getLeading() -
98                     fm.getDescent()) / 2;
99
100         int titleX;
101         Rectangle r = new Rectangle(0, 0, 0, 0);
102         if (frame.isIconifiable()) r = iconButton.getBounds();
103         else if (frame.isMaximizable()) r = maxButton.getBounds();
104         else if (frame.isClosable()) r = closeButton.getBounds();
105         int titleW;
106
107         if(WindowsGraphicsUtils.isLeftToRight(frame) ) {
108         if (r.x == 0) r.x = frame.getWidth()-frame.getInsets().right;
109             titleX = systemLabel.getX() + systemLabel.getWidth() + 2;
110             if (xp != null) {
111             titleX += 2;
112             }
113             titleW = r.x - titleX - 3;
114             title = getTitle(frame.getTitle(), fm, titleW);
115         } else {
116         titleX = systemLabel.getX() - 2
117              - SwingUtilities2.stringWidth(frame,fm,title);
118         }
119         if (xp != null) {
120         String JavaDoc shadowType = null;
121         if (isSelected) {
122                     shadowType = xp.getString(this, Part.WP_CAPTION,
123                                               State.ACTIVE, Prop.TEXTSHADOWTYPE);
124         }
125         if ("single".equalsIgnoreCase(shadowType)) {
126                     Point shadowOffset = xp.getPoint(this, Part.WP_WINDOW, State.ACTIVE,
127                                                      Prop.TEXTSHADOWOFFSET);
128                     Color shadowColor = xp.getColor(this, Part.WP_WINDOW, State.ACTIVE,
129                                                      Prop.TEXTSHADOWCOLOR, null);
130                     if (shadowOffset != null && shadowColor != null) {
131             g.setColor(shadowColor);
132             SwingUtilities2.drawString(frame, g, title,
133                      titleX + shadowOffset.x,
134                      baseline + shadowOffset.y);
135             }
136         }
137         }
138         g.setColor(isSelected ? selectedTextColor : notSelectedTextColor);
139             SwingUtilities2.drawString(frame, g, title, titleX, baseline);
140             g.setFont(oldFont);
141         }
142     }
143
144     public Dimension getPreferredSize() {
145     return getMinimumSize();
146     }
147
148     public Dimension getMinimumSize() {
149     Dimension d = new Dimension(super.getMinimumSize());
150     d.height = titlePaneHeight + 2;
151
152     XPStyle xp = XPStyle.getXP();
153     if (xp != null) {
154         // Note: Don't know how to calculate height on XP,
155
// the captionbarheight is 25 but native caption is 30 (maximized 26)
156
if (frame.isMaximum()) {
157         d.height -= 1;
158         } else {
159         d.height += 3;
160         }
161     }
162     return d;
163     }
164
165     protected void paintTitleBackground(Graphics g) {
166     XPStyle xp = XPStyle.getXP();
167     if (xp != null) {
168             Part part = frame.isIcon() ? Part.WP_MINCAPTION
169                                        : (frame.isMaximum() ? Part.WP_MAXCAPTION
170                                                             : Part.WP_CAPTION);
171             State state = frame.isSelected() ? State.ACTIVE : State.INACTIVE;
172             Skin skin = xp.getSkin(this, part);
173             skin.paintSkin(g, 0, 0, getWidth(), getHeight(), state);
174     } else {
175         Boolean JavaDoc gradientsOn = (Boolean JavaDoc)LookAndFeel.getDesktopPropertyValue(
176         "win.frame.captionGradientsOn", Boolean.valueOf(false));
177         if (gradientsOn.booleanValue() && g instanceof Graphics2D) {
178         Graphics2D g2 = (Graphics2D)g;
179         Paint savePaint = g2.getPaint();
180
181         boolean isSelected = frame.isSelected();
182         int w = getWidth();
183
184         if (isSelected) {
185             GradientPaint titleGradient = new GradientPaint(0,0,
186                 selectedTitleColor,
187                 (int)(w*.75),0,
188                 selectedTitleGradientColor);
189             g2.setPaint(titleGradient);
190         } else {
191             GradientPaint titleGradient = new GradientPaint(0,0,
192                 notSelectedTitleColor,
193                 (int)(w*.75),0,
194                 notSelectedTitleGradientColor);
195             g2.setPaint(titleGradient);
196         }
197         g2.fillRect(0, 0, getWidth(), getHeight());
198         g2.setPaint(savePaint);
199         } else {
200         super.paintTitleBackground(g);
201         }
202     }
203     }
204
205     protected void assembleSystemMenu() {
206         systemPopupMenu = new JPopupMenu();
207         addSystemMenuItems(systemPopupMenu);
208         enableActions();
209     systemLabel = new JLabel(frame.getFrameIcon()) {
210         protected void paintComponent(Graphics g) {
211         int x = 0;
212         int y = 0;
213         int w = getWidth();
214         int h = getHeight();
215         g = g.create(); // Create scratch graphics
216
if (isOpaque()) {
217             g.setColor(getBackground());
218             g.fillRect(0, 0, w, h);
219         }
220         Icon icon = getIcon();
221         int iconWidth = 0;
222         int iconHeight = 0;
223         if (icon != null &&
224             (iconWidth = icon.getIconWidth()) > 0 &&
225             (iconHeight = icon.getIconHeight()) > 0) {
226
227             // Set drawing scale to make icon scale to our desired size
228
double drawScale;
229             if (iconWidth > iconHeight) {
230             // Center icon vertically
231
y = (h - w*iconHeight/iconWidth) / 2;
232             drawScale = w / (double)iconWidth;
233             } else {
234             // Center icon horizontally
235
x = (w - h*iconWidth/iconHeight) / 2;
236             drawScale = h / (double)iconHeight;
237             }
238             ((Graphics2D)g).translate(x, y);
239             ((Graphics2D)g).scale(drawScale, drawScale);
240             icon.paintIcon(this, g, 0, 0);
241         }
242         g.dispose();
243         }
244     };
245         systemLabel.addMouseListener(new MouseAdapter() {
246             public void mousePressed(MouseEvent e) {
247         showSystemPopupMenu(e.getComponent());
248             }
249         });
250     }
251
252     protected void addSystemMenuItems(JPopupMenu menu) {
253         JMenuItem mi = (JMenuItem)menu.add(restoreAction);
254         mi.setMnemonic('R');
255         mi = (JMenuItem)menu.add(moveAction);
256         mi.setMnemonic('M');
257         mi = (JMenuItem)menu.add(sizeAction);
258         mi.setMnemonic('S');
259         mi = (JMenuItem)menu.add(iconifyAction);
260         mi.setMnemonic('n');
261         mi = (JMenuItem)menu.add(maximizeAction);
262         mi.setMnemonic('x');
263         systemPopupMenu.add(new JSeparator());
264         mi = (JMenuItem)menu.add(closeAction);
265         mi.setMnemonic('C');
266     }
267
268     protected void showSystemMenu(){
269     showSystemPopupMenu(systemLabel);
270     }
271
272     private void showSystemPopupMenu(Component invoker){
273     Dimension dim = new Dimension();
274     Border border = frame.getBorder();
275     if (border != null) {
276         dim.width += border.getBorderInsets(frame).left +
277         border.getBorderInsets(frame).right;
278         dim.height += border.getBorderInsets(frame).bottom +
279         border.getBorderInsets(frame).top;
280     }
281     if (!frame.isIcon()) {
282         systemPopupMenu.show(invoker,
283                 getX() - dim.width,
284                 getY() + getHeight() - dim.height);
285     } else {
286         systemPopupMenu.show(invoker,
287                 getX() - dim.width,
288                 getY() - systemPopupMenu.getPreferredSize().height -
289              dim.height);
290     }
291     }
292
293     protected PropertyChangeListener JavaDoc createPropertyChangeListener() {
294         return new WindowsPropertyChangeHandler();
295     }
296
297     protected LayoutManager createLayout() {
298         return new WindowsTitlePaneLayout();
299     }
300
301     public class WindowsTitlePaneLayout extends BasicInternalFrameTitlePane.TitlePaneLayout JavaDoc {
302     private Insets captionMargin = null;
303     private Insets contentMargin = null;
304     private XPStyle xp = XPStyle.getXP();
305
306     WindowsTitlePaneLayout() {
307         if (xp != null) {
308         Component c = WindowsInternalFrameTitlePane.this;
309                 captionMargin = xp.getMargin(c, Part.WP_CAPTION, null, Prop.CAPTIONMARGINS);
310                 contentMargin = xp.getMargin(c, Part.WP_CAPTION, null, Prop.CONTENTMARGINS);
311         }
312         if (captionMargin == null) {
313         captionMargin = new Insets(0, 2, 0, 2);
314         }
315         if (contentMargin == null) {
316         contentMargin = new Insets(0, 0, 0, 0);
317         }
318     }
319
320         private int layoutButton(JComponent button, Part part,
321                  int x, int y, int w, int h, int gap,
322                  boolean leftToRight) {
323         if (!leftToRight) {
324         x -= w;
325         }
326         button.setBounds(x, y, w, h);
327         if (leftToRight) {
328         x += w + 2;
329         } else {
330         x -= 2;
331         }
332         return x;
333     }
334
335         public void layoutContainer(Container c) {
336             boolean leftToRight = WindowsGraphicsUtils.isLeftToRight(frame);
337         int x, y;
338             int w = getWidth();
339             int h = getHeight();
340
341         // System button
342
// Note: this icon is square, but the buttons aren't always.
343
int iconSize = (xp != null) ? (h-2)*6/10 : h-4;
344         if (xp != null) {
345         x = (leftToRight) ? captionMargin.left + 2 : w - captionMargin.right - 2;
346         } else {
347         x = (leftToRight) ? captionMargin.left : w - captionMargin.right;
348         }
349         y = (h - iconSize) / 2;
350             layoutButton(systemLabel, Part.WP_SYSBUTTON,
351              x, y, iconSize, iconSize, 0,
352              leftToRight);
353
354         // Right hand buttons
355
if (xp != null) {
356         x = (leftToRight) ? w - captionMargin.right - 2 : captionMargin.left + 2;
357         y = 1; // XP seems to ignore margins and offset here
358
if (frame.isMaximum()) {
359             y += 1;
360         } else {
361             y += 5;
362         }
363         } else {
364         x = (leftToRight) ? w - captionMargin.right : captionMargin.left;
365         y = (h - buttonHeight) / 2;
366         }
367
368         if(frame.isClosable()) {
369                 x = layoutButton(closeButton, Part.WP_CLOSEBUTTON,
370                  x, y, buttonWidth, buttonHeight, 2,
371                  !leftToRight);
372         }
373
374         if(frame.isMaximizable()) {
375                 x = layoutButton(maxButton, Part.WP_MAXBUTTON,
376                  x, y, buttonWidth, buttonHeight, (xp != null) ? 2 : 0,
377                  !leftToRight);
378         }
379
380         if(frame.isIconifiable()) {
381                 layoutButton(iconButton, Part.WP_MINBUTTON,
382                  x, y, buttonWidth, buttonHeight, 0,
383                  !leftToRight);
384         }
385     }
386     } // end WindowsTitlePaneLayout
387

388     public class WindowsPropertyChangeHandler extends PropertyChangeHandler {
389         public void propertyChange(PropertyChangeEvent JavaDoc evt) {
390         String JavaDoc prop = (String JavaDoc)evt.getPropertyName();
391
392             // Update the internal frame icon for the system menu.
393
if (JInternalFrame.FRAME_ICON_PROPERTY.equals(prop) &&
394                     systemLabel != null) {
395                 systemLabel.setIcon(frame.getFrameIcon());
396             }
397
398             super.propertyChange(evt);
399         }
400     }
401
402     /**
403      * A versatile Icon implementation which can take an array of Icon
404      * instances (typically <code>ImageIcon</code>s) and choose one that gives the best
405      * quality for a given Graphics2D scale factor when painting.
406      * <p>
407      * The class is public so it can be instantiated by UIDefaults.ProxyLazyValue.
408      * <p>
409      * Note: We assume here that icons are square.
410      */

411     public static class ScalableIconUIResource implements Icon, UIResource {
412     // We can use an arbitrary size here because we scale to it in paintIcon()
413
private static final int SIZE = 16;
414
415     private Icon[] icons;
416
417     /**
418      * @params objects an array of Icon or UIDefaults.LazyValue
419      * <p>
420      * The constructor is public so it can be called by UIDefaults.ProxyLazyValue.
421      */

422     public ScalableIconUIResource(Object JavaDoc[] objects) {
423         this.icons = new Icon[objects.length];
424
425         for (int i = 0; i < objects.length; i++) {
426         if (objects[i] instanceof UIDefaults.LazyValue) {
427             icons[i] = (Icon)((UIDefaults.LazyValue)objects[i]).createValue(null);
428         } else {
429             icons[i] = (Icon)objects[i];
430         }
431         }
432     }
433
434     /**
435      * @return the <code>Icon</code> closest to the requested size
436      */

437     protected Icon getBestIcon(int size) {
438         if (icons != null && icons.length > 0) {
439         int bestIndex = 0;
440         int minDiff = Integer.MAX_VALUE;
441         for (int i=0; i < icons.length; i++) {
442             Icon icon = icons[i];
443             int iconSize;
444             if (icon != null && (iconSize = icon.getIconWidth()) > 0) {
445             int diff = Math.abs(iconSize - size);
446             if (diff < minDiff) {
447                 minDiff = diff;
448                 bestIndex = i;
449             }
450             }
451         }
452         return icons[bestIndex];
453         } else {
454         return null;
455         }
456     }
457
458     public void paintIcon(Component c, Graphics g, int x, int y) {
459         Graphics2D g2d = (Graphics2D)g.create();
460         // Calculate how big our drawing area is in pixels
461
// Assume we are square
462
int size = getIconWidth();
463         double scale = g2d.getTransform().getScaleX();
464         Icon icon = getBestIcon((int)(size * scale));
465         int iconSize;
466         if (icon != null && (iconSize = icon.getIconWidth()) > 0) {
467         // Set drawing scale to make icon act true to our reported size
468
double drawScale = size / (double)iconSize;
469         g2d.translate(x, y);
470         g2d.scale(drawScale, drawScale);
471         icon.paintIcon(c, g2d, 0, 0);
472         }
473         g2d.dispose();
474     }
475     
476     public int getIconWidth() {
477         return SIZE;
478     }
479
480     public int getIconHeight() {
481         return SIZE;
482     }
483     }
484 }
485
Popular Tags