001: package org.jvnet.substance.netbeans;
002:
003: import org.jvnet.lafwidget.utils.RenderingUtils;
004: import org.jvnet.substance.SubstanceLookAndFeel;
005: import org.netbeans.swing.tabcontrol.TabDisplayer;
006: import javax.swing.*;
007: import javax.swing.plaf.ComponentUI;
008: import java.awt.*;
009: import java.awt.image.BufferedImage;
010: import java.util.HashSet;
011: import java.util.Set;
012: import org.jvnet.substance.border.SubstanceBorderPainter;
013: import org.jvnet.substance.button.BaseButtonShaper;
014: import org.jvnet.substance.color.ColorScheme;
015: import org.jvnet.substance.painter.SubstanceGradientPainter;
016: import org.jvnet.substance.theme.SubstanceTheme;
017: import org.jvnet.substance.utils.SubstanceConstants.Side;
018: import org.jvnet.substance.utils.SubstanceCoreUtilities;
019: import org.netbeans.swing.tabcontrol.plaf.AbstractViewTabDisplayerUI;
020: import org.openide.awt.HtmlRenderer;
021:
022: public class SubstanceViewTabDisplayerUI extends
023: AbstractViewTabDisplayerUI {
024:
025: /**
026: * *********** constants ******************
027: */
028: private static final int TXT_X_PAD = 5;
029:
030: private static final int ICON_X_LEFT_PAD = 5;
031: private static final int ICON_X_RIGHT_PAD = 2;
032:
033: private static final int BUMP_X_PAD = 5;
034: private static final int BUMP_Y_PAD = 4;
035:
036: /**
037: * ****** static fields **********
038: */
039:
040: private static Color inactBgColor;
041: private static Color actBgColor;
042: private static Color borderHighlight;
043: private static Color borderShadow;
044:
045: private FontMetrics fm;
046:
047: private Font txtFont;
048: /**
049: * ******* instance fields *********
050: */
051:
052: private Dimension prefSize;
053:
054: /**
055: * Reusable Rectangle to optimize rectangle creation/garbage collection
056: * during paints
057: */
058: private Rectangle tempRect = new Rectangle();
059:
060: protected SubstanceViewTabDisplayerUI(TabDisplayer displayer) {
061: super (displayer);
062: prefSize = new Dimension(100, 19);
063: }
064:
065: public void installUI(JComponent c) {
066: super .installUI(c);
067: displayer.setFont(SubstanceLookAndFeel.getFontPolicy()
068: .getFontSet("Substance", null).getControlFont());
069: }
070:
071: /**
072: * Should be constructed only from createUI method.
073: */
074:
075: public static ComponentUI createUI(JComponent c) {
076: return new SubstanceViewTabDisplayerUI((TabDisplayer) c);
077: }
078:
079: // @Override
080: // public Icon getButtonIcon(int buttonId, int buttonState) {
081: // SubstanceTheme theme =
082: // SubstanceLookAndFeel.getTheme();
083: // Icon result =
084: // SubstanceNetbeansImageCreator.getTabIcon(theme, buttonId);
085: // if (result == null) {
086: // return super.getButtonIcon(buttonId, buttonState);
087: // }
088: // return result;
089: // }
090:
091: public Dimension getPreferredSize(JComponent c) {
092: FontMetrics fm = getTxtFontMetrics();
093: int height = fm == null ? 21 : fm.getAscent() + 2
094: * fm.getDescent() + 4;
095: Insets insets = c.getInsets();
096: prefSize.height = height + insets.bottom + insets.top;
097: return prefSize;
098: }
099:
100: /**
101: * Overrides basic paint mathod, adds painting of overall
102: * bottom area, depending on activation status value
103: */
104: public void paint(Graphics g, JComponent c) {
105: super .paint(g, c);
106: paintBottomBorder(g, c);
107: }
108:
109: @Override
110: public void update(Graphics graphics, JComponent jComponent) {
111: Graphics2D g2 = (Graphics2D) graphics.create();
112: RenderingUtils.installDesktopHints(g2);
113: super .update(g2, jComponent);
114: g2.dispose();
115: }
116:
117: /**
118: * Paints bottom "activation" line
119: */
120: private void paintBottomBorder(Graphics g, JComponent c) {
121: Rectangle bounds = c.getBounds();
122: g.setColor(SubstanceLookAndFeel.getDefaultColorScheme()
123: .getMidColor());
124: g.drawLine(1, bounds.height - 1, bounds.width - 1,
125: bounds.height - 1);
126: }
127:
128: protected void paintTabContent(Graphics _g, int index, String text,
129: int x, int y, int width, int height) {
130: Graphics2D g2 = (Graphics2D) _g.create();
131: RenderingUtils.installDesktopHints(g2);
132: FontMetrics fm = getTxtFontMetrics();
133: // setting font already here to compute string width correctly
134: g2.setFont(getTxtFont());
135: int txtWidth = width;
136:
137: if (isSelected(index)) {
138: Component buttons = getControlButtons();
139: if (null != buttons) {
140: Dimension buttonsSize = buttons.getPreferredSize();
141: txtWidth = width
142: - (buttonsSize.width + ICON_X_LEFT_PAD
143: + ICON_X_RIGHT_PAD + 2 * TXT_X_PAD);
144: buttons.setLocation(x + txtWidth + 2 * TXT_X_PAD, y
145: + (height - buttonsSize.height) / 2 + 1);
146: }
147: txtWidth = (int) HtmlRenderer.renderString(text, g2, x
148: + TXT_X_PAD, height - fm.getDescent() - 4,
149: txtWidth, height, getTxtFont(), UIManager
150: .getColor("textText"),
151: HtmlRenderer.STYLE_TRUNCATE, true);
152: int bumpWidth = width - (TXT_X_PAD + txtWidth + BUMP_X_PAD);
153: if (bumpWidth > 0) {
154: paintBump(index, g2, x + TXT_X_PAD + txtWidth
155: + BUMP_X_PAD, y + BUMP_Y_PAD, bumpWidth, height
156: - 2 * BUMP_Y_PAD);
157: }
158: } else {
159: txtWidth = width - 2 * TXT_X_PAD;
160: HtmlRenderer.renderString(text, g2, x + TXT_X_PAD, height
161: - fm.getDescent() - 4, txtWidth, height,
162: getTxtFont(), UIManager.getColor("textText"),
163: HtmlRenderer.STYLE_TRUNCATE, true);
164: }
165: g2.dispose();
166: }
167:
168: protected void paintTabBorder(Graphics g, int index, int x, int y,
169: int width, int height) {
170: }
171:
172: protected void paintTabBackground(Graphics g, int index, int x,
173: int y, int width, int height) {
174: boolean selected = isSelected(index);
175: boolean highlighted = selected && isActive();
176: boolean attention = isAttention(index);
177: ColorScheme colorScheme = (selected | highlighted | attention) ? SubstanceLookAndFeel
178: .getActiveColorScheme()
179: : SubstanceLookAndFeel.getDefaultColorScheme();
180: int cyclePos = selected ? 5 : 0;
181:
182: Set<Side> bottom = new HashSet<Side>();
183: bottom.add(Side.BOTTOM);
184: SubstanceGradientPainter painter = SubstanceLookAndFeel
185: .getCurrentGradientPainter();
186:
187: SubstanceBorderPainter borderPainter = SubstanceCoreUtilities
188: .getBorderPainter(this .displayer, painter);
189:
190: Shape contour = BaseButtonShaper.getBaseOutline(width,
191: height + 2, 0, bottom);
192: BufferedImage bi = painter.getContourBackground(width,
193: height + 2, contour, false, colorScheme, colorScheme,
194: cyclePos, true, false);
195:
196: borderPainter.paintBorder(bi.getGraphics(), this .displayer,
197: width, height + 2, contour, null, colorScheme,
198: colorScheme, cyclePos, false);
199:
200: g.drawImage(bi, x, y, null);
201: }
202:
203: private void paintBump(int index, Graphics g, int x, int y,
204: int width, int height) {
205: }
206:
207: static Color getInactBgColor() {
208: return SubstanceLookAndFeel.getDefaultColorScheme()
209: .getMidColor();
210: }
211:
212: static Color getActBgColor() {
213: return SubstanceLookAndFeel.getActiveColorScheme()
214: .getMidColor();
215: }
216:
217: private Color getBorderHighlight() {
218: if (borderHighlight == null) {
219: borderHighlight = getInactBgColor().brighter();
220: }
221: return borderHighlight;
222: }
223:
224: private Color getBorderShadow() {
225: if (borderShadow == null) {
226: borderShadow = getInactBgColor().darker();
227: }
228: return borderShadow;
229: }
230:
231: /**
232: * Specifies font to use for text and font metrics. Subclasses may override
233: * to specify their own text font
234: */
235: protected Font getTxtFont() {
236: if (txtFont == null) {
237: txtFont = SubstanceLookAndFeel.getFontPolicy().getFontSet(
238: "Substance", null).getControlFont();
239: if (txtFont == null) {
240: txtFont = new Font("Dialog", Font.PLAIN, 11);
241: } else if (txtFont.isBold()) {
242: // don't use deriveFont() - see #49973 for details
243: txtFont = new Font(txtFont.getName(), Font.PLAIN,
244: txtFont.getSize());
245: }
246: }
247: return txtFont;
248: }
249: }
|