1 /*
2  * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package javax.swing.plaf.metal;
27 
28 import javax.swing.*;
29 import javax.swing.border.*;
30 import javax.swing.plaf.*;
31 import javax.swing.plaf.basic.BasicBorders;
32 import javax.swing.text.JTextComponent;
33 
34 import java.awt.Component;
35 import java.awt.Insets;
36 import java.awt.Color;
37 import java.awt.Dialog;
38 import java.awt.Frame;
39 import java.awt.Graphics;
40 import java.awt.Window;
41 
42 import sun.swing.StringUIClientPropertyKey;
43 import sun.swing.SwingUtilities2;
44 
45 
46 /**
47  * Factory object that can vend Borders appropriate for the metal L & F.
48  * @author Steve Wilson
49  */
50 
51 public class MetalBorders {
52 
53     /**
54      * Client property indicating the button shouldn't provide a rollover
55      * indicator. Only used with the Ocean theme.
56      */
57     static Object NO_BUTTON_ROLLOVER =
58         new StringUIClientPropertyKey("NoButtonRollover");
59 
60 
61     public static class Flush3DBorder extends AbstractBorder implements UIResource{
paintBorder(Component c, Graphics g, int x, int y, int w, int h)62         public void paintBorder(Component c, Graphics g, int x, int y,
63                           int w, int h) {
64             if (c.isEnabled()) {
65                 MetalUtils.drawFlush3DBorder(g, x, y, w, h);
66             } else {
67                 MetalUtils.drawDisabledBorder(g, x, y, w, h);
68             }
69         }
70 
getBorderInsets(Component c, Insets newInsets)71         public Insets getBorderInsets(Component c, Insets newInsets) {
72             newInsets.set(2, 2, 2, 2);
73             return newInsets;
74         }
75     }
76 
77     public static class ButtonBorder extends AbstractBorder implements UIResource {
78 
79         protected static Insets borderInsets = new Insets( 3, 3, 3, 3 );
80 
paintBorder(Component c, Graphics g, int x, int y, int w, int h)81         public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
82             if (!(c instanceof AbstractButton)) {
83                 return;
84             }
85             if (MetalLookAndFeel.usingOcean()) {
86                 paintOceanBorder(c, g, x, y, w, h);
87                 return;
88             }
89             AbstractButton button = (AbstractButton)c;
90             ButtonModel model = button.getModel();
91 
92             if ( model.isEnabled() ) {
93                 boolean isPressed = model.isPressed() && model.isArmed();
94                 boolean isDefault = (button instanceof JButton && ((JButton)button).isDefaultButton());
95 
96                 if (isPressed && isDefault) {
97                     MetalUtils.drawDefaultButtonPressedBorder(g, x, y, w, h);
98                 } else if (isPressed) {
99                     MetalUtils.drawPressed3DBorder( g, x, y, w, h );
100                 } else if (isDefault) {
101                     MetalUtils.drawDefaultButtonBorder( g, x, y, w, h, false);
102                 } else {
103                     MetalUtils.drawButtonBorder( g, x, y, w, h, false);
104                 }
105             } else { // disabled state
106                 MetalUtils.drawDisabledBorder( g, x, y, w-1, h-1 );
107             }
108         }
109 
paintOceanBorder(Component c, Graphics g, int x, int y, int w, int h)110         private void paintOceanBorder(Component c, Graphics g, int x, int y,
111                                       int w, int h) {
112             AbstractButton button = (AbstractButton)c;
113             ButtonModel model = ((AbstractButton)c).getModel();
114 
115             g.translate(x, y);
116             if (MetalUtils.isToolBarButton(button)) {
117                 if (model.isEnabled()) {
118                     if (model.isPressed()) {
119                         g.setColor(MetalLookAndFeel.getWhite());
120                         g.fillRect(1, h - 1, w - 1, 1);
121                         g.fillRect(w - 1, 1, 1, h - 1);
122                         g.setColor(MetalLookAndFeel.getControlDarkShadow());
123                         g.drawRect(0, 0, w - 2, h - 2);
124                         g.fillRect(1, 1, w - 3, 1);
125                     }
126                     else if (model.isSelected() || model.isRollover()) {
127                         g.setColor(MetalLookAndFeel.getWhite());
128                         g.fillRect(1, h - 1, w - 1, 1);
129                         g.fillRect(w - 1, 1, 1, h - 1);
130                         g.setColor(MetalLookAndFeel.getControlDarkShadow());
131                         g.drawRect(0, 0, w - 2, h - 2);
132                     }
133                     else {
134                         g.setColor(MetalLookAndFeel.getWhite());
135                         g.drawRect(1, 1, w - 2, h - 2);
136                         g.setColor(UIManager.getColor(
137                                 "Button.toolBarBorderBackground"));
138                         g.drawRect(0, 0, w - 2, h - 2);
139                     }
140                 }
141                 else {
142                    g.setColor(UIManager.getColor(
143                            "Button.disabledToolBarBorderBackground"));
144                    g.drawRect(0, 0, w - 2, h - 2);
145                 }
146             }
147             else if (model.isEnabled()) {
148                 boolean pressed = model.isPressed();
149                 boolean armed = model.isArmed();
150 
151                 if ((c instanceof JButton) && ((JButton)c).isDefaultButton()) {
152                     g.setColor(MetalLookAndFeel.getControlDarkShadow());
153                     g.drawRect(0, 0, w - 1, h - 1);
154                     g.drawRect(1, 1, w - 3, h - 3);
155                 }
156                 else if (pressed) {
157                     g.setColor(MetalLookAndFeel.getControlDarkShadow());
158                     g.fillRect(0, 0, w, 2);
159                     g.fillRect(0, 2, 2, h - 2);
160                     g.fillRect(w - 1, 1, 1, h - 1);
161                     g.fillRect(1, h - 1, w - 2, 1);
162                 }
163                 else if (model.isRollover() && button.getClientProperty(
164                                NO_BUTTON_ROLLOVER) == null) {
165                     g.setColor(MetalLookAndFeel.getPrimaryControl());
166                     g.drawRect(0, 0, w - 1, h - 1);
167                     g.drawRect(2, 2, w - 5, h - 5);
168                     g.setColor(MetalLookAndFeel.getControlDarkShadow());
169                     g.drawRect(1, 1, w - 3, h - 3);
170                 }
171                 else {
172                     g.setColor(MetalLookAndFeel.getControlDarkShadow());
173                     g.drawRect(0, 0, w - 1, h - 1);
174                 }
175             }
176             else {
177                 g.setColor(MetalLookAndFeel.getInactiveControlTextColor());
178                 g.drawRect(0, 0, w - 1, h - 1);
179                 if ((c instanceof JButton) && ((JButton)c).isDefaultButton()) {
180                     g.drawRect(1, 1, w - 3, h - 3);
181                 }
182             }
183         }
184 
getBorderInsets(Component c, Insets newInsets)185         public Insets getBorderInsets(Component c, Insets newInsets) {
186             newInsets.set(3, 3, 3, 3);
187             return newInsets;
188         }
189     }
190 
191     public static class InternalFrameBorder extends AbstractBorder implements UIResource {
192         private static final int corner = 14;
193 
paintBorder(Component c, Graphics g, int x, int y, int w, int h)194         public void paintBorder(Component c, Graphics g, int x, int y,
195                           int w, int h) {
196 
197             Color background;
198             Color highlight;
199             Color shadow;
200 
201             if (c instanceof JInternalFrame && ((JInternalFrame)c).isSelected()) {
202                 background = MetalLookAndFeel.getPrimaryControlDarkShadow();
203                 highlight = MetalLookAndFeel.getPrimaryControlShadow();
204                 shadow = MetalLookAndFeel.getPrimaryControlInfo();
205             } else {
206                 background = MetalLookAndFeel.getControlDarkShadow();
207                 highlight = MetalLookAndFeel.getControlShadow();
208                 shadow = MetalLookAndFeel.getControlInfo();
209             }
210 
211               g.setColor(background);
212               // Draw outermost lines
213               g.drawLine( 1, 0, w-2, 0);
214               g.drawLine( 0, 1, 0, h-2);
215               g.drawLine( w-1, 1, w-1, h-2);
216               g.drawLine( 1, h-1, w-2, h-1);
217 
218               // Draw the bulk of the border
219               for (int i = 1; i < 5; i++) {
220                   g.drawRect(x+i,y+i,w-(i*2)-1, h-(i*2)-1);
221               }
222 
223               if (c instanceof JInternalFrame &&
224                                ((JInternalFrame)c).isResizable()) {
225                   g.setColor(highlight);
226                   // Draw the Long highlight lines
227                   g.drawLine( corner+1, 3, w-corner, 3);
228                   g.drawLine( 3, corner+1, 3, h-corner);
229                   g.drawLine( w-2, corner+1, w-2, h-corner);
230                   g.drawLine( corner+1, h-2, w-corner, h-2);
231 
232                   g.setColor(shadow);
233                   // Draw the Long shadow lines
234                   g.drawLine( corner, 2, w-corner-1, 2);
235                   g.drawLine( 2, corner, 2, h-corner-1);
236                   g.drawLine( w-3, corner, w-3, h-corner-1);
237                   g.drawLine( corner, h-3, w-corner-1, h-3);
238               }
239 
240           }
241 
getBorderInsets(Component c, Insets newInsets)242           public Insets getBorderInsets(Component c, Insets newInsets) {
243               newInsets.set(5, 5, 5, 5);
244               return newInsets;
245           }
246     }
247 
248     /**
249      * Border for a Frame.
250      * @since 1.4
251      */
252     static class FrameBorder extends AbstractBorder implements UIResource {
253         private static final int corner = 14;
254 
paintBorder(Component c, Graphics g, int x, int y, int w, int h)255         public void paintBorder(Component c, Graphics g, int x, int y,
256             int w, int h) {
257 
258             Color background;
259             Color highlight;
260             Color shadow;
261 
262             Window window = SwingUtilities.getWindowAncestor(c);
263             if (window != null && window.isActive()) {
264                 background = MetalLookAndFeel.getPrimaryControlDarkShadow();
265                 highlight = MetalLookAndFeel.getPrimaryControlShadow();
266                 shadow = MetalLookAndFeel.getPrimaryControlInfo();
267             } else {
268                 background = MetalLookAndFeel.getControlDarkShadow();
269                 highlight = MetalLookAndFeel.getControlShadow();
270                 shadow = MetalLookAndFeel.getControlInfo();
271             }
272 
273             g.setColor(background);
274             // Draw outermost lines
275             g.drawLine( x+1, y+0, x+w-2, y+0);
276             g.drawLine( x+0, y+1, x+0, y +h-2);
277             g.drawLine( x+w-1, y+1, x+w-1, y+h-2);
278             g.drawLine( x+1, y+h-1, x+w-2, y+h-1);
279 
280             // Draw the bulk of the border
281             for (int i = 1; i < 5; i++) {
282                 g.drawRect(x+i,y+i,w-(i*2)-1, h-(i*2)-1);
283             }
284 
285             if ((window instanceof Frame) && ((Frame) window).isResizable()) {
286                 g.setColor(highlight);
287                 // Draw the Long highlight lines
288                 g.drawLine( corner+1, 3, w-corner, 3);
289                 g.drawLine( 3, corner+1, 3, h-corner);
290                 g.drawLine( w-2, corner+1, w-2, h-corner);
291                 g.drawLine( corner+1, h-2, w-corner, h-2);
292 
293                 g.setColor(shadow);
294                 // Draw the Long shadow lines
295                 g.drawLine( corner, 2, w-corner-1, 2);
296                 g.drawLine( 2, corner, 2, h-corner-1);
297                 g.drawLine( w-3, corner, w-3, h-corner-1);
298                 g.drawLine( corner, h-3, w-corner-1, h-3);
299             }
300 
301         }
302 
getBorderInsets(Component c, Insets newInsets)303         public Insets getBorderInsets(Component c, Insets newInsets)
304         {
305             newInsets.set(5, 5, 5, 5);
306             return newInsets;
307         }
308     }
309 
310     /**
311      * Border for a Frame.
312      * @since 1.4
313      */
314     static class DialogBorder extends AbstractBorder implements UIResource
315     {
316         private static final int corner = 14;
317 
getActiveBackground()318         protected Color getActiveBackground()
319         {
320             return MetalLookAndFeel.getPrimaryControlDarkShadow();
321         }
322 
getActiveHighlight()323         protected Color getActiveHighlight()
324         {
325             return MetalLookAndFeel.getPrimaryControlShadow();
326         }
327 
getActiveShadow()328         protected Color getActiveShadow()
329         {
330             return MetalLookAndFeel.getPrimaryControlInfo();
331         }
332 
getInactiveBackground()333         protected Color getInactiveBackground()
334         {
335             return MetalLookAndFeel.getControlDarkShadow();
336         }
337 
getInactiveHighlight()338         protected Color getInactiveHighlight()
339         {
340             return MetalLookAndFeel.getControlShadow();
341         }
342 
getInactiveShadow()343         protected Color getInactiveShadow()
344         {
345             return MetalLookAndFeel.getControlInfo();
346         }
347 
paintBorder(Component c, Graphics g, int x, int y, int w, int h)348         public void paintBorder(Component c, Graphics g, int x, int y, int w, int h)
349         {
350             Color background;
351             Color highlight;
352             Color shadow;
353 
354             Window window = SwingUtilities.getWindowAncestor(c);
355             if (window != null && window.isActive()) {
356                 background = getActiveBackground();
357                 highlight = getActiveHighlight();
358                 shadow = getActiveShadow();
359             } else {
360                 background = getInactiveBackground();
361                 highlight = getInactiveHighlight();
362                 shadow = getInactiveShadow();
363             }
364 
365             g.setColor(background);
366             // Draw outermost lines
367             g.drawLine( x + 1, y + 0, x + w-2, y + 0);
368             g.drawLine( x + 0, y + 1, x + 0, y + h - 2);
369             g.drawLine( x + w - 1, y + 1, x + w - 1, y + h - 2);
370             g.drawLine( x + 1, y + h - 1, x + w - 2, y + h - 1);
371 
372             // Draw the bulk of the border
373             for (int i = 1; i < 5; i++) {
374                 g.drawRect(x+i,y+i,w-(i*2)-1, h-(i*2)-1);
375             }
376 
377 
378             if ((window instanceof Dialog) && ((Dialog) window).isResizable()) {
379                 g.setColor(highlight);
380                 // Draw the Long highlight lines
381                 g.drawLine( corner+1, 3, w-corner, 3);
382                 g.drawLine( 3, corner+1, 3, h-corner);
383                 g.drawLine( w-2, corner+1, w-2, h-corner);
384                 g.drawLine( corner+1, h-2, w-corner, h-2);
385 
386                 g.setColor(shadow);
387                 // Draw the Long shadow lines
388                 g.drawLine( corner, 2, w-corner-1, 2);
389                 g.drawLine( 2, corner, 2, h-corner-1);
390                 g.drawLine( w-3, corner, w-3, h-corner-1);
391                 g.drawLine( corner, h-3, w-corner-1, h-3);
392             }
393 
394         }
395 
getBorderInsets(Component c, Insets newInsets)396         public Insets getBorderInsets(Component c, Insets newInsets)
397         {
398             newInsets.set(5, 5, 5, 5);
399             return newInsets;
400         }
401     }
402 
403     /**
404      * Border for an Error Dialog.
405      * @since 1.4
406      */
407     static class ErrorDialogBorder extends DialogBorder implements UIResource
408     {
getActiveBackground()409         protected Color getActiveBackground() {
410             return UIManager.getColor("OptionPane.errorDialog.border.background");
411         }
412     }
413 
414 
415     /**
416      * Border for a QuestionDialog.  Also used for a JFileChooser and a
417      * JColorChooser..
418      * @since 1.4
419      */
420     static class QuestionDialogBorder extends DialogBorder implements UIResource
421     {
getActiveBackground()422         protected Color getActiveBackground() {
423             return UIManager.getColor("OptionPane.questionDialog.border.background");
424         }
425     }
426 
427 
428     /**
429      * Border for a Warning Dialog.
430      * @since 1.4
431      */
432     static class WarningDialogBorder extends DialogBorder implements UIResource
433     {
getActiveBackground()434         protected Color getActiveBackground() {
435             return UIManager.getColor("OptionPane.warningDialog.border.background");
436         }
437     }
438 
439 
440     /**
441      * Border for a Palette.
442      * @since 1.3
443      */
444     public static class PaletteBorder extends AbstractBorder implements UIResource {
445         int titleHeight = 0;
446 
paintBorder( Component c, Graphics g, int x, int y, int w, int h )447         public void paintBorder( Component c, Graphics g, int x, int y, int w, int h ) {
448 
449             g.translate(x,y);
450             g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
451             g.drawLine(0, 1, 0, h-2);
452             g.drawLine(1, h-1, w-2, h-1);
453             g.drawLine(w-1,  1, w-1, h-2);
454             g.drawLine( 1, 0, w-2, 0);
455             g.drawRect(1,1, w-3, h-3);
456             g.translate(-x,-y);
457 
458         }
459 
getBorderInsets(Component c, Insets newInsets)460         public Insets getBorderInsets(Component c, Insets newInsets) {
461             newInsets.set(1, 1, 1, 1);
462             return newInsets;
463         }
464     }
465 
466     public static class OptionDialogBorder extends AbstractBorder implements UIResource {
467         int titleHeight = 0;
468 
paintBorder( Component c, Graphics g, int x, int y, int w, int h )469         public void paintBorder( Component c, Graphics g, int x, int y, int w, int h ) {
470 
471             g.translate(x,y);
472 
473             int messageType = JOptionPane.PLAIN_MESSAGE;
474             if (c instanceof JInternalFrame) {
475                 Object obj = ((JInternalFrame) c).getClientProperty(
476                               "JInternalFrame.messageType");
477                 if (obj instanceof Integer) {
478                     messageType = (Integer) obj;
479                 }
480             }
481 
482             Color borderColor;
483 
484             switch (messageType) {
485             case(JOptionPane.ERROR_MESSAGE):
486                 borderColor = UIManager.getColor(
487                     "OptionPane.errorDialog.border.background");
488                 break;
489             case(JOptionPane.QUESTION_MESSAGE):
490                 borderColor = UIManager.getColor(
491                     "OptionPane.questionDialog.border.background");
492                 break;
493             case(JOptionPane.WARNING_MESSAGE):
494                 borderColor = UIManager.getColor(
495                     "OptionPane.warningDialog.border.background");
496                 break;
497             case(JOptionPane.INFORMATION_MESSAGE):
498             case(JOptionPane.PLAIN_MESSAGE):
499             default:
500                 borderColor = MetalLookAndFeel.getPrimaryControlDarkShadow();
501                 break;
502             }
503 
504             g.setColor(borderColor);
505 
506               // Draw outermost lines
507               g.drawLine( 1, 0, w-2, 0);
508               g.drawLine( 0, 1, 0, h-2);
509               g.drawLine( w-1, 1, w-1, h-2);
510               g.drawLine( 1, h-1, w-2, h-1);
511 
512               // Draw the bulk of the border
513               for (int i = 1; i < 3; i++) {
514                   g.drawRect(i, i, w-(i*2)-1, h-(i*2)-1);
515               }
516 
517             g.translate(-x,-y);
518 
519         }
520 
getBorderInsets(Component c, Insets newInsets)521         public Insets getBorderInsets(Component c, Insets newInsets) {
522             newInsets.set(3, 3, 3, 3);
523             return newInsets;
524         }
525     }
526 
527 
528     public static class MenuBarBorder extends AbstractBorder implements UIResource {
529         protected static Insets borderInsets = new Insets( 1, 0, 1, 0 );
530 
paintBorder( Component c, Graphics g, int x, int y, int w, int h )531         public void paintBorder( Component c, Graphics g, int x, int y, int w, int h ) {
532             g.translate(x, y);
533 
534             if (MetalLookAndFeel.usingOcean()) {
535                 // Only paint a border if we're not next to a horizontal toolbar
536                 if (c instanceof JMenuBar
537                         && !MetalToolBarUI.doesMenuBarBorderToolBar((JMenuBar)c)) {
538                     g.setColor(MetalLookAndFeel.getControl());
539                     SwingUtilities2.drawHLine(g, 0, w - 1, h - 2);
540                     g.setColor(UIManager.getColor("MenuBar.borderColor"));
541                     SwingUtilities2.drawHLine(g, 0, w - 1, h - 1);
542                 }
543             } else {
544                 g.setColor(MetalLookAndFeel.getControlShadow());
545                 SwingUtilities2.drawHLine(g, 0, w - 1, h - 1);
546             }
547             g.translate(-x, -y);
548         }
549 
getBorderInsets(Component c, Insets newInsets)550         public Insets getBorderInsets(Component c, Insets newInsets) {
551             if (MetalLookAndFeel.usingOcean()) {
552                 newInsets.set(0, 0, 2, 0);
553             }
554             else {
555                 newInsets.set(1, 0, 1, 0);
556             }
557             return newInsets;
558         }
559     }
560 
561     public static class MenuItemBorder extends AbstractBorder implements UIResource {
562         protected static Insets borderInsets = new Insets( 2, 2, 2, 2 );
563 
paintBorder( Component c, Graphics g, int x, int y, int w, int h )564         public void paintBorder( Component c, Graphics g, int x, int y, int w, int h ) {
565             if (!(c instanceof JMenuItem)) {
566                 return;
567             }
568             JMenuItem b = (JMenuItem) c;
569             ButtonModel model = b.getModel();
570 
571             g.translate( x, y );
572 
573             if ( c.getParent() instanceof JMenuBar ) {
574                 if ( model.isArmed() || model.isSelected() ) {
575                     g.setColor( MetalLookAndFeel.getControlDarkShadow() );
576                     g.drawLine( 0, 0, w - 2, 0 );
577                     g.drawLine( 0, 0, 0, h - 1 );
578                     g.drawLine( w - 2, 2, w - 2, h - 1 );
579 
580                     g.setColor( MetalLookAndFeel.getPrimaryControlHighlight() );
581                     g.drawLine( w - 1, 1, w - 1, h - 1 );
582 
583                     g.setColor( MetalLookAndFeel.getMenuBackground() );
584                     g.drawLine( w - 1, 0, w - 1, 0 );
585                 }
586             } else {
587                 if (  model.isArmed() || ( c instanceof JMenu && model.isSelected() ) ) {
588                     g.setColor( MetalLookAndFeel.getPrimaryControlDarkShadow() );
589                     g.drawLine( 0, 0, w - 1, 0 );
590 
591                     g.setColor( MetalLookAndFeel.getPrimaryControlHighlight() );
592                     g.drawLine( 0, h - 1, w - 1, h - 1 );
593                 } else {
594                     g.setColor( MetalLookAndFeel.getPrimaryControlHighlight() );
595                     g.drawLine( 0, 0, 0, h - 1 );
596                 }
597             }
598 
599             g.translate( -x, -y );
600         }
601 
getBorderInsets(Component c, Insets newInsets)602         public Insets getBorderInsets(Component c, Insets newInsets) {
603             newInsets.set(2, 2, 2, 2);
604             return newInsets;
605         }
606     }
607 
608     public static class PopupMenuBorder extends AbstractBorder implements UIResource {
609         protected static Insets borderInsets = new Insets( 3, 1, 2, 1 );
610 
paintBorder( Component c, Graphics g, int x, int y, int w, int h )611         public void paintBorder( Component c, Graphics g, int x, int y, int w, int h ) {
612             g.translate( x, y );
613 
614             g.setColor( MetalLookAndFeel.getPrimaryControlDarkShadow() );
615             g.drawRect( 0, 0, w - 1, h - 1 );
616 
617             g.setColor( MetalLookAndFeel.getPrimaryControlHighlight() );
618             g.drawLine( 1, 1, w - 2, 1 );
619             g.drawLine( 1, 2, 1, 2 );
620             g.drawLine( 1, h - 2, 1, h - 2 );
621 
622             g.translate( -x, -y );
623 
624         }
625 
getBorderInsets(Component c, Insets newInsets)626         public Insets getBorderInsets(Component c, Insets newInsets) {
627             newInsets.set(3, 1, 2, 1);
628             return newInsets;
629         }
630     }
631 
632 
633     public static class RolloverButtonBorder extends ButtonBorder {
634 
paintBorder( Component c, Graphics g, int x, int y, int w, int h )635         public void paintBorder( Component c, Graphics g, int x, int y, int w, int h ) {
636             AbstractButton b = (AbstractButton) c;
637             ButtonModel model = b.getModel();
638 
639             if ( model.isRollover() && !( model.isPressed() && !model.isArmed() ) ) {
640                 super.paintBorder( c, g, x, y, w, h );
641             }
642         }
643 
644     }
645 
646     /**
647      * A border which is like a Margin border but it will only honor the margin
648      * if the margin has been explicitly set by the developer.
649      *
650      * Note: This is identical to the package private class
651      * BasicBorders.RolloverMarginBorder and should probably be consolidated.
652      */
653     static class RolloverMarginBorder extends EmptyBorder {
654 
RolloverMarginBorder()655         public RolloverMarginBorder() {
656             super(3,3,3,3); // hardcoded margin for JLF requirements.
657         }
658 
getBorderInsets(Component c, Insets insets)659         public Insets getBorderInsets(Component c, Insets insets) {
660             Insets margin = null;
661 
662             if (c instanceof AbstractButton) {
663                 margin = ((AbstractButton)c).getMargin();
664             }
665             if (margin == null || margin instanceof UIResource) {
666                 // default margin so replace
667                 insets.left = left;
668                 insets.top = top;
669                 insets.right = right;
670                 insets.bottom = bottom;
671             } else {
672                 // Margin which has been explicitly set by the user.
673                 insets.left = margin.left;
674                 insets.top = margin.top;
675                 insets.right = margin.right;
676                 insets.bottom = margin.bottom;
677             }
678             return insets;
679         }
680     }
681 
682     public static class ToolBarBorder extends AbstractBorder implements UIResource, SwingConstants
683     {
684         protected MetalBumps bumps = new MetalBumps( 10, 10,
685                                       MetalLookAndFeel.getControlHighlight(),
686                                       MetalLookAndFeel.getControlDarkShadow(),
687                                      UIManager.getColor("ToolBar.background"));
688 
paintBorder( Component c, Graphics g, int x, int y, int w, int h )689         public void paintBorder( Component c, Graphics g, int x, int y, int w, int h )
690         {
691             if (!(c instanceof JToolBar)) {
692                 return;
693             }
694             g.translate( x, y );
695 
696             if ( ((JToolBar) c).isFloatable() )
697             {
698                 if ( ((JToolBar) c).getOrientation() == HORIZONTAL )
699                 {
700                     int shift = MetalLookAndFeel.usingOcean() ? -1 : 0;
701                     bumps.setBumpArea( 10, h - 4 );
702                     if( MetalUtils.isLeftToRight(c) ) {
703                         bumps.paintIcon( c, g, 2, 2 + shift );
704                     } else {
705                         bumps.paintIcon( c, g, w-12,
706                                          2 + shift );
707                     }
708                 }
709                 else // vertical
710                 {
711                     bumps.setBumpArea( w - 4, 10 );
712                     bumps.paintIcon( c, g, 2, 2 );
713                 }
714 
715             }
716 
717             if (((JToolBar) c).getOrientation() == HORIZONTAL &&
718                                MetalLookAndFeel.usingOcean()) {
719                 g.setColor(MetalLookAndFeel.getControl());
720                 g.drawLine(0, h - 2, w, h - 2);
721                 g.setColor(UIManager.getColor("ToolBar.borderColor"));
722                 g.drawLine(0, h - 1, w, h - 1);
723             }
724 
725             g.translate( -x, -y );
726         }
727 
getBorderInsets(Component c, Insets newInsets)728         public Insets getBorderInsets(Component c, Insets newInsets) {
729             if (MetalLookAndFeel.usingOcean()) {
730                 newInsets.set(1, 2, 3, 2);
731             }
732             else {
733                 newInsets.top = newInsets.left = newInsets.bottom = newInsets.right = 2;
734             }
735 
736             if (!(c instanceof JToolBar)) {
737                 return newInsets;
738             }
739             if ( ((JToolBar) c).isFloatable() ) {
740                 if ( ((JToolBar) c).getOrientation() == HORIZONTAL ) {
741                     if (c.getComponentOrientation().isLeftToRight()) {
742                         newInsets.left = 16;
743                     } else {
744                         newInsets.right = 16;
745                     }
746                 } else {// vertical
747                     newInsets.top = 16;
748                 }
749             }
750 
751             Insets margin = ((JToolBar) c).getMargin();
752 
753             if ( margin != null ) {
754                 newInsets.left   += margin.left;
755                 newInsets.top    += margin.top;
756                 newInsets.right  += margin.right;
757                 newInsets.bottom += margin.bottom;
758             }
759 
760             return newInsets;
761         }
762     }
763 
764     private static Border buttonBorder;
765 
766     /**
767      * Returns a border instance for a JButton
768      * @since 1.3
769      */
getButtonBorder()770     public static Border getButtonBorder() {
771         if (buttonBorder == null) {
772             buttonBorder = new BorderUIResource.CompoundBorderUIResource(
773                                                    new MetalBorders.ButtonBorder(),
774                                                    new BasicBorders.MarginBorder());
775         }
776         return buttonBorder;
777     }
778 
779     private static Border textBorder;
780 
781     /**
782      * Returns a border instance for a text component
783      * @since 1.3
784      */
getTextBorder()785     public static Border getTextBorder() {
786         if (textBorder == null) {
787             textBorder = new BorderUIResource.CompoundBorderUIResource(
788                                                    new MetalBorders.Flush3DBorder(),
789                                                    new BasicBorders.MarginBorder());
790         }
791         return textBorder;
792     }
793 
794     private static Border textFieldBorder;
795 
796     /**
797      * Returns a border instance for a JTextField
798      * @since 1.3
799      */
getTextFieldBorder()800     public static Border getTextFieldBorder() {
801         if (textFieldBorder == null) {
802             textFieldBorder = new BorderUIResource.CompoundBorderUIResource(
803                                                    new MetalBorders.TextFieldBorder(),
804                                                    new BasicBorders.MarginBorder());
805         }
806         return textFieldBorder;
807     }
808 
809     public static class TextFieldBorder extends Flush3DBorder {
810 
paintBorder(Component c, Graphics g, int x, int y, int w, int h)811         public void paintBorder(Component c, Graphics g, int x, int y,
812                                 int w, int h) {
813 
814           if (!(c instanceof JTextComponent)) {
815                 // special case for non-text components (bug ID 4144840)
816                 if (c.isEnabled()) {
817                     MetalUtils.drawFlush3DBorder(g, x, y, w, h);
818                 } else {
819                     MetalUtils.drawDisabledBorder(g, x, y, w, h);
820                 }
821                 return;
822             }
823 
824             if (c.isEnabled() && ((JTextComponent)c).isEditable()) {
825                 MetalUtils.drawFlush3DBorder(g, x, y, w, h);
826             } else {
827                 MetalUtils.drawDisabledBorder(g, x, y, w, h);
828             }
829 
830         }
831     }
832 
833     public static class ScrollPaneBorder extends AbstractBorder implements UIResource {
paintBorder(Component c, Graphics g, int x, int y, int w, int h)834         public void paintBorder(Component c, Graphics g, int x, int y,
835                           int w, int h) {
836 
837             if (!(c instanceof JScrollPane)) {
838                 return;
839             }
840             JScrollPane scroll = (JScrollPane)c;
841             JComponent colHeader = scroll.getColumnHeader();
842             int colHeaderHeight = 0;
843             if (colHeader != null)
844                colHeaderHeight = colHeader.getHeight();
845 
846             JComponent rowHeader = scroll.getRowHeader();
847             int rowHeaderWidth = 0;
848             if (rowHeader != null)
849                rowHeaderWidth = rowHeader.getWidth();
850 
851 
852             g.translate( x, y);
853 
854             g.setColor( MetalLookAndFeel.getControlDarkShadow() );
855             g.drawRect( 0, 0, w-2, h-2 );
856             g.setColor( MetalLookAndFeel.getControlHighlight() );
857 
858             g.drawLine( w-1, 1, w-1, h-1);
859             g.drawLine( 1, h-1, w-1, h-1);
860 
861             g.setColor( MetalLookAndFeel.getControl() );
862             g.drawLine( w-2, 2+colHeaderHeight, w-2, 2+colHeaderHeight );
863             g.drawLine( 1+rowHeaderWidth, h-2, 1+rowHeaderWidth, h-2 );
864 
865             g.translate( -x, -y);
866 
867         }
868 
getBorderInsets(Component c, Insets insets)869         public Insets getBorderInsets(Component c, Insets insets) {
870             insets.set(1, 1, 2, 2);
871             return insets;
872         }
873     }
874 
875     private static Border toggleButtonBorder;
876 
877     /**
878      * Returns a border instance for a JToggleButton
879      * @since 1.3
880      */
getToggleButtonBorder()881     public static Border getToggleButtonBorder() {
882         if (toggleButtonBorder == null) {
883             toggleButtonBorder = new BorderUIResource.CompoundBorderUIResource(
884                                                    new MetalBorders.ToggleButtonBorder(),
885                                                    new BasicBorders.MarginBorder());
886         }
887         return toggleButtonBorder;
888     }
889 
890     /**
891      * @since 1.3
892      */
893     public static class ToggleButtonBorder extends ButtonBorder {
paintBorder(Component c, Graphics g, int x, int y, int w, int h)894         public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
895             AbstractButton button = (AbstractButton)c;
896             ButtonModel model = button.getModel();
897             if (MetalLookAndFeel.usingOcean()) {
898                 if(model.isArmed() || !button.isEnabled()) {
899                     super.paintBorder(c, g, x, y, w, h);
900                 }
901                 else {
902                  g.setColor(MetalLookAndFeel.getControlDarkShadow());
903                  g.drawRect(0, 0, w - 1, h - 1);
904             }
905             return;
906         }
907             if (! c.isEnabled() ) {
908                 MetalUtils.drawDisabledBorder( g, x, y, w-1, h-1 );
909             } else {
910                 if ( model.isPressed() && model.isArmed() ) {
911                    MetalUtils.drawPressed3DBorder( g, x, y, w, h );
912                 } else if ( model.isSelected() ) {
913                     MetalUtils.drawDark3DBorder( g, x, y, w, h );
914                 } else {
915                     MetalUtils.drawFlush3DBorder( g, x, y, w, h );
916                 }
917             }
918         }
919     }
920 
921     /**
922      * Border for a Table Header
923      * @since 1.3
924      */
925     public static class TableHeaderBorder extends javax.swing.border.AbstractBorder {
926         protected Insets editorBorderInsets = new Insets( 2, 2, 2, 0 );
927 
paintBorder(Component c, Graphics g, int x, int y, int w, int h)928         public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
929             g.translate( x, y );
930 
931             g.setColor( MetalLookAndFeel.getControlDarkShadow() );
932             g.drawLine( w-1, 0, w-1, h-1 );
933             g.drawLine( 1, h-1, w-1, h-1 );
934             g.setColor( MetalLookAndFeel.getControlHighlight() );
935             g.drawLine( 0, 0, w-2, 0 );
936             g.drawLine( 0, 0, 0, h-2 );
937 
938             g.translate( -x, -y );
939         }
940 
getBorderInsets(Component c, Insets insets)941         public Insets getBorderInsets(Component c, Insets insets) {
942             insets.set(2, 2, 2, 0);
943             return insets;
944         }
945     }
946 
947     /**
948      * Returns a border instance for a Desktop Icon
949      * @since 1.3
950      */
getDesktopIconBorder()951     public static Border getDesktopIconBorder() {
952         return new BorderUIResource.CompoundBorderUIResource(
953                                           new LineBorder(MetalLookAndFeel.getControlDarkShadow(), 1),
954                                           new MatteBorder (2,2,1,2, MetalLookAndFeel.getControl()));
955     }
956 
getToolBarRolloverBorder()957     static Border getToolBarRolloverBorder() {
958         if (MetalLookAndFeel.usingOcean()) {
959             return new CompoundBorder(
960                 new MetalBorders.ButtonBorder(),
961                 new MetalBorders.RolloverMarginBorder());
962         }
963         return new CompoundBorder(new MetalBorders.RolloverButtonBorder(),
964                                   new MetalBorders.RolloverMarginBorder());
965     }
966 
getToolBarNonrolloverBorder()967     static Border getToolBarNonrolloverBorder() {
968         if (MetalLookAndFeel.usingOcean()) {
969             new CompoundBorder(
970                 new MetalBorders.ButtonBorder(),
971                 new MetalBorders.RolloverMarginBorder());
972         }
973         return new CompoundBorder(new MetalBorders.ButtonBorder(),
974                                   new MetalBorders.RolloverMarginBorder());
975     }
976 }
977