001: /*
002: * BumpyGradientInternalFrameTitlePane.java
003: *
004: * Copyright (C) 2002, 2003, 2004, 2005, 2006 Takis Diakoumis
005: *
006: * This program is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU General Public License
008: * as published by the Free Software Foundation; either version 2
009: * of the License, or any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
019: *
020: */
021:
022: package org.underworldlabs.swing.plaf.bumpygradient;
023:
024: import java.awt.Color;
025: import java.awt.Component;
026: import java.awt.Container;
027: import java.awt.Dimension;
028: import java.awt.Font;
029: import java.awt.FontMetrics;
030: import java.awt.Graphics;
031: import java.awt.LayoutManager;
032: import java.awt.Rectangle;
033:
034: import javax.swing.Icon;
035: import javax.swing.JInternalFrame;
036: import javax.swing.SwingUtilities;
037: import javax.swing.plaf.metal.MetalInternalFrameTitlePane;
038: import org.underworldlabs.swing.plaf.smoothgradient.SmoothGradientLookAndFeel;
039: import org.underworldlabs.swing.plaf.smoothgradient.SmoothGradientUtils;
040:
041: /* ----------------------------------------------------------
042: * CVS NOTE: Changes to the CVS repository prior to the
043: * release of version 3.0.0beta1 has meant a
044: * resetting of CVS revision numbers.
045: * ----------------------------------------------------------
046: */
047:
048: /**
049: *
050: * @author Takis Diakoumis
051: * @version $Revision: 1.4 $
052: * @date $Date: 2006/05/14 06:56:07 $
053: */
054: public final class BumpyGradientInternalFrameTitlePane extends
055: MetalInternalFrameTitlePane {
056:
057: private String closeButtonToolTip;
058: private String iconButtonToolTip;
059: private String restoreButtonToolTip;
060: private String maxButtonToolTip;
061:
062: private BumpyGradientBumps paletteBumps;
063:
064: private final BumpyGradientBumps activeBumps = new BumpyGradientBumps(
065: 0, 0, BumpyGradientLookAndFeel
066: .getInternalFrameBumpsHighlight(),
067: BumpyGradientLookAndFeel.getPrimaryControlDarkShadow(),
068: BumpyGradientLookAndFeel.getPrimaryControl());
069:
070: private final BumpyGradientBumps inactiveBumps = new BumpyGradientBumps(
071: 0, 0, BumpyGradientLookAndFeel.getControlHighlight(),
072: BumpyGradientLookAndFeel.getControlDarkShadow(),
073: BumpyGradientLookAndFeel.getControl());
074:
075: public BumpyGradientInternalFrameTitlePane(JInternalFrame frame) {
076: super (frame);
077: }
078:
079: public void paintPalette(Graphics g) {
080: boolean leftToRight = SmoothGradientUtils.isLeftToRight(frame);
081:
082: int width = getWidth();
083: int height = getHeight();
084:
085: if (paletteBumps == null) {
086: paletteBumps = new BumpyGradientBumps(0, 0,
087: BumpyGradientLookAndFeel
088: .getPrimaryControlHighlight(),
089: BumpyGradientLookAndFeel.getPrimaryControlInfo(),
090: BumpyGradientLookAndFeel.getPrimaryControlShadow());
091: }
092:
093: Color background = BumpyGradientLookAndFeel
094: .getPrimaryControlShadow();
095: Color darkShadow = BumpyGradientLookAndFeel
096: .getControlDarkShadow();
097:
098: g.setColor(background);
099: g.fillRect(0, 0, width, height);
100:
101: g.setColor(darkShadow);
102: g.drawLine(0, height - 1, width, height - 1);
103:
104: int buttonsWidth = getButtonsWidth();
105: int xOffset = leftToRight ? 4 : buttonsWidth + 4;
106: int bumpLength = width - buttonsWidth - 2 * 4;
107: int bumpHeight = getHeight() - 4;
108: paletteBumps.setBumpArea(bumpLength, bumpHeight);
109: paletteBumps.paintIcon(this , g, xOffset, 2);
110: }
111:
112: protected LayoutManager createLayout() {
113: return new PolishedTitlePaneLayout();
114: }
115:
116: public void paintComponent(Graphics g) {
117:
118: if (isPalette) {
119: paintPalette(g);
120: return;
121: }
122:
123: boolean leftToRight = SmoothGradientUtils.isLeftToRight(frame);
124: boolean isSelected = frame.isSelected();
125:
126: int width = getWidth();
127: int height = getHeight();
128:
129: Color background = null;
130: Color foreground = null;
131: Color shadow = null;
132:
133: BumpyGradientBumps bumps;
134:
135: if (isSelected) {
136: background = SmoothGradientLookAndFeel
137: .getWindowTitleBackground();
138: foreground = SmoothGradientLookAndFeel
139: .getWindowTitleForeground();
140: bumps = activeBumps;
141: } else {
142: background = SmoothGradientLookAndFeel
143: .getWindowTitleInactiveBackground();
144: foreground = SmoothGradientLookAndFeel
145: .getWindowTitleInactiveForeground();
146: bumps = inactiveBumps;
147: }
148:
149: shadow = SmoothGradientLookAndFeel.getControlDarkShadow();
150: g.setColor(background);
151: g.fillRect(0, 0, width, height);
152:
153: g.setColor(shadow);
154: g.drawLine(0, height - 1, width, height - 1);
155: g.drawLine(0, 0, 0, 0);
156: g.drawLine(width - 1, 0, width - 1, 0);
157:
158: int titleLength = 0;
159: int xOffset = leftToRight ? 5 : width - 5;
160: String frameTitle = frame.getTitle();
161:
162: Icon icon = frame.getFrameIcon();
163:
164: if (icon != null) {
165:
166: if (!leftToRight)
167: xOffset -= icon.getIconWidth();
168:
169: int iconY = ((height / 2) - (icon.getIconHeight() / 2));
170: icon.paintIcon(frame, g, xOffset, iconY);
171: xOffset += leftToRight ? icon.getIconWidth() + 5 : -5;
172:
173: }
174:
175: boolean iconifiable = frame.isIconifiable();
176: boolean maximizable = frame.isMaximizable();
177:
178: if (frameTitle != null) {
179: Font f = getFont();
180: g.setFont(f);
181: FontMetrics fm = g.getFontMetrics();
182: //int fHeight = fm.getHeight();
183:
184: g.setColor(foreground);
185:
186: int yOffset = ((height - fm.getHeight()) / 2)
187: + fm.getAscent();
188: Rectangle rect = new Rectangle(0, 0, 0, 0);
189:
190: if (iconifiable)
191: rect = iconButton.getBounds();
192:
193: else if (maximizable)
194: rect = maxButton.getBounds();
195:
196: else if (frame.isClosable())
197: rect = closeButton.getBounds();
198:
199: int titleW;
200:
201: if (leftToRight) {
202:
203: if (rect.x == 0)
204: rect.x = frame.getWidth() - frame.getInsets().right
205: - 2;
206:
207: titleW = rect.x - xOffset - 4;
208: frameTitle = getTitle(frameTitle, fm, titleW);
209:
210: }
211:
212: else {
213: titleW = xOffset - rect.x - rect.width - 4;
214: frameTitle = getTitle(frameTitle, fm, titleW);
215: xOffset -= SwingUtilities.computeStringWidth(fm,
216: frameTitle);
217: }
218:
219: titleLength = SwingUtilities.computeStringWidth(fm,
220: frameTitle);
221: g.drawString(frameTitle, xOffset, yOffset);
222: xOffset += leftToRight ? titleLength + 5 : -5;
223:
224: }
225:
226: int bumpXOffset;
227: int bumpLength;
228: int buttonsWidth = getButtonsWidth();
229:
230: if (leftToRight) {
231:
232: if (!iconifiable && !maximizable)
233: bumpLength = width - buttonsWidth - xOffset - 4;
234: else
235: bumpLength = width - buttonsWidth - xOffset + 4;
236:
237: bumpXOffset = xOffset;
238:
239: }
240:
241: else {
242:
243: if (!iconifiable && !maximizable)
244: bumpLength = width - buttonsWidth - xOffset - 4;
245: else
246: bumpLength = width - buttonsWidth - xOffset + 4;
247:
248: bumpXOffset = buttonsWidth + 5;
249:
250: }
251:
252: int bumpYOffset = 3;
253: int bumpHeight = getHeight() - (2 * bumpYOffset);
254: bumps.setBumpArea(bumpLength, bumpHeight);
255: bumps.paintIcon(this , g, bumpXOffset, bumpYOffset);
256:
257: // draw the gradient
258: Rectangle r = new Rectangle(1, 0, width, height);
259: SmoothGradientUtils.addLight3DEffekt(g, r, true);
260:
261: }
262:
263: protected String getTitle(String text, FontMetrics fm,
264: int availTextWidth) {
265: if ((text == null) || (text.equals("")))
266: return "";
267: int textWidth = SwingUtilities.computeStringWidth(fm, text);
268: String clipString = "...";
269: if (textWidth > availTextWidth) {
270: int totalWidth = SwingUtilities.computeStringWidth(fm,
271: clipString);
272: int nChars;
273: for (nChars = 0; nChars < text.length(); nChars++) {
274: totalWidth += fm.charWidth(text.charAt(nChars));
275: if (totalWidth > availTextWidth) {
276: break;
277: }
278: }
279: text = text.substring(0, nChars) + clipString;
280: }
281: return text;
282: }
283:
284: private int getButtonsWidth() {
285: boolean leftToRight = SmoothGradientUtils.isLeftToRight(frame);
286:
287: int w = getWidth();
288: int x = leftToRight ? w : 0;
289: int spacing;
290:
291: // assumes all buttons have the same dimensions
292: // these dimensions include the borders
293: int buttonWidth = closeButton.getIcon().getIconWidth();
294:
295: if (frame.isClosable()) {
296: if (isPalette) {
297: spacing = 3;
298: x += leftToRight ? -spacing - (buttonWidth + 2)
299: : spacing;
300: if (!leftToRight)
301: x += (buttonWidth + 2);
302: } else {
303: spacing = 4;
304: x += leftToRight ? -spacing - buttonWidth : spacing;
305: if (!leftToRight)
306: x += buttonWidth;
307: }
308: }
309:
310: if (frame.isMaximizable() && !isPalette) {
311: spacing = frame.isClosable() ? 10 : 4;
312: x += leftToRight ? -spacing - buttonWidth : spacing;
313: if (!leftToRight)
314: x += buttonWidth;
315: }
316:
317: if (frame.isIconifiable() && !isPalette) {
318: spacing = frame.isMaximizable() ? 2
319: : (frame.isClosable() ? 10 : 4);
320: x += leftToRight ? -spacing - buttonWidth : spacing;
321: if (!leftToRight)
322: x += buttonWidth;
323: }
324:
325: return leftToRight ? w - x : x;
326: }
327:
328: class PolishedTitlePaneLayout extends TitlePaneLayout {
329: public void addLayoutComponent(String name, Component c) {
330: }
331:
332: public void removeLayoutComponent(Component c) {
333: }
334:
335: public Dimension preferredLayoutSize(Container c) {
336: return minimumLayoutSize(c);
337: }
338:
339: public Dimension minimumLayoutSize(Container c) {
340: // Compute width.
341: int width = 30;
342: if (frame.isClosable()) {
343: width += 21;
344: }
345: if (frame.isMaximizable()) {
346: width += 16 + (frame.isClosable() ? 10 : 4);
347: }
348: if (frame.isIconifiable()) {
349: width += 16 + (frame.isMaximizable() ? 2 : (frame
350: .isClosable() ? 10 : 4));
351: }
352: FontMetrics fm = getFontMetrics(getFont());
353: String frameTitle = frame.getTitle();
354: int title_w = frameTitle != null ? fm
355: .stringWidth(frameTitle) : 0;
356: int title_length = frameTitle != null ? frameTitle.length()
357: : 0;
358:
359: if (title_length > 2) {
360: int subtitle_w = fm.stringWidth(frame.getTitle()
361: .substring(0, 2)
362: + "...");
363: width += (title_w < subtitle_w) ? title_w : subtitle_w;
364: } else {
365: width += title_w;
366: }
367:
368: // Compute height.
369: int height = 0;
370: if (isPalette) {
371: height = paletteTitleHeight;
372: } else {
373: int fontHeight = fm.getHeight();
374: fontHeight += 7;
375: Icon icon = frame.getFrameIcon();
376: int iconHeight = 0;
377: if (icon != null) {
378: // SystemMenuBar forces the icon to be 16x16 or less.
379: iconHeight = Math.min(icon.getIconHeight(), 16);
380: }
381: iconHeight += 5;
382: height = Math.max(fontHeight, iconHeight);
383:
384: }
385:
386: return new Dimension(width, height);
387: }
388:
389: public void layoutContainer(Container c) {
390: boolean leftToRight = SmoothGradientUtils
391: .isLeftToRight(frame);
392:
393: int w = getWidth();
394: int x = leftToRight ? w : 0;
395: int y = 3;
396: int spacing;
397:
398: // assumes all buttons have the same dimensions
399: // these dimensions include the borders
400: int buttonHeight = closeButton.getIcon().getIconHeight();
401: int buttonWidth = closeButton.getIcon().getIconWidth();
402:
403: if (frame.isClosable()) {
404: if (isPalette) {
405: spacing = 3;
406: x += leftToRight ? -spacing - (buttonWidth + 2)
407: : spacing;
408: closeButton.setBounds(x, y, buttonWidth + 2,
409: getHeight() - 4);
410: if (!leftToRight)
411: x += (buttonWidth + 2);
412: } else {
413: spacing = 4;
414: x += leftToRight ? -spacing - buttonWidth : spacing;
415: closeButton.setBounds(x, y, buttonWidth,
416: buttonHeight);
417: if (!leftToRight)
418: x += buttonWidth;
419: }
420: }
421:
422: if (frame.isMaximizable() && !isPalette) {
423: spacing = 1;
424: x += leftToRight ? -spacing - buttonWidth : spacing;
425: maxButton.setBounds(x, y, buttonWidth, buttonHeight);
426: if (!leftToRight)
427: x += buttonWidth;
428: }
429:
430: if (frame.isIconifiable() && !isPalette) {
431: spacing = 1;
432: x += leftToRight ? -spacing - buttonWidth : spacing;
433: iconButton.setBounds(x, y, buttonWidth, buttonHeight);
434: if (!leftToRight)
435: x += buttonWidth;
436: }
437:
438: }
439:
440: } // class PolishedTitlePaneLayout
441:
442: }
|