KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > swing > tabcontrol > plaf > WinXPViewTabDisplayerUI


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.swing.tabcontrol.plaf;
21
22 import org.netbeans.swing.tabcontrol.TabDisplayer;
23
24 import javax.swing.*;
25 import javax.swing.plaf.ComponentUI JavaDoc;
26 import java.awt.*;
27 import java.awt.event.MouseEvent JavaDoc;
28
29 import java.util.HashMap JavaDoc;
30 import java.util.Map JavaDoc;
31 import org.netbeans.swing.tabcontrol.event.TabActionEvent;
32
33
34 import org.openide.awt.HtmlRenderer;
35
36 /**
37  * Win XP-like user interface of view type tabs.
38  *
39  * @author Dafe Simonek
40  */

41 public final class WinXPViewTabDisplayerUI extends AbstractViewTabDisplayerUI {
42
43     /*********** constants *************/
44
45     /**
46      * Space between text and left side of the tab
47      */

48     private static final int TXT_X_PAD = 8;
49     private static final int TXT_Y_PAD = 3;
50
51     private static final int ICON_X_PAD = 2;
52
53     private static final int BUMP_X_PAD = 3;
54     private static final int BUMP_Y_PAD_UPPER = 5;
55     private static final int BUMP_Y_PAD_BOTTOM = 3;
56
57     private static final int HIGHLIGHTED_RAISE = 1;
58
59     /*********** static fields **********/
60     
61     /**
62      * True when colors were already initialized, false otherwise
63      */

64     private static boolean colorsReady = false;
65
66     private static Color unselFillBrightC, unselFillDarkC, selFillC, focusFillBrightC, focusFillDarkC, txtC, borderC, bottomBorderC, selBorderC, bgFillC;
67     
68     private static Map JavaDoc<Integer JavaDoc, String JavaDoc[]> buttonIconPaths;
69
70     /**
71      * ******** instance fields ********
72      */

73
74     private Dimension prefSize;
75
76     /**
77      * rectangle instance used to speedup recurring computations in painting
78      * methods
79      */

80     private Rectangle tempRect = new Rectangle();
81
82     /**
83      * Should be constructed only from createUI method.
84      */

85     private WinXPViewTabDisplayerUI(TabDisplayer displayer) {
86         super(displayer);
87         prefSize = new Dimension(100, 17);
88     }
89
90     public static ComponentUI JavaDoc createUI(JComponent c) {
91         return new WinXPViewTabDisplayerUI((TabDisplayer)c);
92     }
93      
94     public void installUI (JComponent c) {
95         super.installUI(c);
96         initColors();
97         initIcons();
98         c.setOpaque(true);
99     }
100
101     protected AbstractViewTabDisplayerUI.Controller createController() {
102         return new OwnController();
103     }
104
105     public Dimension getPreferredSize(JComponent c) {
106         FontMetrics fm = getTxtFontMetrics();
107         int height = fm == null ?
108                 17 : fm.getAscent() + 2 * fm.getDescent() + 3;
109         Insets insets = c.getInsets();
110         prefSize.height = height + insets.bottom + insets.top;
111         return prefSize;
112     }
113
114     protected void paintTabContent(Graphics g, int index, String JavaDoc text, int x,
115                                    int y, int width, int height) {
116         FontMetrics fm = getTxtFontMetrics();
117         // setting font already here to compute string width correctly
118
g.setFont(getTxtFont());
119         // highlighted one is higher then others
120
if (!isTabInFront(index) && isMoreThanOne()) {
121             y += HIGHLIGHTED_RAISE;
122             height -= HIGHLIGHTED_RAISE;
123         }
124         int txtWidth = width;
125         if (isSelected(index)) {
126             Component buttons = getControlButtons();
127             if( null != buttons ) {
128                 Dimension buttonsSize = buttons.getPreferredSize();
129                 txtWidth = width - (buttonsSize.width + ICON_X_PAD + 2*TXT_X_PAD);
130                 buttons.setLocation( x + txtWidth+2*TXT_X_PAD, y + (height-buttonsSize.height)/2 );
131             }
132         } else {
133             txtWidth = width - 2 * TXT_X_PAD;
134         }
135         
136         int highlightedRaiseCompensation = (!isTabInFront(index) && isMoreThanOne()) ? HIGHLIGHTED_RAISE : 0;
137         // draw bump (dragger)
138
ColorUtil.paintXpTabDragTexture(getDisplayer(), g, x + BUMP_X_PAD, y
139                  + BUMP_Y_PAD_UPPER, height - (BUMP_Y_PAD_UPPER
140                  + BUMP_Y_PAD_BOTTOM)+highlightedRaiseCompensation);
141         HtmlRenderer.renderString(text, g, x + TXT_X_PAD, y + fm.getAscent()
142                 + TXT_Y_PAD, txtWidth, height, getTxtFont(),
143                 txtC,
144                 HtmlRenderer.STYLE_TRUNCATE, true);
145     }
146
147     protected void paintTabBorder(Graphics g, int index, int x, int y,
148                                   int width, int height) {
149         boolean isFirst = index == 0;
150         boolean isHighlighted = isTabHighlighted(index);
151
152         g.translate(x, y);
153
154         ColorUtil.paintXpTabHeader(isHighlighted ?
155                                    ColorUtil.XP_HIGHLIGHTED_TAB :
156                                    ColorUtil.XP_REGULAR_TAB, g, 0,
157                                    0, width);
158         Color borderColor = isHighlighted ? selBorderC : borderC;
159         g.setColor(borderColor);
160         if (isFirst) {
161             g.drawLine(0, 3, 0, height - 2);
162         }
163         g.drawLine(width - 1, 3, width - 1, height - 2);
164         g.setColor(bottomBorderC);
165         g.drawLine(0, height - 1, width - 1, height - 1);
166
167         g.translate(-x, -y);
168     }
169
170     protected void paintTabBackground(Graphics g, int index, int x, int y,
171                                       int width, int height) {
172         // shrink rectangle - don't affect border and tab header
173
y += 3;
174         width -= 1;
175         height -= 4;
176         // background body, colored according to state
177
boolean selected = isSelected(index);
178         boolean focused = selected && isActive();
179         boolean attention = isAttention(index);
180         if (focused && !attention) {
181             ColorUtil.xpFillRectGradient((Graphics2D) g, x, y, width, height,
182                                          focusFillBrightC, focusFillDarkC);
183         } else if (selected && isMoreThanOne() && !attention) {
184             g.setColor(selFillC);
185             g.fillRect(x, y, width, height);
186         } else if (attention) {
187             Color a = new Color (255, 255, 128);
188             Color b = new Color (230, 200, 64);
189             ColorUtil.xpFillRectGradient((Graphics2D) g, x, y, width, height,
190                                          a, b);
191         } else {
192             ColorUtil.xpFillRectGradient((Graphics2D) g, x, y, width, height,
193                                          unselFillBrightC, unselFillDarkC);
194         }
195     }
196
197     /**
198      * Override to bold font
199      */

200     protected Font getTxtFont() {
201         Font font = super.getTxtFont();
202         if (!font.isBold()) {
203             font = font.deriveFont(Font.BOLD);
204         }
205         return font;
206     }
207
208     /**
209      * @return true if tab with given index should be highlighted with XP
210      * highlight header, false otherwise.
211      */

212     private boolean isTabHighlighted(int index) {
213         if (((OwnController) getController()).getMouseIndex() == index) {
214             return true;
215         }
216         return isTabInFront(index) && isMoreThanOne();
217     }
218
219     /**
220      * @return true if tab is selected in other tabs or selected and also
221      * active
222      */

223     private boolean isTabInFront(int index) {
224         return isSelected(index) && (isActive() || isMoreThanOne());
225     }
226
227     /**
228      * @return true if there is more then one tab, false otherwise
229      */

230     private boolean isMoreThanOne() {
231         return getDataModel().size() > 1;
232     }
233
234     /**
235      * Initialization of colors
236      */

237     private static void initColors() {
238         if (!colorsReady) {
239             txtC = UIManager.getColor("TabbedPane.foreground"); // NOI18N
240
selFillC = UIManager.getColor("TabbedPane.highlight"); // NOI18N
241
focusFillBrightC = UIManager.getColor("tab_focus_fill_bright"); // NOI18N
242
focusFillDarkC = UIManager.getColor("tab_focus_fill_dark"); // NOI18N
243
unselFillBrightC = UIManager.getColor("tab_unsel_fill_bright"); // NOI18N
244
unselFillDarkC = UIManager.getColor("tab_unsel_fill_dark"); // NOI18N
245
borderC = UIManager.getColor("tab_border"); // NOI18N
246
bottomBorderC = UIManager.getColor("tab_bottom_border"); // NOI18N
247
selBorderC = UIManager.getColor("tab_sel_border"); // NOI18N
248
bgFillC = UIManager.getColor("workplace_fill"); // NOI18N
249
colorsReady = true;
250         }
251     }
252     
253     private static void initIcons() {
254         if( null == buttonIconPaths ) {
255             buttonIconPaths = new HashMap JavaDoc<Integer JavaDoc, String JavaDoc[]>(7);
256             
257             //close button
258
String JavaDoc[] iconPaths = new String JavaDoc[4];
259             iconPaths[TabControlButton.STATE_DEFAULT] = "org/netbeans/swing/tabcontrol/resources/xp_bigclose_enabled.png"; // NOI18N
260
iconPaths[TabControlButton.STATE_PRESSED] = "org/netbeans/swing/tabcontrol/resources/xp_bigclose_pressed.png"; // NOI18N
261
iconPaths[TabControlButton.STATE_DISABLED] = iconPaths[TabControlButton.STATE_DEFAULT];
262             iconPaths[TabControlButton.STATE_ROLLOVER] = "org/netbeans/swing/tabcontrol/resources/xp_bigclose_rollover.png"; // NOI18N
263
buttonIconPaths.put( TabControlButton.ID_CLOSE_BUTTON, iconPaths );
264             
265             //slide/pin button
266
iconPaths = new String JavaDoc[4];
267             iconPaths[TabControlButton.STATE_DEFAULT] = "org/netbeans/swing/tabcontrol/resources/xp_slideright_enabled.png"; // NOI18N
268
iconPaths[TabControlButton.STATE_PRESSED] = "org/netbeans/swing/tabcontrol/resources/xp_slideright_pressed.png"; // NOI18N
269
iconPaths[TabControlButton.STATE_DISABLED] = iconPaths[TabControlButton.STATE_DEFAULT];
270             iconPaths[TabControlButton.STATE_ROLLOVER] = "org/netbeans/swing/tabcontrol/resources/xp_slideright_rollover.png"; // NOI18N
271
buttonIconPaths.put( TabControlButton.ID_SLIDE_RIGHT_BUTTON, iconPaths );
272             
273             iconPaths = new String JavaDoc[4];
274             iconPaths[TabControlButton.STATE_DEFAULT] = "org/netbeans/swing/tabcontrol/resources/xp_slideleft_enabled.png"; // NOI18N
275
iconPaths[TabControlButton.STATE_PRESSED] = "org/netbeans/swing/tabcontrol/resources/xp_slideleft_pressed.png"; // NOI18N
276
iconPaths[TabControlButton.STATE_DISABLED] = iconPaths[TabControlButton.STATE_DEFAULT];
277             iconPaths[TabControlButton.STATE_ROLLOVER] = "org/netbeans/swing/tabcontrol/resources/xp_slideleft_rollover.png"; // NOI18N
278
buttonIconPaths.put( TabControlButton.ID_SLIDE_LEFT_BUTTON, iconPaths );
279             
280             iconPaths = new String JavaDoc[4];
281             iconPaths[TabControlButton.STATE_DEFAULT] = "org/netbeans/swing/tabcontrol/resources/xp_slidebottom_enabled.png"; // NOI18N
282
iconPaths[TabControlButton.STATE_PRESSED] = "org/netbeans/swing/tabcontrol/resources/xp_slidebottom_pressed.png"; // NOI18N
283
iconPaths[TabControlButton.STATE_DISABLED] = iconPaths[TabControlButton.STATE_DEFAULT];
284             iconPaths[TabControlButton.STATE_ROLLOVER] = "org/netbeans/swing/tabcontrol/resources/xp_slidebottom_rollover.png"; // NOI18N
285
buttonIconPaths.put( TabControlButton.ID_SLIDE_DOWN_BUTTON, iconPaths );
286             
287             iconPaths = new String JavaDoc[4];
288             iconPaths[TabControlButton.STATE_DEFAULT] = "org/netbeans/swing/tabcontrol/resources/xp_pin_enabled.png"; // NOI18N
289
iconPaths[TabControlButton.STATE_PRESSED] = "org/netbeans/swing/tabcontrol/resources/xp_pin_pressed.png"; // NOI18N
290
iconPaths[TabControlButton.STATE_DISABLED] = iconPaths[TabControlButton.STATE_DEFAULT];
291             iconPaths[TabControlButton.STATE_ROLLOVER] = "org/netbeans/swing/tabcontrol/resources/xp_pin_rollover.png"; // NOI18N
292
buttonIconPaths.put( TabControlButton.ID_PIN_BUTTON, iconPaths );
293         }
294     }
295
296     public Icon getButtonIcon(int buttonId, int buttonState) {
297         Icon res = null;
298         initIcons();
299         String JavaDoc[] paths = buttonIconPaths.get( buttonId );
300         if( null != paths && buttonState >=0 && buttonState < paths.length ) {
301             res = TabControlButtonFactory.getIcon( paths[buttonState] );
302         }
303         return res;
304     }
305
306     public void postTabAction(TabActionEvent e) {
307         super.postTabAction(e);
308         if( TabDisplayer.COMMAND_MAXIMIZE.equals( e.getActionCommand() ) ) {
309             ((OwnController)getController()).updateHighlight( -1 );
310         }
311     }
312     
313     /**
314      * Own close icon button controller
315      */

316     private class OwnController extends Controller {
317
318         /**
319          * holds index of tab in which mouse pointer was lastly located. -1
320          * means mouse pointer is out of component's area
321          */

322         // TBD - should be part of model, not controller
323
private int lastIndex = -1;
324
325         /**
326          * @return Index of tab in which mouse pointer is currently located.
327          */

328         public int getMouseIndex() {
329             return lastIndex;
330         }
331         
332         /**
333          * Triggers visual tab header change when mouse enters/leaves tab in
334          * advance to superclass functionality.
335          */

336         public void mouseMoved(MouseEvent JavaDoc e) {
337             super.mouseMoved(e);
338             Point pos = e.getPoint();
339             if( !e.getSource().equals( displayer ) ) {
340                 pos = SwingUtilities.convertPoint( (Component) e.getSource(), pos, displayer );
341             }
342             updateHighlight(getLayoutModel().indexOfPoint(pos.x, pos.y));
343         }
344
345         /**
346          * Resets tab header in advance to superclass functionality
347          */

348         public void mouseExited(MouseEvent JavaDoc e) {
349             super.mouseExited(e);
350             if( !inControlButtonsRect(e.getPoint())) {
351                 updateHighlight(-1);
352             }
353         }
354
355         /**
356          * Invokes repaint of dirty region if needed
357          */

358         private void updateHighlight(int curIndex) {
359             if (curIndex == lastIndex) {
360                 return;
361             }
362             // compute region which needs repaint
363
TabLayoutModel tlm = getLayoutModel();
364             int x, y, w, h;
365             Rectangle repaintRect = null;
366             if (curIndex != -1) {
367                 x = tlm.getX(curIndex);
368                 y = tlm.getY(curIndex);
369                 w = tlm.getW(curIndex);
370                 h = tlm.getH(curIndex);
371                 repaintRect = new Rectangle(x, y, w, h);
372             }
373             // due to model changes, lastIndex may become invalid, so check
374
if ((lastIndex != -1) && (lastIndex < getDataModel().size())) {
375                 x = tlm.getX(lastIndex);
376                 y = tlm.getY(lastIndex);
377                 w = tlm.getW(lastIndex);
378                 h = tlm.getH(lastIndex);
379                 if (repaintRect != null) {
380                     repaintRect =
381                             repaintRect.union(new Rectangle(x, y, w, h));
382                 } else {
383                     repaintRect = new Rectangle(x, y, w, h);
384                 }
385             }
386             // trigger repaint if needed, update index
387
if (repaintRect != null) {
388                 getDisplayer().repaint(repaintRect);
389             }
390             lastIndex = curIndex;
391         }
392
393         public void mouseEntered(MouseEvent JavaDoc e) {
394             super.mouseEntered(e);
395             mouseMoved( e );
396         }
397
398
399     } // end of OwnController
400
}
401
Popular Tags