001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: /*
042: * WinClassicEditorTabDisplayerUI.java
043: *
044: * Created on 09 December 2003, 16:53
045: */
046:
047: package org.netbeans.swing.tabcontrol.plaf;
048:
049: import java.awt.Component;
050: import java.awt.Container;
051: import java.awt.Dimension;
052: import java.awt.FontMetrics;
053: import java.awt.GradientPaint;
054: import java.awt.Graphics;
055: import java.awt.Graphics2D;
056: import java.awt.Insets;
057: import java.awt.Rectangle;
058: import java.util.HashMap;
059: import java.util.Map;
060: import javax.swing.Icon;
061: import javax.swing.JComponent;
062: import javax.swing.UIManager;
063: import org.netbeans.swing.tabcontrol.TabDisplayer;
064:
065: import javax.swing.plaf.ComponentUI;
066:
067: /**
068: * Windows classic impl of tabs ui
069: *
070: * @author Tim Boudreau
071: */
072: public final class WinClassicEditorTabDisplayerUI extends
073: BasicScrollingTabDisplayerUI {
074:
075: private static final Rectangle scratch5 = new Rectangle();
076: private static Map<Integer, String[]> buttonIconPaths;
077:
078: private static boolean isGenericUI = !"Windows".equals( //NOI18N
079: UIManager.getLookAndFeel().getID());
080:
081: /**
082: * Creates a new instance of WinClassicEditorTabDisplayerUI
083: */
084: public WinClassicEditorTabDisplayerUI(TabDisplayer displayer) {
085: super (displayer);
086: }
087:
088: public static ComponentUI createUI(JComponent c) {
089: return new WinClassicEditorTabDisplayerUI((TabDisplayer) c);
090: }
091:
092: public Rectangle getTabRect(int idx, Rectangle rect) {
093: Rectangle r = super .getTabRect(idx, rect);
094: //For win classic, take up the full space, even the insets, to match
095: //earlier appearance
096: r.y = 0;
097: r.height = displayer.getHeight();
098: return r;
099: }
100:
101: public void install() {
102: super .install();
103: if (!isGenericUI) {
104: displayer.setBackground(UIManager
105: .getColor("tab_unsel_fill"));
106: displayer.setOpaque(true);
107: }
108: }
109:
110: public Dimension getPreferredSize(JComponent c) {
111: int prefHeight = 28;
112: Graphics g = BasicScrollingTabDisplayerUI
113: .getOffscreenGraphics();
114: if (g != null) {
115: FontMetrics fm = g.getFontMetrics(displayer.getFont());
116: Insets ins = getTabAreaInsets();
117: prefHeight = fm.getHeight() + ins.top + ins.bottom
118: + (isGenericUI ? 5 : 6);
119: }
120: return new Dimension(displayer.getWidth(), prefHeight);
121: }
122:
123: private void genericPaintAfterTabs(Graphics g) {
124: g.setColor(UIManager.getColor("controlShadow")); //NOI18N
125: Insets ins = displayer.getInsets();
126: Rectangle r = new Rectangle();
127: getTabsVisibleArea(r);
128: r.width = displayer.getWidth();
129: int selEnd = 0;
130: int last = getLastVisibleTab();
131: if (last > -1) {
132: getTabRect(last, scratch5);
133: g.drawLine(scratch5.x + scratch5.width, displayer
134: .getHeight() - 1, displayer.getWidth()
135: - (ins.left + ins.right) - 4,
136: displayer.getHeight() - 1);
137: g.drawLine(0, displayer.getHeight() - 2, 2, displayer
138: .getHeight() - 2);
139: //TODO remove when a specific GTK l&f UI class is available
140: if ("GTK".equals(UIManager.getLookAndFeel().getID())) {
141: boolean sel = last == displayer.getSelectionModel()
142: .getSelectedIndex();
143: //paint a fading shadow to match the view tabs
144: int x = scratch5.x + scratch5.width;
145: g.setColor(sel ? UIManager.getColor("controlShadow")
146: : ColorUtil.adjustTowards(g.getColor(), 20,
147: UIManager.getColor("control"))); //NOI18N
148: g.drawLine(x, scratch5.y + 5, x, scratch5.y
149: + scratch5.height - 2);
150: g.setColor(ColorUtil.adjustTowards(g.getColor(), 20,
151: UIManager.getColor("control"))); //NOI18N
152: g.drawLine(x + 1, scratch5.y + 6, x + 1, scratch5.y
153: + scratch5.height - 2);
154: }
155: if ((tabState.getState(getFirstVisibleTab()) & TabState.CLIP_LEFT) != 0
156: && getFirstVisibleTab() != displayer
157: .getSelectionModel().getSelectedIndex()) {
158: //Draw a small gradient line continuing the left edge of
159: //the displayer up the left side of a left clipped tab
160: GradientPaint gp = ColorUtil.getGradientPaint(0,
161: displayer.getHeight() / 2, UIManager
162: .getColor("control"), 0, displayer
163: .getHeight(), UIManager
164: .getColor("controlShadow"));
165: ((Graphics2D) g).setPaint(gp);
166: g.drawLine(0, displayer.getHeight() / 2, 0, displayer
167: .getHeight());
168: } else {
169: //Fill the small gap between the top of the content displayer
170: //and the bottom of the tabs, caused by the tab area bottom inset
171: g.setColor(UIManager.getColor("controlShadow"));
172: g.drawLine(0, displayer.getHeight(), 0, displayer
173: .getHeight() - 2);
174: }
175: if ((tabState.getState(getLastVisibleTab()) & TabState.CLIP_RIGHT) != 0
176: && getLastVisibleTab() != displayer
177: .getSelectionModel().getSelectedIndex()) {
178: GradientPaint gp = ColorUtil.getGradientPaint(0,
179: displayer.getHeight() / 2, UIManager
180: .getColor("control"), 0, displayer
181: .getHeight(), UIManager
182: .getColor("controlShadow"));
183: ((Graphics2D) g).setPaint(gp);
184: getTabRect(getLastVisibleTab(), scratch5);
185: g.drawLine(scratch5.x + scratch5.width, displayer
186: .getHeight() / 2, scratch5.x + scratch5.width,
187: displayer.getHeight());
188: }
189:
190: } else {
191: g.drawLine(r.x, displayer.getHeight() - ins.bottom, r.x
192: + r.width - 4, displayer.getHeight() - ins.bottom);
193: }
194: }
195:
196: protected void paintAfterTabs(Graphics g) {
197: if (isGenericUI) {
198: genericPaintAfterTabs(g);
199: return;
200: }
201: Rectangle r = new Rectangle();
202: getTabsVisibleArea(r);
203: r.width = displayer.getWidth();
204: g.setColor(displayer.isActive() ? defaultRenderer
205: .getSelectedActivatedBackground() : defaultRenderer
206: .getSelectedBackground());
207:
208: Insets ins = getTabAreaInsets();
209: ins.bottom++;
210: g.fillRect(r.x, r.y + r.height, r.x + r.width, displayer
211: .getHeight()
212: - (r.y + r.height));
213:
214: g.setColor(UIManager.getColor("controlLtHighlight")); //NOI18N
215:
216: int selEnd = 0;
217: int i = selectionModel.getSelectedIndex();
218: if (i != -1) {
219: getTabRect(i, scratch5);
220: if (scratch5.width != 0) {
221: if (r.x < scratch5.x) {
222: g.drawLine(r.x, displayer.getHeight() - ins.bottom,
223: scratch5.x - 1, displayer.getHeight()
224: - ins.bottom);
225: }
226: if (scratch5.x + scratch5.width < r.x + r.width) {
227: selEnd = scratch5.x + scratch5.width;
228: //If the last tab is not clipped, the final tab is one
229: //pixel smaller; we need to overwrite one pixel of the
230: //border or there will be a small stub sticking down
231: if (!scroll().isLastTabClipped()) {
232: selEnd--;
233: }
234: g.drawLine(selEnd, displayer.getHeight()
235: - ins.bottom, r.x + r.width, displayer
236: .getHeight()
237: - ins.bottom);
238: }
239: }
240: return;
241: }
242:
243: g.drawLine(r.x, displayer.getHeight() - ins.bottom, r.x
244: + r.width, displayer.getHeight() - ins.bottom);
245: }
246:
247: protected TabCellRenderer createDefaultRenderer() {
248: return new WinClassicEditorTabCellRenderer();
249: }
250:
251: private static void initIcons() {
252: if (null == buttonIconPaths) {
253: buttonIconPaths = new HashMap<Integer, String[]>(7);
254:
255: //left button
256: String[] iconPaths = new String[4];
257: iconPaths[TabControlButton.STATE_DEFAULT] = "org/netbeans/swing/tabcontrol/resources/win_scrollleft_enabled.png"; // NOI18N
258: iconPaths[TabControlButton.STATE_DISABLED] = "org/netbeans/swing/tabcontrol/resources/win_scrollleft_disabled.png"; // NOI18N
259: iconPaths[TabControlButton.STATE_ROLLOVER] = "org/netbeans/swing/tabcontrol/resources/win_scrollleft_rollover.png"; // NOI18N
260: iconPaths[TabControlButton.STATE_PRESSED] = "org/netbeans/swing/tabcontrol/resources/win_scrollleft_pressed.png"; // NOI18N
261: buttonIconPaths.put(TabControlButton.ID_SCROLL_LEFT_BUTTON,
262: iconPaths);
263:
264: //right button
265: iconPaths = new String[4];
266: iconPaths[TabControlButton.STATE_DEFAULT] = "org/netbeans/swing/tabcontrol/resources/win_scrollright_enabled.png"; // NOI18N
267: iconPaths[TabControlButton.STATE_DISABLED] = "org/netbeans/swing/tabcontrol/resources/win_scrollright_disabled.png"; // NOI18N
268: iconPaths[TabControlButton.STATE_ROLLOVER] = "org/netbeans/swing/tabcontrol/resources/win_scrollright_rollover.png"; // NOI18N
269: iconPaths[TabControlButton.STATE_PRESSED] = "org/netbeans/swing/tabcontrol/resources/win_scrollright_pressed.png"; // NOI18N
270: buttonIconPaths.put(
271: TabControlButton.ID_SCROLL_RIGHT_BUTTON, iconPaths);
272:
273: //drop down button
274: iconPaths = new String[4];
275: iconPaths[TabControlButton.STATE_DEFAULT] = "org/netbeans/swing/tabcontrol/resources/win_popup_enabled.png"; // NOI18N
276: iconPaths[TabControlButton.STATE_DISABLED] = "org/netbeans/swing/tabcontrol/resources/win_popup_disabled.png"; // NOI18N
277: iconPaths[TabControlButton.STATE_ROLLOVER] = "org/netbeans/swing/tabcontrol/resources/win_popup_rollover.png"; // NOI18N
278: iconPaths[TabControlButton.STATE_PRESSED] = "org/netbeans/swing/tabcontrol/resources/win_popup_pressed.png"; // NOI18N
279: buttonIconPaths.put(TabControlButton.ID_DROP_DOWN_BUTTON,
280: iconPaths);
281:
282: //maximize/restore button
283: iconPaths = new String[4];
284: iconPaths[TabControlButton.STATE_DEFAULT] = "org/netbeans/swing/tabcontrol/resources/win_maximize_enabled.png"; // NOI18N
285: iconPaths[TabControlButton.STATE_DISABLED] = "org/netbeans/swing/tabcontrol/resources/win_maximize_disabled.png"; // NOI18N
286: iconPaths[TabControlButton.STATE_ROLLOVER] = "org/netbeans/swing/tabcontrol/resources/win_maximize_rollover.png"; // NOI18N
287: iconPaths[TabControlButton.STATE_PRESSED] = "org/netbeans/swing/tabcontrol/resources/win_maximize_pressed.png"; // NOI18N
288: buttonIconPaths.put(TabControlButton.ID_MAXIMIZE_BUTTON,
289: iconPaths);
290:
291: iconPaths = new String[4];
292: iconPaths[TabControlButton.STATE_DEFAULT] = "org/netbeans/swing/tabcontrol/resources/win_restore_enabled.png"; // NOI18N
293: iconPaths[TabControlButton.STATE_DISABLED] = "org/netbeans/swing/tabcontrol/resources/win_restore_disabled.png"; // NOI18N
294: iconPaths[TabControlButton.STATE_ROLLOVER] = "org/netbeans/swing/tabcontrol/resources/win_restore_rollover.png"; // NOI18N
295: iconPaths[TabControlButton.STATE_PRESSED] = "org/netbeans/swing/tabcontrol/resources/win_restore_pressed.png"; // NOI18N
296: buttonIconPaths.put(TabControlButton.ID_RESTORE_BUTTON,
297: iconPaths);
298: }
299: }
300:
301: public Icon getButtonIcon(int buttonId, int buttonState) {
302: Icon res = null;
303: initIcons();
304: String[] paths = buttonIconPaths.get(buttonId);
305: if (null != paths && buttonState >= 0
306: && buttonState < paths.length) {
307: res = TabControlButtonFactory.getIcon(paths[buttonState]);
308: }
309: return res;
310: }
311:
312: protected Rectangle getControlButtonsRectangle(Container parent) {
313: Component c = getControlButtons();
314: return new Rectangle(parent.getWidth() - c.getWidth() - 4, 4, c
315: .getWidth(), c.getHeight());
316: }
317:
318: public Insets getTabAreaInsets() {
319: Insets retValue = super .getTabAreaInsets();
320: retValue.right += 4;
321: return retValue;
322: }
323: }
|