1 /*
2  * Copyright (c) 1998, 2010, 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 com.sun.java.swing.plaf.windows;
27 
28 import javax.swing.*;
29 import javax.swing.border.*;
30 import javax.swing.plaf.*;
31 import javax.swing.plaf.basic.*;
32 
33 import java.awt.Component;
34 import java.awt.Insets;
35 import java.awt.Color;
36 import java.awt.Graphics;
37 
38 import static com.sun.java.swing.plaf.windows.TMSchema.*;
39 import static com.sun.java.swing.plaf.windows.XPStyle.Skin;
40 
41 /**
42  * Factory object that can vend Borders appropriate for the Windows 95 L & F.
43  * @author Rich Schiavi
44  */
45 
46 public class WindowsBorders {
47 
48     /**
49      * Returns a  border instance for a Windows Progress Bar
50      * @since 1.4
51      */
getProgressBarBorder()52     public static Border getProgressBarBorder() {
53         UIDefaults table = UIManager.getLookAndFeelDefaults();
54         Border progressBarBorder = new BorderUIResource.CompoundBorderUIResource(
55                                          new WindowsBorders.ProgressBarBorder(
56                                               table.getColor("ProgressBar.shadow"),
57                                               table.getColor("ProgressBar.highlight")),
58                                               new EmptyBorder(1,1,1,1)
59                                         );
60         return progressBarBorder;
61     }
62 
63     /**
64      * Returns a border instance for a Windows ToolBar
65      *
66      * @return a border used for the toolbar
67      * @since 1.4
68      */
getToolBarBorder()69     public static Border getToolBarBorder() {
70         UIDefaults table = UIManager.getLookAndFeelDefaults();
71         Border toolBarBorder = new WindowsBorders.ToolBarBorder(
72                                         table.getColor("ToolBar.shadow"),
73                                         table.getColor("ToolBar.highlight"));
74         return toolBarBorder;
75     }
76 
77     /**
78      * Returns an new instance of a border used to indicate which cell item
79      * has focus.
80      *
81      * @return a border to indicate which cell item has focus
82      * @since 1.4
83      */
getFocusCellHighlightBorder()84     public static Border getFocusCellHighlightBorder() {
85         return new ComplementDashedBorder();
86     }
87 
getTableHeaderBorder()88     public static Border getTableHeaderBorder() {
89         UIDefaults table = UIManager.getLookAndFeelDefaults();
90         Border tableHeaderBorder = new BorderUIResource.CompoundBorderUIResource(
91                            new BasicBorders.ButtonBorder(
92                                            table.getColor("Table.shadow"),
93                                            table.getColor("Table.darkShadow"),
94                                            table.getColor("Table.light"),
95                                            table.getColor("Table.highlight")),
96                                      new BasicBorders.MarginBorder());
97         return tableHeaderBorder;
98     }
99 
getInternalFrameBorder()100     public static Border getInternalFrameBorder() {
101         UIDefaults table = UIManager.getLookAndFeelDefaults();
102         Border internalFrameBorder = new
103             BorderUIResource.CompoundBorderUIResource(
104                 BorderFactory.createBevelBorder(BevelBorder.RAISED,
105                     table.getColor("InternalFrame.borderColor"),
106                     table.getColor("InternalFrame.borderHighlight"),
107                     table.getColor("InternalFrame.borderDarkShadow"),
108                     table.getColor("InternalFrame.borderShadow")),
109                 new WindowsBorders.InternalFrameLineBorder(
110                     table.getColor("InternalFrame.activeBorderColor"),
111                     table.getColor("InternalFrame.inactiveBorderColor"),
112                     table.getInt("InternalFrame.borderWidth")));
113 
114         return internalFrameBorder;
115     }
116 
117     public static class ProgressBarBorder extends AbstractBorder implements UIResource {
118         protected Color shadow;
119         protected Color highlight;
120 
ProgressBarBorder(Color shadow, Color highlight)121         public ProgressBarBorder(Color shadow, Color highlight) {
122             this.highlight = highlight;
123             this.shadow = shadow;
124         }
125 
paintBorder(Component c, Graphics g, int x, int y, int width, int height)126         public void paintBorder(Component c, Graphics g, int x, int y,
127                                 int width, int height) {
128             g.setColor(shadow);
129             g.drawLine(x,y, width-1,y); // draw top
130             g.drawLine(x,y, x,height-1); // draw left
131             g.setColor(highlight);
132             g.drawLine(x,height-1, width-1,height-1); // draw bottom
133             g.drawLine(width-1,y, width-1,height-1); // draw right
134         }
135 
getBorderInsets(Component c, Insets insets)136         public Insets getBorderInsets(Component c, Insets insets) {
137             insets.set(1,1,1,1);
138             return insets;
139         }
140     }
141 
142     /**
143      * A border for the ToolBar. If the ToolBar is floatable then the handle grip is drawn
144      * <p>
145      * @since 1.4
146      */
147     public static class ToolBarBorder extends AbstractBorder implements UIResource, SwingConstants {
148         protected Color shadow;
149         protected Color highlight;
150 
ToolBarBorder(Color shadow, Color highlight)151         public ToolBarBorder(Color shadow, Color highlight) {
152             this.highlight = highlight;
153             this.shadow = shadow;
154         }
155 
paintBorder(Component c, Graphics g, int x, int y, int width, int height)156         public void paintBorder(Component c, Graphics g, int x, int y,
157                                 int width, int height) {
158             if (!(c instanceof JToolBar)) {
159                 return;
160             }
161             g.translate(x, y);
162 
163             XPStyle xp = XPStyle.getXP();
164             if (xp != null) {
165                 Border xpBorder = xp.getBorder(c, Part.TP_TOOLBAR);
166                 if (xpBorder != null) {
167                     xpBorder.paintBorder(c, g, 0, 0, width, height);
168                 }
169             }
170             if (((JToolBar)c).isFloatable()) {
171                 boolean vertical = ((JToolBar)c).getOrientation() == VERTICAL;
172 
173                 if (xp != null) {
174                     Part part = vertical ? Part.RP_GRIPPERVERT : Part.RP_GRIPPER;
175                     Skin skin = xp.getSkin(c, part);
176                     int dx, dy, dw, dh;
177                     if (vertical) {
178                         dx = 0;
179                         dy = 2;
180                         dw = width - 1;
181                         dh = skin.getHeight();
182                     } else {
183                         dw = skin.getWidth();
184                         dh = height - 1;
185                         dx = c.getComponentOrientation().isLeftToRight() ? 2 : (width-dw-2);
186                         dy = 0;
187                     }
188                     skin.paintSkin(g, dx, dy, dw, dh, State.NORMAL);
189 
190                 } else {
191 
192                     if (!vertical) {
193                         if (c.getComponentOrientation().isLeftToRight()) {
194                             g.setColor(shadow);
195                             g.drawLine(4, 3, 4, height - 4);
196                             g.drawLine(4, height - 4, 2, height - 4);
197 
198                             g.setColor(highlight);
199                             g.drawLine(2, 3, 3, 3);
200                             g.drawLine(2, 3, 2, height - 5);
201                         } else {
202                             g.setColor(shadow);
203                             g.drawLine(width - 3, 3, width - 3, height - 4);
204                             g.drawLine(width - 4, height - 4, width - 4, height - 4);
205 
206                             g.setColor(highlight);
207                             g.drawLine(width - 5, 3, width - 4, 3);
208                             g.drawLine(width - 5, 3, width - 5, height - 5);
209                         }
210                     } else { // Vertical
211                         g.setColor(shadow);
212                         g.drawLine(3, 4, width - 4, 4);
213                         g.drawLine(width - 4, 2, width - 4, 4);
214 
215                         g.setColor(highlight);
216                         g.drawLine(3, 2, width - 4, 2);
217                         g.drawLine(3, 2, 3, 3);
218                     }
219                 }
220             }
221 
222             g.translate(-x, -y);
223         }
224 
getBorderInsets(Component c, Insets insets)225         public Insets getBorderInsets(Component c, Insets insets) {
226             insets.set(1,1,1,1);
227             if (!(c instanceof JToolBar)) {
228                 return insets;
229             }
230             if (((JToolBar)c).isFloatable()) {
231                 int gripInset = (XPStyle.getXP() != null) ? 12 : 9;
232                 if (((JToolBar)c).getOrientation() == HORIZONTAL) {
233                     if (c.getComponentOrientation().isLeftToRight()) {
234                         insets.left = gripInset;
235                     } else {
236                         insets.right = gripInset;
237                     }
238                 } else {
239                     insets.top = gripInset;
240                 }
241             }
242             return insets;
243         }
244     }
245 
246     /**
247      * This class is an implementation of a dashed border.
248      * @since 1.4
249      */
250     public static class DashedBorder extends LineBorder implements UIResource {
DashedBorder(Color color)251         public DashedBorder(Color color) {
252             super(color);
253         }
254 
DashedBorder(Color color, int thickness)255         public DashedBorder(Color color, int thickness)  {
256             super(color, thickness);
257         }
258 
paintBorder(Component c, Graphics g, int x, int y, int width, int height)259         public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
260             Color oldColor = g.getColor();
261             int i;
262 
263             g.setColor(lineColor);
264             for(i = 0; i < thickness; i++)  {
265                 BasicGraphicsUtils.drawDashedRect(g, x+i, y+i, width-i-i, height-i-i);
266             }
267             g.setColor(oldColor);
268         }
269     }
270 
271     /**
272      * A dashed border that paints itself in the complementary color
273      * of the component's background color.
274      */
275     static class ComplementDashedBorder extends LineBorder implements UIResource {
276         private Color origColor;
277         private Color paintColor;
278 
ComplementDashedBorder()279         public ComplementDashedBorder() {
280             super(null);
281         }
282 
paintBorder(Component c, Graphics g, int x, int y, int width, int height)283         public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
284             Color color = c.getBackground();
285 
286             if (origColor != color) {
287                 origColor = color;
288                 paintColor = new Color(~origColor.getRGB());
289             }
290 
291             g.setColor(paintColor);
292             BasicGraphicsUtils.drawDashedRect(g, x, y, width, height);
293         }
294     }
295 
296     /**
297      * This class is an implementation of the InternalFrameLine border.
298      * @since 1.4
299      */
300     public static class InternalFrameLineBorder extends LineBorder implements
301             UIResource {
302         protected Color activeColor;
303         protected Color inactiveColor;
304 
InternalFrameLineBorder(Color activeBorderColor, Color inactiveBorderColor, int thickness)305         public InternalFrameLineBorder(Color activeBorderColor,
306                                        Color inactiveBorderColor,
307                                        int thickness) {
308             super(activeBorderColor, thickness);
309             activeColor = activeBorderColor;
310             inactiveColor = inactiveBorderColor;
311         }
312 
paintBorder(Component c, Graphics g, int x, int y, int width, int height)313         public void paintBorder(Component c, Graphics g, int x, int y,
314                 int width, int height) {
315 
316             JInternalFrame jif = null;
317             if (c instanceof JInternalFrame) {
318                 jif = (JInternalFrame)c;
319             } else if (c instanceof JInternalFrame.JDesktopIcon) {
320                 jif = ((JInternalFrame.JDesktopIcon)c).getInternalFrame();
321             } else {
322                 return;
323             }
324 
325             if (jif.isSelected()) {
326                 // Set the line color so the line border gets the correct
327                 // color.
328                 lineColor = activeColor;
329                 super.paintBorder(c, g, x, y, width, height);
330             } else {
331                 lineColor = inactiveColor;
332                 super.paintBorder(c, g, x, y, width, height);
333             }
334         }
335     }
336 }
337