001: /*
002: * SmoothGradientInternalFrameTitlePane.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.smoothgradient;
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:
039: /* ----------------------------------------------------------
040: * CVS NOTE: Changes to the CVS repository prior to the
041: * release of version 3.0.0beta1 has meant a
042: * resetting of CVS revision numbers.
043: * ----------------------------------------------------------
044: */
045:
046: /**
047: *
048: * @author Takis Diakoumis
049: * @version $Revision: 1.4 $
050: * @date $Date: 2006/05/14 06:56:07 $
051: */
052: public final class SmoothGradientInternalFrameTitlePane extends
053: MetalInternalFrameTitlePane {
054:
055: private String closeButtonToolTip;
056: private String iconButtonToolTip;
057: private String restoreButtonToolTip;
058: private String maxButtonToolTip;
059:
060: public SmoothGradientInternalFrameTitlePane(JInternalFrame frame) {
061: super (frame);
062: }
063:
064: public void paintPalette(Graphics g) {
065: boolean leftToRight = SmoothGradientUtils.isLeftToRight(frame);
066:
067: int width = getWidth();
068: int height = getHeight();
069:
070: Color background = SmoothGradientLookAndFeel
071: .getPrimaryControlShadow();
072: Color darkShadow = SmoothGradientLookAndFeel
073: .getControlDarkShadow();
074:
075: g.setColor(background);
076: g.fillRect(0, 0, width, height);
077:
078: g.setColor(darkShadow);
079: g.drawLine(0, height - 1, width, height - 1);
080:
081: int buttonsWidth = getButtonsWidth();
082: int xOffset = leftToRight ? 4 : buttonsWidth + 4;
083: int bumpLength = width - buttonsWidth - 2 * 4;
084: int bumpHeight = getHeight() - 4;
085: }
086:
087: protected LayoutManager createLayout() {
088: return new PolishedTitlePaneLayout();
089: }
090:
091: public void paintComponent(Graphics g) {
092:
093: if (isPalette) {
094: paintPalette(g);
095: return;
096: }
097:
098: boolean leftToRight = SmoothGradientUtils.isLeftToRight(frame);
099: boolean isSelected = frame.isSelected();
100:
101: int width = getWidth();
102: int height = getHeight();
103:
104: Color background = null;
105: Color foreground = null;
106: Color shadow = null;
107:
108: if (isSelected) {
109: background = SmoothGradientLookAndFeel
110: .getWindowTitleBackground();
111: foreground = SmoothGradientLookAndFeel
112: .getWindowTitleForeground();
113: } else {
114: background = SmoothGradientLookAndFeel
115: .getWindowTitleInactiveBackground();
116: foreground = SmoothGradientLookAndFeel
117: .getWindowTitleInactiveForeground();
118: }
119:
120: shadow = SmoothGradientLookAndFeel.getControlDarkShadow();
121: g.setColor(background);
122: g.fillRect(0, 0, width, height);
123:
124: g.setColor(shadow);
125: g.drawLine(0, height - 1, width, height - 1);
126: g.drawLine(0, 0, 0, 0);
127: g.drawLine(width - 1, 0, width - 1, 0);
128:
129: int titleLength = 0;
130: int xOffset = leftToRight ? 5 : width - 5;
131: String frameTitle = frame.getTitle();
132:
133: Icon icon = frame.getFrameIcon();
134:
135: if (icon != null) {
136:
137: if (!leftToRight)
138: xOffset -= icon.getIconWidth();
139:
140: int iconY = ((height / 2) - (icon.getIconHeight() / 2));
141: icon.paintIcon(frame, g, xOffset, iconY);
142: xOffset += leftToRight ? icon.getIconWidth() + 5 : -5;
143:
144: }
145:
146: boolean iconifiable = frame.isIconifiable();
147: boolean maximizable = frame.isMaximizable();
148:
149: if (frameTitle != null) {
150: Font f = getFont();
151: g.setFont(f);
152: FontMetrics fm = g.getFontMetrics();
153: //int fHeight = fm.getHeight();
154:
155: g.setColor(foreground);
156:
157: int yOffset = ((height - fm.getHeight()) / 2)
158: + fm.getAscent();
159: Rectangle rect = new Rectangle(0, 0, 0, 0);
160:
161: if (iconifiable)
162: rect = iconButton.getBounds();
163:
164: else if (maximizable)
165: rect = maxButton.getBounds();
166:
167: else if (frame.isClosable())
168: rect = closeButton.getBounds();
169:
170: int titleW;
171:
172: if (leftToRight) {
173:
174: if (rect.x == 0)
175: rect.x = frame.getWidth() - frame.getInsets().right
176: - 2;
177:
178: titleW = rect.x - xOffset - 4;
179: frameTitle = getTitle(frameTitle, fm, titleW);
180:
181: }
182:
183: else {
184: titleW = xOffset - rect.x - rect.width - 4;
185: frameTitle = getTitle(frameTitle, fm, titleW);
186: xOffset -= SwingUtilities.computeStringWidth(fm,
187: frameTitle);
188: }
189:
190: titleLength = SwingUtilities.computeStringWidth(fm,
191: frameTitle);
192: g.drawString(frameTitle, xOffset, yOffset);
193: xOffset += leftToRight ? titleLength + 5 : -5;
194:
195: }
196:
197: // draw the gradient
198: Rectangle r = new Rectangle(1, 0, width, height);
199: SmoothGradientUtils.addLight3DEffekt(g, r, true);
200:
201: }
202:
203: protected String getTitle(String text, FontMetrics fm,
204: int availTextWidth) {
205: if ((text == null) || (text.equals("")))
206: return "";
207: int textWidth = SwingUtilities.computeStringWidth(fm, text);
208: String clipString = "...";
209: if (textWidth > availTextWidth) {
210: int totalWidth = SwingUtilities.computeStringWidth(fm,
211: clipString);
212: int nChars;
213: for (nChars = 0; nChars < text.length(); nChars++) {
214: totalWidth += fm.charWidth(text.charAt(nChars));
215: if (totalWidth > availTextWidth) {
216: break;
217: }
218: }
219: text = text.substring(0, nChars) + clipString;
220: }
221: return text;
222: }
223:
224: private int getButtonsWidth() {
225: boolean leftToRight = SmoothGradientUtils.isLeftToRight(frame);
226:
227: int w = getWidth();
228: int x = leftToRight ? w : 0;
229: int spacing;
230:
231: // assumes all buttons have the same dimensions
232: // these dimensions include the borders
233: int buttonWidth = closeButton.getIcon().getIconWidth();
234:
235: if (frame.isClosable()) {
236: if (isPalette) {
237: spacing = 3;
238: x += leftToRight ? -spacing - (buttonWidth + 2)
239: : spacing;
240: if (!leftToRight)
241: x += (buttonWidth + 2);
242: } else {
243: spacing = 4;
244: x += leftToRight ? -spacing - buttonWidth : spacing;
245: if (!leftToRight)
246: x += buttonWidth;
247: }
248: }
249:
250: if (frame.isMaximizable() && !isPalette) {
251: spacing = frame.isClosable() ? 10 : 4;
252: x += leftToRight ? -spacing - buttonWidth : spacing;
253: if (!leftToRight)
254: x += buttonWidth;
255: }
256:
257: if (frame.isIconifiable() && !isPalette) {
258: spacing = frame.isMaximizable() ? 2
259: : (frame.isClosable() ? 10 : 4);
260: x += leftToRight ? -spacing - buttonWidth : spacing;
261: if (!leftToRight)
262: x += buttonWidth;
263: }
264:
265: return leftToRight ? w - x : x;
266: }
267:
268: class PolishedTitlePaneLayout extends TitlePaneLayout {
269: public void addLayoutComponent(String name, Component c) {
270: }
271:
272: public void removeLayoutComponent(Component c) {
273: }
274:
275: public Dimension preferredLayoutSize(Container c) {
276: return minimumLayoutSize(c);
277: }
278:
279: public Dimension minimumLayoutSize(Container c) {
280: // Compute width.
281: int width = 30;
282: if (frame.isClosable()) {
283: width += 21;
284: }
285: if (frame.isMaximizable()) {
286: width += 16 + (frame.isClosable() ? 10 : 4);
287: }
288: if (frame.isIconifiable()) {
289: width += 16 + (frame.isMaximizable() ? 2 : (frame
290: .isClosable() ? 10 : 4));
291: }
292: FontMetrics fm = getFontMetrics(getFont());
293: String frameTitle = frame.getTitle();
294: int title_w = frameTitle != null ? fm
295: .stringWidth(frameTitle) : 0;
296: int title_length = frameTitle != null ? frameTitle.length()
297: : 0;
298:
299: if (title_length > 2) {
300: int subtitle_w = fm.stringWidth(frame.getTitle()
301: .substring(0, 2)
302: + "...");
303: width += (title_w < subtitle_w) ? title_w : subtitle_w;
304: } else {
305: width += title_w;
306: }
307:
308: // Compute height.
309: int height = 0;
310: if (isPalette) {
311: height = paletteTitleHeight;
312: } else {
313: int fontHeight = fm.getHeight();
314: fontHeight += 7;
315: Icon icon = frame.getFrameIcon();
316: int iconHeight = 0;
317: if (icon != null) {
318: // SystemMenuBar forces the icon to be 16x16 or less.
319: iconHeight = Math.min(icon.getIconHeight(), 16);
320: }
321: iconHeight += 5;
322: height = Math.max(fontHeight, iconHeight);
323:
324: }
325:
326: return new Dimension(width, height);
327: }
328:
329: public void layoutContainer(Container c) {
330: boolean leftToRight = SmoothGradientUtils
331: .isLeftToRight(frame);
332:
333: int w = getWidth();
334: int x = leftToRight ? w : 0;
335: int y = 3;
336: int spacing;
337:
338: // assumes all buttons have the same dimensions
339: // these dimensions include the borders
340: int buttonHeight = closeButton.getIcon().getIconHeight();
341: int buttonWidth = closeButton.getIcon().getIconWidth();
342:
343: if (frame.isClosable()) {
344: if (isPalette) {
345: spacing = 3;
346: x += leftToRight ? -spacing - (buttonWidth + 2)
347: : spacing;
348: closeButton.setBounds(x, y, buttonWidth + 2,
349: getHeight() - 4);
350: if (!leftToRight)
351: x += (buttonWidth + 2);
352: } else {
353: spacing = 4;
354: x += leftToRight ? -spacing - buttonWidth : spacing;
355: closeButton.setBounds(x, y, buttonWidth,
356: buttonHeight);
357: if (!leftToRight)
358: x += buttonWidth;
359: }
360: }
361:
362: if (frame.isMaximizable() && !isPalette) {
363: spacing = 1;
364: x += leftToRight ? -spacing - buttonWidth : spacing;
365: maxButton.setBounds(x, y, buttonWidth, buttonHeight);
366: if (!leftToRight)
367: x += buttonWidth;
368: }
369:
370: if (frame.isIconifiable() && !isPalette) {
371: spacing = 1;
372: x += leftToRight ? -spacing - buttonWidth : spacing;
373: iconButton.setBounds(x, y, buttonWidth, buttonHeight);
374: if (!leftToRight)
375: x += buttonWidth;
376: }
377:
378: }
379:
380: } // class PolishedTitlePaneLayout
381:
382: }
|