001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /**
019: * @author Anton Avtamonov, Sergey Burlak, Vadim Bogdanov, Alexander Simbirtsev
020: * @version $Revision$
021: */package javax.swing.plaf.metal;
022:
023: import java.awt.Color;
024: import java.awt.Component;
025: import java.awt.Graphics;
026: import java.awt.Insets;
027: import java.awt.Window;
028:
029: import javax.swing.AbstractButton;
030: import javax.swing.JButton;
031: import javax.swing.JInternalFrame;
032: import javax.swing.JMenu;
033: import javax.swing.JMenuItem;
034: import javax.swing.JToolBar;
035: import javax.swing.SwingConstants;
036: import javax.swing.SwingUtilities;
037: import javax.swing.UIManager;
038: import javax.swing.border.AbstractBorder;
039: import javax.swing.border.Border;
040: import javax.swing.border.LineBorder;
041: import javax.swing.border.MatteBorder;
042: import javax.swing.plaf.BorderUIResource;
043: import javax.swing.plaf.ColorUIResource;
044: import javax.swing.plaf.UIResource;
045: import javax.swing.plaf.basic.BasicBorders.MarginBorder;
046:
047: import org.apache.harmony.x.swing.Utilities;
048:
049: public class MetalBorders {
050: public static class ButtonBorder extends AbstractBorder implements
051: UIResource {
052: protected static Insets borderInsets = new Insets(3, 3, 3, 3);
053:
054: public Insets getBorderInsets(final Component component,
055: final Insets insets) {
056: return initBorderInsets(insets, borderInsets);
057: }
058:
059: public Insets getBorderInsets(final Component component) {
060: return borderInsets;
061: }
062:
063: public void paintBorder(final Component c, final Graphics g,
064: final int x, final int y, final int w, final int h) {
065: if (c.isEnabled()) {
066: final AbstractButton button = (AbstractButton) c;
067: if ((button instanceof JButton)
068: && ((JButton) button).isDefaultButton()) {
069: Utilities.draw3DRect(g, x + 2, y + 2, w - 3, h - 3,
070: MetalLookAndFeel.getControlShadow(),
071: MetalLookAndFeel.getControlHighlight(),
072: true);
073: Utilities.draw3DRect(g, x, y, w - 1, h - 1,
074: MetalLookAndFeel.getControlDarkShadow(),
075: MetalLookAndFeel.getControlDarkShadow(),
076: true);
077: Utilities.draw3DRect(g, x + 1, y + 1, w - 3, h - 3,
078: MetalLookAndFeel.getControlDarkShadow(),
079: MetalLookAndFeel.getControlDarkShadow(),
080: true);
081: } else {
082: Utilities.draw3DRect(g, x, y, w, h,
083: MetalLookAndFeel.getControlDarkShadow(),
084: MetalLookAndFeel.getControlHighlight(),
085: false);
086: if (!button.getModel().isArmed()) {
087: Utilities.draw3DRect(g, x + 1, y + 1, w - 2,
088: h - 2, MetalLookAndFeel
089: .getControlShadow(),
090: MetalLookAndFeel.getControlHighlight(),
091: true);
092: }
093: }
094: } else {
095: Color oldColor = g.getColor();
096: g.setColor(MetalLookAndFeel.getControlShadow());
097: g.drawRect(x, y, w - 1, h - 1);
098: g.setColor(oldColor);
099: }
100: }
101: }
102:
103: public static class Flush3DBorder extends AbstractBorder implements
104: UIResource {
105: private static final Insets BORDER_INSETS = new Insets(2, 2, 2,
106: 2);
107:
108: public Insets getBorderInsets(final Component component,
109: final Insets insets) {
110: return initBorderInsets(insets, BORDER_INSETS);
111: }
112:
113: public Insets getBorderInsets(final Component component) {
114: return BORDER_INSETS;
115: }
116:
117: public void paintBorder(final Component c, final Graphics g,
118: final int x, final int y, final int w, final int h) {
119: Color shadow = MetalLookAndFeel.getControlShadow();
120: Color highlight = MetalLookAndFeel.getControlHighlight();
121: Utilities.draw3DRect(g, x, y, w, h, shadow, highlight,
122: false);
123: Utilities.draw3DRect(g, x + 1, y + 1, w - 2, h - 2, shadow,
124: highlight, true);
125: }
126: }
127:
128: public static class InternalFrameBorder extends AbstractBorder
129: implements UIResource {
130: private static final int width = 5;
131: private static final int corner = 15 + width;
132: private static final Insets BORDER_INSETS = new Insets(width,
133: width, width, width);
134:
135: Color activeColor;
136: Color activeHighlight;
137: Color activeDarkShadow;
138: Color activeShadow;
139:
140: public InternalFrameBorder() {
141: installColors();
142: }
143:
144: public Insets getBorderInsets(final Component c,
145: final Insets insets) {
146: return initBorderInsets(insets, BORDER_INSETS);
147: }
148:
149: public Insets getBorderInsets(final Component c) {
150: return BORDER_INSETS;
151: }
152:
153: public void paintBorder(final Component c, final Graphics g,
154: final int x, final int y, final int w, final int h) {
155: boolean isActive = isActive(c);
156:
157: Color color;
158: Color highlight;
159: Color darkShadow;
160: Color shadow;
161: if (isActive) {
162: color = activeColor;
163: highlight = activeHighlight;
164: darkShadow = activeDarkShadow;
165: shadow = activeShadow;
166: } else {
167: color = MetalLookAndFeel.getControlDarkShadow();
168: highlight = MetalLookAndFeel.getControlHighlight();
169: darkShadow = MetalLookAndFeel.getControlDarkShadow();
170: shadow = MetalLookAndFeel.getControlShadow();
171: }
172:
173: fillBorder(g, x + 1, y + 1, w - 1, h - 1, color, width - 2);
174: Utilities.draw3DRect(g, x, y, w, h, darkShadow, highlight,
175: true);
176: Utilities.draw3DRect(g, x + width - 1, y + width - 1, w - 2
177: * width + 2, h - 2 * width + 2, darkShadow,
178: highlight, false);
179:
180: if (!canBeResized(c)) {
181: return;
182: }
183:
184: // paint corners (only for resizable frame)
185: Color saveColor = g.getColor();
186: g.setColor(shadow);
187: g.fillRect(x + 1, y + 1, corner - 2, 3);
188: g.fillRect(x + 1, y + 1, 3, corner - 2);
189: g.fillRect(w - corner + 1, y + 1, corner - 2, 3);
190: g.fillRect(w - 4, y + 1, 3, corner - 2);
191: g.fillRect(x + 1, h - 4, corner - 2, 3);
192: g.fillRect(x + 1, h - corner + 1, 3, corner - 2);
193: g.fillRect(w - corner + 1, h - 4, corner - 2, 3);
194: g.fillRect(w - 4, h - corner + 1, 3, corner - 2);
195:
196: g.setColor(saveColor);
197: }
198:
199: void installColors() {
200: if (activeColor == null) {
201: activeColor = MetalLookAndFeel
202: .getPrimaryControlDarkShadow();
203: activeHighlight = MetalLookAndFeel
204: .getPrimaryControlHighlight();
205: activeDarkShadow = MetalLookAndFeel
206: .getPrimaryControlDarkShadow();
207: activeShadow = MetalLookAndFeel
208: .getPrimaryControlShadow();
209: }
210: }
211:
212: boolean isActive(final Component c) {
213: return ((JInternalFrame) c).isSelected();
214: }
215:
216: boolean canBeResized(final Component c) {
217: JInternalFrame frame = (JInternalFrame) c;
218: return frame.isResizable() && !frame.isMaximum();
219: }
220: }
221:
222: public static class MenuBarBorder extends AbstractBorder implements
223: UIResource {
224: protected static Insets borderInsets = new Insets(1, 0, 1, 0);
225:
226: public Insets getBorderInsets(final Component component,
227: final Insets insets) {
228: return initBorderInsets(insets, borderInsets);
229: }
230:
231: public Insets getBorderInsets(final Component component) {
232: return borderInsets;
233: }
234:
235: public void paintBorder(final Component c, final Graphics g,
236: final int x, final int y, final int w, final int h) {
237: Color oldColor = g.getColor();
238:
239: g.setColor(MetalLookAndFeel.getControlShadow());
240: g.drawLine(x, y + h - 1, x + w, y + h - 1);
241:
242: g.setColor(oldColor);
243: }
244: }
245:
246: public static class MenuItemBorder extends AbstractBorder implements
247: UIResource {
248: protected static Insets borderInsets = new Insets(2, 2, 2, 2);
249:
250: public Insets getBorderInsets(final Component component,
251: final Insets insets) {
252: return initBorderInsets(insets, borderInsets);
253: }
254:
255: public Insets getBorderInsets(final Component component) {
256: return borderInsets;
257: }
258:
259: public void paintBorder(final Component c, final Graphics g,
260: final int x, final int y, final int w, final int h) {
261: JMenuItem item = (JMenuItem) c;
262: if ((item.isArmed() || (item instanceof JMenu)
263: && item.isSelected())
264: && item.isEnabled()) {
265: Utilities.draw3DRect(g, x, y, w, h, MetalLookAndFeel
266: .getControlDarkShadow(), MetalLookAndFeel
267: .getControlHighlight(), false);
268: }
269: }
270: }
271:
272: public static class OptionDialogBorder extends AbstractBorder
273: implements UIResource {
274: private static DialogBorder borderImpl;
275: private static final Insets BORDER_INSETS = new Insets(3, 3, 3,
276: 3);
277:
278: public OptionDialogBorder() {
279: borderImpl = new DialogBorder();
280: }
281:
282: public Insets getBorderInsets(final Component c,
283: final Insets insets) {
284: return initBorderInsets(insets, BORDER_INSETS);
285: }
286:
287: public Insets getBorderInsets(final Component c) {
288: return BORDER_INSETS;
289: }
290:
291: public void paintBorder(final Component c, final Graphics g,
292: final int x, final int y, final int w, final int h) {
293: borderImpl.paintBorder(c, g, x, y, w, h);
294: }
295: }
296:
297: public static class PaletteBorder extends AbstractBorder implements
298: UIResource {
299: private static final int width = 1;
300: private static final Insets borderInsets = new Insets(width,
301: width, width, width);
302:
303: public Insets getBorderInsets(final Component c,
304: final Insets insets) {
305: return initBorderInsets(insets, borderInsets);
306: }
307:
308: public Insets getBorderInsets(final Component c) {
309: return borderInsets;
310: }
311:
312: public void paintBorder(final Component c, final Graphics g,
313: final int x, final int y, final int w, final int h) {
314: Color saveColor = g.getColor();
315: g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
316:
317: g.fillRect(x, y, width, h);
318: g.fillRect(w - width, y, width, h);
319: g.fillRect(x, y, w, width);
320: g.fillRect(x, h - width, w, width);
321:
322: g.setColor(saveColor);
323: }
324: }
325:
326: public static class PopupMenuBorder extends AbstractBorder
327: implements UIResource {
328: protected static Insets borderInsets = new Insets(2, 2, 1, 1);
329:
330: public Insets getBorderInsets(final Component component,
331: final Insets insets) {
332: return initBorderInsets(insets, borderInsets);
333: }
334:
335: public Insets getBorderInsets(final Component component) {
336: return borderInsets;
337: }
338:
339: public void paintBorder(final Component c, final Graphics g,
340: final int x, final int y, final int w, final int h) {
341: Utilities.draw3DRect(g, x + 1, y + 1, w - 1, h - 1,
342: MetalLookAndFeel.getControlDarkShadow(),
343: MetalLookAndFeel.getControlHighlight(), true);
344: Color oldColor = g.getColor();
345:
346: g.setColor(MetalLookAndFeel.getControlDarkShadow());
347: g.drawRect(x, y, w - 1, h - 1);
348:
349: g.setColor(oldColor);
350: }
351: }
352:
353: public static class RolloverButtonBorder extends ButtonBorder {
354: public void paintBorder(final Component c, final Graphics g,
355: final int x, final int y, final int w, final int h) {
356: if (((AbstractButton) c).getModel().isRollover()) {
357: super .paintBorder(c, g, x, y, w, h);
358: }
359: }
360: }
361:
362: public static class ScrollPaneBorder extends AbstractBorder
363: implements UIResource {
364: private static final Insets borderInsets = new Insets(1, 1, 2,
365: 2);
366:
367: public Insets getBorderInsets(final Component component) {
368: return borderInsets;
369: }
370:
371: public void paintBorder(final Component c, final Graphics g,
372: final int x, final int y, final int w, final int h) {
373: Utilities.draw3DRect(g, x, y, w, h, MetalLookAndFeel
374: .getControlShadow(), MetalLookAndFeel
375: .getControlHighlight(), false);
376: }
377: }
378:
379: public static class TableHeaderBorder extends AbstractBorder {
380: protected Insets editorBorderInsets = new Insets(2, 2, 2, 0);
381:
382: public Insets getBorderInsets(final Component c) {
383: return editorBorderInsets;
384: }
385:
386: public void paintBorder(final Component c, final Graphics g,
387: final int x, final int y, final int w, final int h) {
388: Utilities.draw3DRect(g, x, y, w, h, MetalLookAndFeel
389: .getControlShadow(), MetalLookAndFeel
390: .getControlHighlight(), true);
391: }
392: }
393:
394: public static class TextFieldBorder extends Flush3DBorder {
395:
396: public void paintBorder(Component c, Graphics g, int x, int y,
397: int w, int h) {
398: if (!c.isEnabled()) {
399: return;
400: }
401: super .paintBorder(c, g, x, y, w, h);
402: }
403: }
404:
405: public static class ToggleButtonBorder extends ButtonBorder {
406: public void paintBorder(final Component c, final Graphics g,
407: final int x, final int y, final int w, final int h) {
408: if (((AbstractButton) c).isSelected()) {
409: Utilities.draw3DRect(g, x, y, w, h, MetalLookAndFeel
410: .getControlDarkShadow(), MetalLookAndFeel
411: .getControlHighlight(), false);
412: Utilities.draw3DRect(g, x + 1, y + 1, w - 2, h - 2,
413: MetalLookAndFeel.getControlShadow(),
414: MetalLookAndFeel.getControlShadow(), true);
415: } else {
416: super .paintBorder(c, g, x, y, w, h);
417: }
418: }
419: }
420:
421: public static class ToolBarBorder extends AbstractBorder implements
422: UIResource, SwingConstants {
423:
424: private static final int NORMAL_INDENT = 2;
425: private static final int BIGGER_INDENT = 16;
426: private static final Insets INSETS = new Insets(NORMAL_INDENT,
427: NORMAL_INDENT, NORMAL_INDENT, NORMAL_INDENT);
428:
429: protected MetalBumps bumps;
430:
431: public Insets getBorderInsets(final Component c,
432: final Insets insets) {
433: JToolBar toolBar = (JToolBar) c;
434: Insets result = initBorderInsets(insets, INSETS);
435: if (toolBar.isFloatable()) {
436: if (toolBar.getOrientation() == JToolBar.HORIZONTAL) {
437: result.left = BIGGER_INDENT;
438: } else {
439: result.top = BIGGER_INDENT;
440: }
441: }
442:
443: Insets margin = toolBar.getMargin();
444: result.top += margin.top;
445: result.left += margin.left;
446: result.bottom += margin.bottom;
447: result.right += margin.right;
448:
449: return result;
450: }
451:
452: public Insets getBorderInsets(final Component c) {
453: return getBorderInsets(c, null);
454: }
455:
456: public void paintBorder(final Component c, final Graphics g,
457: final int x, final int y, final int w, final int h) {
458: JToolBar toolBar = (JToolBar) c;
459: if (!toolBar.isFloatable()) {
460: return;
461: }
462:
463: int bumpsWidth;
464: int bumpsHeight;
465: if (toolBar.getOrientation() == JToolBar.HORIZONTAL) {
466: bumpsWidth = BIGGER_INDENT - NORMAL_INDENT
467: - NORMAL_INDENT;
468: bumpsHeight = h - NORMAL_INDENT - NORMAL_INDENT;
469: } else {
470: bumpsWidth = w - NORMAL_INDENT - NORMAL_INDENT;
471: bumpsHeight = BIGGER_INDENT - NORMAL_INDENT
472: - NORMAL_INDENT;
473: }
474: MetalBumps.paintBumps(g, x + NORMAL_INDENT, y
475: + NORMAL_INDENT, bumpsWidth, bumpsHeight,
476: MetalLookAndFeel.getControlHighlight(),
477: MetalLookAndFeel.getControlDarkShadow());
478: }
479: }
480:
481: /**
482: * This class implements the border for top level containers.
483: * It is used when <code>JRootPane.windowDecorationStyle</code> is set to
484: * <code>JRootPane.FRAME</code>.
485: */
486: static class FrameBorder extends InternalFrameBorder {
487: boolean isActive(final Component c) {
488: return SwingUtilities.getWindowAncestor(c).isActive();
489: }
490:
491: boolean canBeResized(final Component c) {
492: Window window = SwingUtilities.getWindowAncestor(c);
493: return Utilities.isResizableWindow(window)
494: && !Utilities.isMaximumFrame(window);
495: }
496: }
497:
498: /**
499: * This class implements the border for top level containers.
500: * It is used when <code>JRootPane.windowDecorationStyle</code> is set to
501: * <code>JRootPane.PLAIN_DIALOG</code>.
502: */
503: static class DialogBorder extends FrameBorder {
504: }
505:
506: /**
507: * This class implements the border for top level containers.
508: * It is used when <code>JRootPane.windowDecorationStyle</code> is set to
509: * <code>JRootPane.QUESTION_DIALOG</code>.
510: */
511: static final class QuestionDialogBorder extends DialogBorder {
512: void installColors() {
513: if (activeColor == null) {
514: activeColor = UIManager
515: .getColor("OptionPane.questionDialog.border.background");
516: activeHighlight = MetalLookAndFeel
517: .getPrimaryControlHighlight();
518: activeDarkShadow = UIManager
519: .getColor("OptionPane.questionDialog.border.background");
520: activeShadow = UIManager
521: .getColor("OptionPane.questionDialog.titlePane.shadow");
522: }
523: }
524: }
525:
526: /**
527: * This class implements the border for top level containers.
528: * It is used when <code>JRootPane.windowDecorationStyle</code> is set to
529: * <code>JRootPane.WARNING_DIALOG</code>.
530: */
531: static final class WarningDialogBorder extends DialogBorder {
532: void installColors() {
533: if (activeColor == null) {
534: activeColor = UIManager
535: .getColor("OptionPane.warningDialog.border.background");
536: activeHighlight = MetalLookAndFeel
537: .getPrimaryControlHighlight();
538: activeDarkShadow = UIManager
539: .getColor("OptionPane.warningDialog.border.background");
540: activeShadow = UIManager
541: .getColor("OptionPane.warningDialog.titlePane.shadow");
542: }
543: }
544: }
545:
546: /**
547: * This class implements the border for top level containers.
548: * It is used when <code>JRootPane.windowDecorationStyle</code> is set to
549: * <code>JRootPane.ERROR_DIALOG</code>.
550: */
551: static final class ErrorDialogBorder extends DialogBorder {
552: void installColors() {
553: if (activeColor == null) {
554: activeColor = UIManager
555: .getColor("OptionPane.errorDialog.border.background");
556: activeHighlight = MetalLookAndFeel
557: .getPrimaryControlHighlight();
558: activeDarkShadow = UIManager
559: .getColor("OptionPane.errorDialog.border.background");
560: activeShadow = UIManager
561: .getColor("OptionPane.errorDialog.titlePane.shadow");
562: }
563: }
564: }
565:
566: static class ToolBarButtonMarginBorder extends MarginBorder {
567: /**
568: * Return new instance of the Insets class
569: * @param Component c
570: *
571: * @return Insets result
572: */
573: public Insets getBorderInsets(final Component c) {
574: Insets result = super .getBorderInsets(c);
575: return Utilities.isUIResource(result) ? new Insets(3, 3, 3,
576: 3) : result;
577: }
578: }
579:
580: public static Border getToggleButtonBorder() {
581: return createCompoundBorder(new ToggleButtonBorder());
582: }
583:
584: public static Border getTextFieldBorder() {
585: return createCompoundBorder(new TextFieldBorder());
586: }
587:
588: public static Border getTextBorder() {
589: return createCompoundBorder(new Flush3DBorder());
590: }
591:
592: public static Border getDesktopIconBorder() {
593: LineBorder lineBorder = new LineBorder(new ColorUIResource(122,
594: 138, 153), 1);
595: MatteBorder matteBorder = new MatteBorder(
596: new Insets(2, 2, 1, 2), new ColorUIResource(238, 238,
597: 238));
598:
599: return new BorderUIResource.CompoundBorderUIResource(
600: lineBorder, matteBorder);
601: }
602:
603: public static Border getButtonBorder() {
604: return createCompoundBorder(new ButtonBorder());
605: }
606:
607: /**
608: * The auxiliary function to implement <code>paintBorder()</code> method.
609: * Fills the border area with <code>color</code> color.
610: *
611: * @param c the component that has the painted border
612: * @param g <code>Graphics</code> object to paint
613: * @param x position of the border
614: * @param y position of the border
615: * @param w position of the border
616: * @param h position of the border
617: * @param color the color to fill the border area
618: * @param width the width of the border
619: */
620: private static void fillBorder(final Graphics g, final int x,
621: final int y, final int w, final int h, final Color color,
622: final int width) {
623: Color saveColor = g.getColor();
624: g.setColor(color);
625:
626: g.fillRect(x, y, width, h);
627: g.fillRect(w - width, y, width, h);
628: g.fillRect(x, y, w, width);
629: g.fillRect(x, h - width, w, width);
630:
631: g.setColor(saveColor);
632: }
633:
634: private static Insets initBorderInsets(final Insets result,
635: final Insets template) {
636: if (result == null) {
637: return (Insets) template.clone();
638: }
639:
640: result.bottom = template.bottom;
641: result.left = template.left;
642: result.right = template.right;
643: result.top = template.top;
644:
645: return result;
646: }
647:
648: private static Border createCompoundBorder(final Border b) {
649: return new BorderUIResource.CompoundBorderUIResource(b,
650: new MarginBorder());
651: }
652: }
|