1 /*
2  * Copyright (c) 1998, 2014, 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 {@literal 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     @SuppressWarnings("serial") // Superclass is not serializable across versions
118     public static class ProgressBarBorder extends AbstractBorder implements UIResource {
119         protected Color shadow;
120         protected Color highlight;
121 
ProgressBarBorder(Color shadow, Color highlight)122         public ProgressBarBorder(Color shadow, Color highlight) {
123             this.highlight = highlight;
124             this.shadow = shadow;
125         }
126 
paintBorder(Component c, Graphics g, int x, int y, int width, int height)127         public void paintBorder(Component c, Graphics g, int x, int y,
128                                 int width, int height) {
129             g.setColor(shadow);
130             g.drawLine(x,y, width-1,y); // draw top
131             g.drawLine(x,y, x,height-1); // draw left
132             g.setColor(highlight);
133             g.drawLine(x,height-1, width-1,height-1); // draw bottom
134             g.drawLine(width-1,y, width-1,height-1); // draw right
135         }
136 
getBorderInsets(Component c, Insets insets)137         public Insets getBorderInsets(Component c, Insets insets) {
138             insets.set(1,1,1,1);
139             return insets;
140         }
141     }
142 
143     /**
144      * A border for the ToolBar. If the ToolBar is floatable then the handle grip is drawn
145      *
146      * @since 1.4
147      */
148     @SuppressWarnings("serial") // Superclass is not serializable across versions
149     public static class ToolBarBorder extends AbstractBorder implements UIResource, SwingConstants {
150         protected Color shadow;
151         protected Color highlight;
152 
ToolBarBorder(Color shadow, Color highlight)153         public ToolBarBorder(Color shadow, Color highlight) {
154             this.highlight = highlight;
155             this.shadow = shadow;
156         }
157 
paintBorder(Component c, Graphics g, int x, int y, int width, int height)158         public void paintBorder(Component c, Graphics g, int x, int y,
159                                 int width, int height) {
160             if (!(c instanceof JToolBar)) {
161                 return;
162             }
163             g.translate(x, y);
164 
165             XPStyle xp = XPStyle.getXP();
166             if (xp != null) {
167                 Border xpBorder = xp.getBorder(c, Part.TP_TOOLBAR);
168                 if (xpBorder != null) {
169                     xpBorder.paintBorder(c, g, 0, 0, width, height);
170                 }
171             }
172             if (((JToolBar)c).isFloatable()) {
173                 boolean vertical = ((JToolBar)c).getOrientation() == VERTICAL;
174 
175                 if (xp != null) {
176                     Part part = vertical ? Part.RP_GRIPPERVERT : Part.RP_GRIPPER;
177                     Skin skin = xp.getSkin(c, part);
178                     int dx, dy, dw, dh;
179                     if (vertical) {
180                         dx = 0;
181                         dy = 2;
182                         dw = width - 1;
183                         dh = skin.getHeight();
184                     } else {
185                         dw = skin.getWidth();
186                         dh = height - 1;
187                         dx = c.getComponentOrientation().isLeftToRight() ? 2 : (width-dw-2);
188                         dy = 0;
189                     }
190                     skin.paintSkin(g, dx, dy, dw, dh, State.NORMAL);
191 
192                 } else {
193 
194                     if (!vertical) {
195                         if (c.getComponentOrientation().isLeftToRight()) {
196                             g.setColor(shadow);
197                             g.drawLine(4, 3, 4, height - 4);
198                             g.drawLine(4, height - 4, 2, height - 4);
199 
200                             g.setColor(highlight);
201                             g.drawLine(2, 3, 3, 3);
202                             g.drawLine(2, 3, 2, height - 5);
203                         } else {
204                             g.setColor(shadow);
205                             g.drawLine(width - 3, 3, width - 3, height - 4);
206                             g.drawLine(width - 4, height - 4, width - 4, height - 4);
207 
208                             g.setColor(highlight);
209                             g.drawLine(width - 5, 3, width - 4, 3);
210                             g.drawLine(width - 5, 3, width - 5, height - 5);
211                         }
212                     } else { // Vertical
213                         g.setColor(shadow);
214                         g.drawLine(3, 4, width - 4, 4);
215                         g.drawLine(width - 4, 2, width - 4, 4);
216 
217                         g.setColor(highlight);
218                         g.drawLine(3, 2, width - 4, 2);
219                         g.drawLine(3, 2, 3, 3);
220                     }
221                 }
222             }
223 
224             g.translate(-x, -y);
225         }
226 
getBorderInsets(Component c, Insets insets)227         public Insets getBorderInsets(Component c, Insets insets) {
228             insets.set(1,1,1,1);
229             if (!(c instanceof JToolBar)) {
230                 return insets;
231             }
232             if (((JToolBar)c).isFloatable()) {
233                 int gripInset = (XPStyle.getXP() != null) ? 12 : 9;
234                 if (((JToolBar)c).getOrientation() == HORIZONTAL) {
235                     if (c.getComponentOrientation().isLeftToRight()) {
236                         insets.left = gripInset;
237                     } else {
238                         insets.right = gripInset;
239                     }
240                 } else {
241                     insets.top = gripInset;
242                 }
243             }
244             return insets;
245         }
246     }
247 
248     /**
249      * This class is an implementation of a dashed border.
250      * @since 1.4
251      */
252     @SuppressWarnings("serial") // Superclass is not serializable across versions
253     public static class DashedBorder extends LineBorder implements UIResource {
DashedBorder(Color color)254         public DashedBorder(Color color) {
255             super(color);
256         }
257 
DashedBorder(Color color, int thickness)258         public DashedBorder(Color color, int thickness)  {
259             super(color, thickness);
260         }
261 
paintBorder(Component c, Graphics g, int x, int y, int width, int height)262         public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
263             Color oldColor = g.getColor();
264             int i;
265 
266             g.setColor(lineColor);
267             for(i = 0; i < thickness; i++)  {
268                 BasicGraphicsUtils.drawDashedRect(g, x+i, y+i, width-i-i, height-i-i);
269             }
270             g.setColor(oldColor);
271         }
272     }
273 
274     /**
275      * A dashed border that paints itself in the complementary color
276      * of the component's background color.
277      */
278     @SuppressWarnings("serial") // Superclass is not serializable across versions
279     static class ComplementDashedBorder extends LineBorder implements UIResource {
280         private Color origColor;
281         private Color paintColor;
282 
ComplementDashedBorder()283         public ComplementDashedBorder() {
284             super(null);
285         }
286 
paintBorder(Component c, Graphics g, int x, int y, int width, int height)287         public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
288             Color color = c.getBackground();
289 
290             if (origColor != color) {
291                 origColor = color;
292                 paintColor = new Color(~origColor.getRGB());
293             }
294 
295             g.setColor(paintColor);
296             BasicGraphicsUtils.drawDashedRect(g, x, y, width, height);
297         }
298     }
299 
300     /**
301      * This class is an implementation of the InternalFrameLine border.
302      * @since 1.4
303      */
304     @SuppressWarnings("serial") // Superclass is not serializable across versions
305     public static class InternalFrameLineBorder extends LineBorder implements
306             UIResource {
307         protected Color activeColor;
308         protected Color inactiveColor;
309 
InternalFrameLineBorder(Color activeBorderColor, Color inactiveBorderColor, int thickness)310         public InternalFrameLineBorder(Color activeBorderColor,
311                                        Color inactiveBorderColor,
312                                        int thickness) {
313             super(activeBorderColor, thickness);
314             activeColor = activeBorderColor;
315             inactiveColor = inactiveBorderColor;
316         }
317 
paintBorder(Component c, Graphics g, int x, int y, int width, int height)318         public void paintBorder(Component c, Graphics g, int x, int y,
319                 int width, int height) {
320 
321             JInternalFrame jif = null;
322             if (c instanceof JInternalFrame) {
323                 jif = (JInternalFrame)c;
324             } else if (c instanceof JInternalFrame.JDesktopIcon) {
325                 jif = ((JInternalFrame.JDesktopIcon)c).getInternalFrame();
326             } else {
327                 return;
328             }
329 
330             if (jif.isSelected()) {
331                 // Set the line color so the line border gets the correct
332                 // color.
333                 lineColor = activeColor;
334                 super.paintBorder(c, g, x, y, width, height);
335             } else {
336                 lineColor = inactiveColor;
337                 super.paintBorder(c, g, x, y, width, height);
338             }
339         }
340     }
341 }
342