1/*
2 * Copyright (c) 1997, 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
26package javax.swing.plaf.basic;
27
28import javax.swing.*;
29import javax.swing.border.*;
30import javax.swing.plaf.*;
31import javax.swing.text.JTextComponent;
32
33import java.awt.Component;
34import java.awt.Insets;
35import java.awt.Dimension;
36import java.awt.Rectangle;
37import java.awt.Color;
38import java.awt.Graphics;
39
40import sun.swing.SwingUtilities2;
41
42/**
43 * Factory object that can vend Borders appropriate for the basic L & F.
44 * @author Georges Saab
45 * @author Amy Fowler
46 */
47
48public class BasicBorders {
49
50    /**
51     * Returns a border instance for a {@code JButton}.
52     *
53     * @return a border instance for a {@code JButton}
54     */
55    public static Border getButtonBorder() {
56        UIDefaults table = UIManager.getLookAndFeelDefaults();
57        Border buttonBorder = new BorderUIResource.CompoundBorderUIResource(
58                           new BasicBorders.ButtonBorder(
59                                           table.getColor("Button.shadow"),
60                                           table.getColor("Button.darkShadow"),
61                                           table.getColor("Button.light"),
62                                           table.getColor("Button.highlight")),
63                                     new MarginBorder());
64        return buttonBorder;
65    }
66
67    /**
68     * Returns a border instance for a {@code JRadioButton}.
69     *
70     * @return a border instance for a {@code JRadioButton}
71     */
72    public static Border getRadioButtonBorder() {
73        UIDefaults table = UIManager.getLookAndFeelDefaults();
74        Border radioButtonBorder = new BorderUIResource.CompoundBorderUIResource(
75                           new BasicBorders.RadioButtonBorder(
76                                           table.getColor("RadioButton.shadow"),
77                                           table.getColor("RadioButton.darkShadow"),
78                                           table.getColor("RadioButton.light"),
79                                           table.getColor("RadioButton.highlight")),
80                                     new MarginBorder());
81        return radioButtonBorder;
82    }
83
84    /**
85     * Returns a border instance for a {@code JToggleButton}.
86     *
87     * @return a border instance for a {@code JToggleButton}
88     */
89    public static Border getToggleButtonBorder() {
90        UIDefaults table = UIManager.getLookAndFeelDefaults();
91        Border toggleButtonBorder = new BorderUIResource.CompoundBorderUIResource(
92                                     new BasicBorders.ToggleButtonBorder(
93                                           table.getColor("ToggleButton.shadow"),
94                                           table.getColor("ToggleButton.darkShadow"),
95                                           table.getColor("ToggleButton.light"),
96                                           table.getColor("ToggleButton.highlight")),
97                                     new MarginBorder());
98        return toggleButtonBorder;
99    }
100
101    /**
102     * Returns a border instance for a {@code JMenuBar}.
103     *
104     * @return a border instance for a {@code JMenuBar}
105     */
106    public static Border getMenuBarBorder() {
107        UIDefaults table = UIManager.getLookAndFeelDefaults();
108        Border menuBarBorder = new BasicBorders.MenuBarBorder(
109                                        table.getColor("MenuBar.shadow"),
110                                        table.getColor("MenuBar.highlight")
111                                   );
112        return menuBarBorder;
113    }
114
115    /**
116     * Returns a border instance for a {@code JSplitPane}.
117     *
118     * @return a border instance for a {@code JSplitPane}
119     */
120    public static Border getSplitPaneBorder() {
121        UIDefaults table = UIManager.getLookAndFeelDefaults();
122        Border splitPaneBorder = new BasicBorders.SplitPaneBorder(
123                                     table.getColor("SplitPane.highlight"),
124                                     table.getColor("SplitPane.darkShadow"));
125        return splitPaneBorder;
126    }
127
128    /**
129     * Returns a border instance for a {@code JSplitPane} divider.
130     *
131     * @return a border instance for a {@code JSplitPane} divider
132     * @since 1.3
133     */
134    public static Border getSplitPaneDividerBorder() {
135        UIDefaults table = UIManager.getLookAndFeelDefaults();
136        Border splitPaneBorder = new BasicBorders.SplitPaneDividerBorder(
137                                     table.getColor("SplitPane.highlight"),
138                                     table.getColor("SplitPane.darkShadow"));
139        return splitPaneBorder;
140    }
141
142    /**
143     * Returns a border instance for a {@code JTextField}.
144     *
145     * @return a border instance for a {@code JTextField}
146     */
147    public static Border getTextFieldBorder() {
148        UIDefaults table = UIManager.getLookAndFeelDefaults();
149        Border textFieldBorder = new BasicBorders.FieldBorder(
150                                           table.getColor("TextField.shadow"),
151                                           table.getColor("TextField.darkShadow"),
152                                           table.getColor("TextField.light"),
153                                           table.getColor("TextField.highlight"));
154        return textFieldBorder;
155    }
156
157    /**
158     * Returns a border instance for a {@code JProgressBar}.
159     *
160     * @return a border instance for a {@code JProgressBar}
161     */
162    public static Border getProgressBarBorder() {
163        UIDefaults table = UIManager.getLookAndFeelDefaults();
164        Border progressBarBorder = new BorderUIResource.LineBorderUIResource(Color.green, 2);
165        return progressBarBorder;
166    }
167
168    /**
169     * Returns a border instance for a {@code JInternalFrame}.
170     *
171     * @return a border instance for a {@code JInternalFrame}
172     */
173    public static Border getInternalFrameBorder() {
174        UIDefaults table = UIManager.getLookAndFeelDefaults();
175        Border internalFrameBorder = new BorderUIResource.CompoundBorderUIResource(
176                                new BevelBorder(BevelBorder.RAISED,
177                                        table.getColor("InternalFrame.borderLight"),
178                                        table.getColor("InternalFrame.borderHighlight"),
179                                        table.getColor("InternalFrame.borderDarkShadow"),
180                                        table.getColor("InternalFrame.borderShadow")),
181                                BorderFactory.createLineBorder(
182                                        table.getColor("InternalFrame.borderColor"), 1));
183
184        return internalFrameBorder;
185    }
186
187    /**
188     * Special thin border for rollover toolbar buttons.
189     * @since 1.4
190     */
191    @SuppressWarnings("serial") // Superclass is not serializable across versions
192    public static class RolloverButtonBorder extends ButtonBorder {
193
194        /**
195         * Constructs a new instance of a {@code RolloverButtonBorder}.
196         *
197         * @param shadow a color of shadow
198         * @param darkShadow a color of dark shadow
199         * @param highlight a color of highlight
200         * @param lightHighlight a color of light highlight
201         */
202        public RolloverButtonBorder(Color shadow, Color darkShadow,
203                                  Color highlight, Color lightHighlight) {
204            super(shadow, darkShadow, highlight, lightHighlight);
205        }
206
207        public void paintBorder( Component c, Graphics g, int x, int y, int w, int h ) {
208            AbstractButton b = (AbstractButton) c;
209            ButtonModel model = b.getModel();
210
211            Color shade = shadow;
212            Component p = b.getParent();
213            if (p != null && p.getBackground().equals(shadow)) {
214                shade = darkShadow;
215            }
216
217            if ((model.isRollover() && !(model.isPressed() && !model.isArmed())) ||
218                model.isSelected()) {
219
220                Color oldColor = g.getColor();
221                g.translate(x, y);
222
223                if (model.isPressed() && model.isArmed() || model.isSelected()) {
224                    // Draw the pressd button
225                    g.setColor(shade);
226                    g.drawRect(0, 0, w-1, h-1);
227                    g.setColor(lightHighlight);
228                    g.drawLine(w-1, 0, w-1, h-1);
229                    g.drawLine(0, h-1, w-1, h-1);
230                } else {
231                    // Draw a rollover button
232                    g.setColor(lightHighlight);
233                    g.drawRect(0, 0, w-1, h-1);
234                    g.setColor(shade);
235                    g.drawLine(w-1, 0, w-1, h-1);
236                    g.drawLine(0, h-1, w-1, h-1);
237                }
238                g.translate(-x, -y);
239                g.setColor(oldColor);
240            }
241        }
242    }
243
244
245    /**
246     * A border which is like a Margin border but it will only honor the margin
247     * if the margin has been explicitly set by the developer.
248     *
249     * Note: This is identical to the package private class
250     * MetalBorders.RolloverMarginBorder and should probably be consolidated.
251     */
252    @SuppressWarnings("serial") // Superclass is not serializable across versions
253    static class RolloverMarginBorder extends EmptyBorder {
254
255        public RolloverMarginBorder() {
256            super(3,3,3,3); // hardcoded margin for JLF requirements.
257        }
258
259        public Insets getBorderInsets(Component c, Insets insets) {
260            Insets margin = null;
261
262            if (c instanceof AbstractButton) {
263                margin = ((AbstractButton)c).getMargin();
264            }
265            if (margin == null || margin instanceof UIResource) {
266                // default margin so replace
267                insets.left = left;
268                insets.top = top;
269                insets.right = right;
270                insets.bottom = bottom;
271            } else {
272                // Margin which has been explicitly set by the user.
273                insets.left = margin.left;
274                insets.top = margin.top;
275                insets.right = margin.right;
276                insets.bottom = margin.bottom;
277            }
278            return insets;
279        }
280    }
281
282    /**
283     * Draws a border around a button.
284     */
285    @SuppressWarnings("serial") // Superclass is not serializable across versions
286   public static class ButtonBorder extends AbstractBorder implements UIResource {
287        /**
288         * The color of shadow.
289         */
290        protected Color shadow;
291        /**
292         * The color of dark shadow.
293         */
294        protected Color darkShadow;
295        /**
296         * The color of highlight.
297         */
298        protected Color highlight;
299        /**
300         * The color of light highlight.
301         */
302        protected Color lightHighlight;
303
304        /**
305         * Constructs a new instance of a {@code ButtonBorder}.
306         *
307         * @param shadow a color of shadow
308         * @param darkShadow a color of dark shadow
309         * @param highlight a color of highlight
310         * @param lightHighlight a color of light highlight
311         */
312        public ButtonBorder(Color shadow, Color darkShadow,
313                            Color highlight, Color lightHighlight) {
314            this.shadow = shadow;
315            this.darkShadow = darkShadow;
316            this.highlight = highlight;
317            this.lightHighlight = lightHighlight;
318        }
319
320        public void paintBorder(Component c, Graphics g, int x, int y,
321                            int width, int height) {
322            boolean isPressed = false;
323            boolean isDefault = false;
324
325            if (c instanceof AbstractButton) {
326                AbstractButton b = (AbstractButton)c;
327                ButtonModel model = b.getModel();
328
329                isPressed = model.isPressed() && model.isArmed();
330
331                if (c instanceof JButton) {
332                    isDefault = ((JButton)c).isDefaultButton();
333                }
334            }
335            BasicGraphicsUtils.drawBezel(g, x, y, width, height,
336                                   isPressed, isDefault, shadow,
337                                   darkShadow, highlight, lightHighlight);
338        }
339
340        public Insets getBorderInsets(Component c, Insets insets)       {
341            // leave room for default visual
342            insets.set(2, 3, 3, 3);
343            return insets;
344        }
345
346    }
347
348    /**
349     * Draws the border around a toggle button.
350     */
351    @SuppressWarnings("serial") // Superclass is not serializable across versions
352    public static class ToggleButtonBorder extends ButtonBorder {
353
354        /**
355         * Constructs a new instance of a {@code ToggleButtonBorder}.
356         *
357         * @param shadow a color of shadow
358         * @param darkShadow a color of dark shadow
359         * @param highlight a color of highlight
360         * @param lightHighlight a color of light highlight
361         */
362        public ToggleButtonBorder(Color shadow, Color darkShadow,
363                                  Color highlight, Color lightHighlight) {
364            super(shadow, darkShadow, highlight, lightHighlight);
365        }
366
367        public void paintBorder(Component c, Graphics g, int x, int y,
368                                int width, int height) {
369                BasicGraphicsUtils.drawBezel(g, x, y, width, height,
370                                             false, false,
371                                             shadow, darkShadow,
372                                             highlight, lightHighlight);
373        }
374
375        public Insets getBorderInsets(Component c, Insets insets)       {
376            insets.set(2, 2, 2, 2);
377            return insets;
378        }
379    }
380
381    /**
382     * Draws the border around a radio button.
383     */
384    @SuppressWarnings("serial") // Superclass is not serializable across versions
385    public static class RadioButtonBorder extends ButtonBorder {
386
387        /**
388         * Constructs a new instance of a {@code RadioButtonBorder}.
389         *
390         * @param shadow a color of shadow
391         * @param darkShadow a color of dark shadow
392         * @param highlight a color of highlight
393         * @param lightHighlight a color of light highlight
394         */
395        public RadioButtonBorder(Color shadow, Color darkShadow,
396                                 Color highlight, Color lightHighlight) {
397            super(shadow, darkShadow, highlight, lightHighlight);
398        }
399
400
401        public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
402
403            if (c instanceof AbstractButton) {
404                AbstractButton b = (AbstractButton)c;
405                ButtonModel model = b.getModel();
406
407                if (model.isArmed() && model.isPressed() || model.isSelected()) {
408                    BasicGraphicsUtils.drawLoweredBezel(g, x, y, width, height,
409                                                        shadow, darkShadow,
410                                                        highlight, lightHighlight);
411                } else {
412                    BasicGraphicsUtils.drawBezel(g, x, y, width, height,
413                                               false, b.isFocusPainted() && b.hasFocus(),
414                                                 shadow, darkShadow,
415                                                 highlight, lightHighlight);
416                }
417            } else {
418                BasicGraphicsUtils.drawBezel(g, x, y, width, height, false, false,
419                                             shadow, darkShadow, highlight, lightHighlight);
420            }
421        }
422
423        public Insets getBorderInsets(Component c, Insets insets)       {
424            insets.set(2, 2, 2, 2);
425            return insets;
426        }
427    }
428
429    /**
430     * Draws the border around a menu bar.
431     */
432    @SuppressWarnings("serial") // Superclass is not serializable across versions
433    public static class MenuBarBorder extends AbstractBorder implements UIResource {
434        /**
435         * The color of shadow.
436         */
437        private Color shadow;
438        /**
439         * The color of highlight.
440         */
441        private Color highlight;
442
443        /**
444         * Constructs a new instance of a {@code MenuBarBorder}.
445         *
446         * @param shadow a color of shadow
447         * @param highlight a color of highlight
448         */
449        public MenuBarBorder(Color shadow, Color highlight) {
450            this.shadow = shadow;
451            this.highlight = highlight;
452        }
453
454        public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
455            Color oldColor = g.getColor();
456            g.translate(x, y);
457            g.setColor(shadow);
458            SwingUtilities2.drawHLine(g, 0, width - 1, height - 2);
459            g.setColor(highlight);
460            SwingUtilities2.drawHLine(g, 0, width - 1, height - 1);
461            g.translate(-x, -y);
462            g.setColor(oldColor);
463        }
464
465        public Insets getBorderInsets(Component c, Insets insets)       {
466            insets.set(0, 0, 2, 0);
467            return insets;
468        }
469    }
470
471    /**
472     * Draws the border around components which support margins.
473     */
474    @SuppressWarnings("serial") // Superclass is not serializable across versions
475    public static class MarginBorder extends AbstractBorder implements UIResource {
476        public Insets getBorderInsets(Component c, Insets insets)       {
477            Insets margin = null;
478            //
479            // Ideally we'd have an interface defined for classes which
480            // support margins (to avoid this hackery), but we've
481            // decided against it for simplicity
482            //
483           if (c instanceof AbstractButton) {
484               AbstractButton b = (AbstractButton)c;
485               margin = b.getMargin();
486           } else if (c instanceof JToolBar) {
487               JToolBar t = (JToolBar)c;
488               margin = t.getMargin();
489           } else if (c instanceof JTextComponent) {
490               JTextComponent t = (JTextComponent)c;
491               margin = t.getMargin();
492           }
493           insets.top = margin != null? margin.top : 0;
494           insets.left = margin != null? margin.left : 0;
495           insets.bottom = margin != null? margin.bottom : 0;
496           insets.right = margin != null? margin.right : 0;
497
498           return insets;
499        }
500    }
501
502    /**
503     * Draws the border around a field.
504     */
505    @SuppressWarnings("serial") // Superclass is not serializable across versions
506    public static class FieldBorder extends AbstractBorder implements UIResource {
507        /**
508         * The color of shadow.
509         */
510        protected Color shadow;
511        /**
512         * The color of dark shadow.
513         */
514        protected Color darkShadow;
515        /**
516         * The color of highlight.
517         */
518        protected Color highlight;
519        /**
520         * The color of light highlight.
521         */
522        protected Color lightHighlight;
523
524        /**
525         * Constructs a new instance of a {@code FieldBorder}.
526         *
527         * @param shadow a color of shadow
528         * @param darkShadow a color of dark shadow
529         * @param highlight a color of highlight
530         * @param lightHighlight a color of light highlight
531         */
532        public FieldBorder(Color shadow, Color darkShadow,
533                           Color highlight, Color lightHighlight) {
534            this.shadow = shadow;
535            this.highlight = highlight;
536            this.darkShadow = darkShadow;
537            this.lightHighlight = lightHighlight;
538        }
539
540        public void paintBorder(Component c, Graphics g, int x, int y,
541                            int width, int height) {
542            BasicGraphicsUtils.drawEtchedRect(g, x, y, width, height,
543                                              shadow, darkShadow,
544                                              highlight, lightHighlight);
545        }
546
547        public Insets getBorderInsets(Component c, Insets insets) {
548            Insets margin = null;
549            if (c instanceof JTextComponent) {
550                margin = ((JTextComponent)c).getMargin();
551            }
552            insets.top = margin != null? 2+margin.top : 2;
553            insets.left = margin != null? 2+margin.left : 2;
554            insets.bottom = margin != null? 2+margin.bottom : 2;
555            insets.right = margin != null? 2+margin.right : 2;
556
557            return insets;
558        }
559    }
560
561
562    /**
563     * Draws the border around the divider in a splitpane
564     * (when BasicSplitPaneUI is used). To get the appropriate effect, this
565     * needs to be used with a SplitPaneBorder.
566     */
567    static class SplitPaneDividerBorder implements Border, UIResource {
568        Color highlight;
569        Color shadow;
570
571        SplitPaneDividerBorder(Color highlight, Color shadow) {
572            this.highlight = highlight;
573            this.shadow = shadow;
574        }
575
576        public void paintBorder(Component c, Graphics g, int x, int y,
577                                int width, int height) {
578            if (!(c instanceof BasicSplitPaneDivider)) {
579                return;
580            }
581            Component          child;
582            Rectangle          cBounds;
583            JSplitPane         splitPane = ((BasicSplitPaneDivider)c).
584                                         getBasicSplitPaneUI().getSplitPane();
585            Dimension          size = c.getSize();
586
587            child = splitPane.getLeftComponent();
588            // This is needed for the space between the divider and end of
589            // splitpane.
590            g.setColor(c.getBackground());
591            g.drawRect(x, y, width - 1, height - 1);
592            if(splitPane.getOrientation() == JSplitPane.HORIZONTAL_SPLIT) {
593                if(child != null) {
594                    g.setColor(highlight);
595                    g.drawLine(0, 0, 0, size.height);
596                }
597                child = splitPane.getRightComponent();
598                if(child != null) {
599                    g.setColor(shadow);
600                    g.drawLine(size.width - 1, 0, size.width - 1, size.height);
601                }
602            } else {
603                if(child != null) {
604                    g.setColor(highlight);
605                    g.drawLine(0, 0, size.width, 0);
606                }
607                child = splitPane.getRightComponent();
608                if(child != null) {
609                    g.setColor(shadow);
610                    g.drawLine(0, size.height - 1, size.width,
611                               size.height - 1);
612                }
613            }
614        }
615        public Insets getBorderInsets(Component c) {
616            Insets insets = new Insets(0,0,0,0);
617            if (c instanceof BasicSplitPaneDivider) {
618                BasicSplitPaneUI bspui = ((BasicSplitPaneDivider)c).
619                                         getBasicSplitPaneUI();
620
621                if (bspui != null) {
622                    JSplitPane splitPane = bspui.getSplitPane();
623
624                    if (splitPane != null) {
625                        if (splitPane.getOrientation() ==
626                            JSplitPane.HORIZONTAL_SPLIT) {
627                            insets.top = insets.bottom = 0;
628                            insets.left = insets.right = 1;
629                            return insets;
630                        }
631                        // VERTICAL_SPLIT
632                        insets.top = insets.bottom = 1;
633                        insets.left = insets.right = 0;
634                        return insets;
635                    }
636                }
637            }
638            insets.top = insets.bottom = insets.left = insets.right = 1;
639            return insets;
640        }
641        public boolean isBorderOpaque() { return true; }
642    }
643
644
645    /**
646     * Draws the border around the splitpane. To work correctly you should
647     * also install a border on the divider (property SplitPaneDivider.border).
648     */
649    public static class SplitPaneBorder implements Border, UIResource {
650        /**
651         * The color of highlight
652         */
653        protected Color highlight;
654        /**
655         * The color of shadow
656         */
657        protected Color shadow;
658
659        /**
660         * Constructs a new instance of a {@code SplitPaneBorder}.
661         *
662         * @param highlight a color of highlight
663         * @param shadow a color of shadow
664         */
665        public SplitPaneBorder(Color highlight, Color shadow) {
666            this.highlight = highlight;
667            this.shadow = shadow;
668        }
669
670        public void paintBorder(Component c, Graphics g, int x, int y,
671                                int width, int height) {
672            if (!(c instanceof JSplitPane)) {
673                return;
674            }
675            // The only tricky part with this border is that the divider is
676            // not positioned at the top (for horizontal) or left (for vert),
677            // so this border draws to where the divider is:
678            // -----------------
679            // |xxxxxxx xxxxxxx|
680            // |x     ---     x|
681            // |x     | |     x|
682            // |x     |D|     x|
683            // |x     | |     x|
684            // |x     ---     x|
685            // |xxxxxxx xxxxxxx|
686            // -----------------
687            // The above shows (rather excessively) what this looks like for
688            // a horizontal orientation. This border then draws the x's, with
689            // the SplitPaneDividerBorder drawing its own border.
690
691            Component          child;
692            Rectangle          cBounds;
693
694            JSplitPane splitPane = (JSplitPane)c;
695
696            child = splitPane.getLeftComponent();
697            // This is needed for the space between the divider and end of
698            // splitpane.
699            g.setColor(c.getBackground());
700            g.drawRect(x, y, width - 1, height - 1);
701            if(splitPane.getOrientation() == JSplitPane.HORIZONTAL_SPLIT) {
702                if(child != null) {
703                    cBounds = child.getBounds();
704                    g.setColor(shadow);
705                    g.drawLine(0, 0, cBounds.width + 1, 0);
706                    g.drawLine(0, 1, 0, cBounds.height + 1);
707
708                    g.setColor(highlight);
709                    g.drawLine(0, cBounds.height + 1, cBounds.width + 1,
710                               cBounds.height + 1);
711                }
712                child = splitPane.getRightComponent();
713                if(child != null) {
714                    cBounds = child.getBounds();
715
716                    int             maxX = cBounds.x + cBounds.width;
717                    int             maxY = cBounds.y + cBounds.height;
718
719                    g.setColor(shadow);
720                    g.drawLine(cBounds.x - 1, 0, maxX, 0);
721                    g.setColor(highlight);
722                    g.drawLine(cBounds.x - 1, maxY, maxX, maxY);
723                    g.drawLine(maxX, 0, maxX, maxY + 1);
724                }
725            } else {
726                if(child != null) {
727                    cBounds = child.getBounds();
728                    g.setColor(shadow);
729                    g.drawLine(0, 0, cBounds.width + 1, 0);
730                    g.drawLine(0, 1, 0, cBounds.height);
731                    g.setColor(highlight);
732                    g.drawLine(1 + cBounds.width, 0, 1 + cBounds.width,
733                               cBounds.height + 1);
734                    g.drawLine(0, cBounds.height + 1, 0, cBounds.height + 1);
735                }
736                child = splitPane.getRightComponent();
737                if(child != null) {
738                    cBounds = child.getBounds();
739
740                    int             maxX = cBounds.x + cBounds.width;
741                    int             maxY = cBounds.y + cBounds.height;
742
743                    g.setColor(shadow);
744                    g.drawLine(0, cBounds.y - 1, 0, maxY);
745                    g.drawLine(maxX, cBounds.y - 1, maxX, cBounds.y - 1);
746                    g.setColor(highlight);
747                    g.drawLine(0, maxY, cBounds.width + 1, maxY);
748                    g.drawLine(maxX, cBounds.y, maxX, maxY);
749                }
750            }
751        }
752        public Insets getBorderInsets(Component c) {
753            return new Insets(1, 1, 1, 1);
754        }
755        public boolean isBorderOpaque() { return true; }
756    }
757
758}
759