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: package org.netbeans.swing.tabcontrol.plaf;
043:
044: import java.awt.Color;
045: import java.awt.Component;
046: import java.awt.Dimension;
047: import java.awt.Font;
048: import java.awt.FontMetrics;
049: import java.awt.Graphics;
050: import java.awt.Graphics2D;
051: import java.awt.Insets;
052: import java.awt.Rectangle;
053: import java.awt.image.BufferedImage;
054: import java.awt.image.RescaleOp;
055: import org.netbeans.swing.tabcontrol.TabDisplayer;
056: import javax.swing.plaf.ComponentUI;
057: import java.util.HashMap;
058: import java.util.Map;
059: import javax.swing.Icon;
060: import javax.swing.JComponent;
061: import javax.swing.JTabbedPane;
062: import javax.swing.UIManager;
063: import javax.swing.plaf.synth.Region;
064: import javax.swing.plaf.synth.SynthConstants;
065: import javax.swing.plaf.synth.SynthContext;
066: import javax.swing.plaf.synth.SynthLookAndFeel;
067: import javax.swing.plaf.synth.SynthPainter;
068: import javax.swing.plaf.synth.SynthStyle;
069: import javax.swing.plaf.synth.SynthStyleFactory;
070: import org.openide.awt.HtmlRenderer;
071:
072: /**
073: * GTK user interface of view type tabs. It uses native engine to paint tab
074: * background.
075: *
076: * @author Dafe Simonek
077: */
078: public final class GtkViewTabDisplayerUI extends
079: AbstractViewTabDisplayerUI {
080:
081: /**
082: * ******** constants ************
083: */
084:
085: private static final int BUMP_X_PAD = 0;
086: private static final int BUMP_WIDTH = 0;
087: private static final int TXT_X_PAD = 7;
088: private static final int TXT_Y_PAD = 5;
089:
090: private static final int ICON_X_PAD = 2;
091:
092: private static Map<Integer, String[]> buttonIconPaths;
093:
094: private static JTabbedPane dummyTab;
095:
096: /**
097: * ******** instance fields ********
098: */
099:
100: private Dimension prefSize;
101:
102: /**
103: * Reusable Rectangle to optimize rectangle creation/garbage collection
104: * during paints
105: */
106: private Rectangle tempRect = new Rectangle();
107:
108: /**
109: * Should be constructed only from createUI method.
110: */
111: private GtkViewTabDisplayerUI(TabDisplayer displayer) {
112: super (displayer);
113: prefSize = new Dimension(100, 19);
114: }
115:
116: public static ComponentUI createUI(JComponent c) {
117: return new GtkViewTabDisplayerUI((TabDisplayer) c);
118: }
119:
120: public Dimension getPreferredSize(JComponent c) {
121: FontMetrics fm = getTxtFontMetrics();
122: int height = fm == null ? 19 : fm.getAscent() + 2
123: * fm.getDescent() + 5;
124: Insets insets = c.getInsets();
125: prefSize.height = height + insets.bottom + insets.top;
126: return prefSize;
127: }
128:
129: /**
130: * adds painting of overall border
131: */
132: public void paint(Graphics g, JComponent c) {
133:
134: ColorUtil.setupAntialiasing(g);
135:
136: Color col = c.getBackground();
137: if (col != null) {
138: g.setColor(col);
139: g.fillRect(0, 0, c.getWidth(), c.getHeight());
140: }
141: paintOverallBorder(g, c);
142: super .paint(g, c);
143: }
144:
145: /**
146: * Paints lower border, bottom line, separating tabs from content
147: */
148: protected void paintOverallBorder(Graphics g, JComponent c) {
149: return;
150: }
151:
152: protected Font getTxtFont() {
153: Font result = UIManager.getFont("controlFont");
154: if (result != null) {
155: return result;
156: }
157: return super .getTxtFont();
158: }
159:
160: protected void paintTabContent(Graphics g, int index, String text,
161: int x, int y, int width, int height) {
162: // substract lower border
163: height--;
164: FontMetrics fm = getTxtFontMetrics();
165: // setting font already here to compute string width correctly
166: g.setFont(getTxtFont());
167: int txtWidth = width;
168: if (isSelected(index)) {
169: Component buttons = getControlButtons();
170: if (null != buttons) {
171: Dimension buttonsSize = buttons.getPreferredSize();
172: txtWidth = width
173: - (buttonsSize.width + ICON_X_PAD + 2 * TXT_X_PAD);
174: buttons.setLocation(x + txtWidth + 2 * TXT_X_PAD, y
175: + (height - buttonsSize.height) / 2
176: + (TXT_Y_PAD / 2));
177: }
178: } else {
179: txtWidth = width - 2 * TXT_X_PAD;
180: }
181: // draw bump (dragger)
182: drawBump(g, index, x + 4, y + 6, BUMP_WIDTH, height - 8);
183:
184: // draw text in right color
185: Color txtC = UIManager.getColor("TabbedPane.foreground"); //NOI18N
186:
187: HtmlRenderer.renderString(text, g, x + TXT_X_PAD, y
188: + fm.getAscent() + TXT_Y_PAD, txtWidth, height,
189: getTxtFont(), txtC, HtmlRenderer.STYLE_TRUNCATE, true);
190: }
191:
192: protected void paintTabBorder(Graphics g, int index, int x, int y,
193: int width, int height) {
194:
195: return;
196: }
197:
198: private static void paintTabBackgroundNative(Graphics g, int index,
199: int state, int x, int y, int w, int h) {
200: }
201:
202: protected void paintTabBackground(Graphics g, int index, int x,
203: int y, int width, int height) {
204: int state = isSelected(index) ? SynthConstants.SELECTED
205: : SynthConstants.DEFAULT;
206: if (dummyTab == null) {
207: dummyTab = new JTabbedPane();
208: }
209: Region region = Region.TABBED_PANE_TAB;
210: SynthLookAndFeel laf = (SynthLookAndFeel) UIManager
211: .getLookAndFeel();
212: SynthStyleFactory sf = laf.getStyleFactory();
213: SynthStyle style = sf.getStyle(dummyTab, region);
214: SynthContext context = new SynthContext(dummyTab, region,
215: style, state);
216: SynthPainter painter = style.getPainter(context);
217: if (state == SynthConstants.SELECTED) {
218: // differentiate active and selected tabs, active tab made brighter,
219: // selected tab darker and lower
220: RescaleOp op = null;
221: if (isActive()) {
222: op = new RescaleOp(1.08f, 0, null);
223: } else {
224: op = new RescaleOp(0.96f, 0, null);
225: y++;
226: height--;
227: }
228:
229: BufferedImage bufIm = new BufferedImage(width, height,
230: BufferedImage.TYPE_INT_RGB);
231: Graphics2D g2d = bufIm.createGraphics();
232: g2d.setBackground(UIManager.getColor("Panel.background"));
233: g2d.clearRect(0, 0, width, height);
234: painter.paintTabbedPaneTabBackground(context, g2d, 0, 0,
235: width, height, index);
236: BufferedImage img = op.filter(bufIm, null);
237: g.drawImage(img, x, y, null);
238: } else {
239: // non selected are lowered by 2 pixels
240: painter.paintTabbedPaneTabBackground(context, g, x, y + 2,
241: width, height - 2, index);
242: }
243: }
244:
245: /**
246: * Paints dragger in given rectangle
247: */
248: private void drawBump(Graphics g, int index, int x, int y,
249: int width, int height) {
250: //This look and feel is also used as the default UI on non-JDS
251: return;
252: }
253:
254: private static void initIcons() {
255: if (null == buttonIconPaths) {
256: buttonIconPaths = new HashMap<Integer, String[]>(7);
257:
258: //close button
259: String[] iconPaths = new String[4];
260: iconPaths[TabControlButton.STATE_DEFAULT] = "org/netbeans/swing/tabcontrol/resources/gtk_bigclose_enabled.png"; // NOI18N
261: iconPaths[TabControlButton.STATE_PRESSED] = "org/netbeans/swing/tabcontrol/resources/gtk_bigclose_pressed.png"; // NOI18N
262: iconPaths[TabControlButton.STATE_DISABLED] = iconPaths[TabControlButton.STATE_DEFAULT];
263: iconPaths[TabControlButton.STATE_ROLLOVER] = "org/netbeans/swing/tabcontrol/resources/gtk_bigclose_rollover.png"; // NOI18N
264: buttonIconPaths.put(TabControlButton.ID_CLOSE_BUTTON,
265: iconPaths);
266:
267: //slide/pin button
268: iconPaths = new String[4];
269: iconPaths[TabControlButton.STATE_DEFAULT] = "org/netbeans/swing/tabcontrol/resources/gtk_slideright_enabled.png"; // NOI18N
270: iconPaths[TabControlButton.STATE_PRESSED] = "org/netbeans/swing/tabcontrol/resources/gtk_slideright_pressed.png"; // NOI18N
271: iconPaths[TabControlButton.STATE_DISABLED] = iconPaths[TabControlButton.STATE_DEFAULT];
272: iconPaths[TabControlButton.STATE_ROLLOVER] = "org/netbeans/swing/tabcontrol/resources/gtk_slideright_rollover.png"; // NOI18N
273: buttonIconPaths.put(TabControlButton.ID_SLIDE_RIGHT_BUTTON,
274: iconPaths);
275:
276: iconPaths = new String[4];
277: iconPaths[TabControlButton.STATE_DEFAULT] = "org/netbeans/swing/tabcontrol/resources/gtk_slideleft_enabled.png"; // NOI18N
278: iconPaths[TabControlButton.STATE_PRESSED] = "org/netbeans/swing/tabcontrol/resources/gtk_slideleft_pressed.png"; // NOI18N
279: iconPaths[TabControlButton.STATE_DISABLED] = iconPaths[TabControlButton.STATE_DEFAULT];
280: iconPaths[TabControlButton.STATE_ROLLOVER] = "org/netbeans/swing/tabcontrol/resources/gtk_slideleft_rollover.png"; // NOI18N
281: buttonIconPaths.put(TabControlButton.ID_SLIDE_LEFT_BUTTON,
282: iconPaths);
283:
284: iconPaths = new String[4];
285: iconPaths[TabControlButton.STATE_DEFAULT] = "org/netbeans/swing/tabcontrol/resources/gtk_slidebottom_enabled.png"; // NOI18N
286: iconPaths[TabControlButton.STATE_PRESSED] = "org/netbeans/swing/tabcontrol/resources/gtk_slidebottom_pressed.png"; // NOI18N
287: iconPaths[TabControlButton.STATE_DISABLED] = iconPaths[TabControlButton.STATE_DEFAULT];
288: iconPaths[TabControlButton.STATE_ROLLOVER] = "org/netbeans/swing/tabcontrol/resources/gtk_slidebottom_rollover.png"; // NOI18N
289: buttonIconPaths.put(TabControlButton.ID_SLIDE_DOWN_BUTTON,
290: iconPaths);
291:
292: iconPaths = new String[4];
293: iconPaths[TabControlButton.STATE_DEFAULT] = "org/netbeans/swing/tabcontrol/resources/gtk_pin_enabled.png"; // NOI18N
294: iconPaths[TabControlButton.STATE_PRESSED] = "org/netbeans/swing/tabcontrol/resources/gtk_pin_pressed.png"; // NOI18N
295: iconPaths[TabControlButton.STATE_DISABLED] = iconPaths[TabControlButton.STATE_DEFAULT];
296: iconPaths[TabControlButton.STATE_ROLLOVER] = "org/netbeans/swing/tabcontrol/resources/gtk_pin_rollover.png"; // NOI18N
297: buttonIconPaths.put(TabControlButton.ID_PIN_BUTTON,
298: iconPaths);
299: }
300: }
301:
302: public Icon getButtonIcon(int buttonId, int buttonState) {
303: Icon res = null;
304: initIcons();
305: String[] paths = buttonIconPaths.get(buttonId);
306: if (null != paths && buttonState >= 0
307: && buttonState < paths.length) {
308: res = TabControlButtonFactory.getIcon(paths[buttonState]);
309: }
310: return res;
311: }
312:
313: }
|