001 /*
002 * $Id: PartialLineBorder.java,v 1.5 2012/02/19 17:35:50 davep Exp $
003 *
004 * This file is part of McIDAS-V
005 *
006 * Copyright 2007-2012
007 * Space Science and Engineering Center (SSEC)
008 * University of Wisconsin - Madison
009 * 1225 W. Dayton Street, Madison, WI 53706, USA
010 * https://www.ssec.wisc.edu/mcidas
011 *
012 * All Rights Reserved
013 *
014 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
015 * some McIDAS-V source code is based on IDV and VisAD source code.
016 *
017 * McIDAS-V is free software; you can redistribute it and/or modify
018 * it under the terms of the GNU Lesser Public License as published by
019 * the Free Software Foundation; either version 3 of the License, or
020 * (at your option) any later version.
021 *
022 * McIDAS-V is distributed in the hope that it will be useful,
023 * but WITHOUT ANY WARRANTY; without even the implied warranty of
024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
025 * GNU Lesser Public License for more details.
026 *
027 * You should have received a copy of the GNU Lesser Public License
028 * along with this program. If not, see http://www.gnu.org/licenses.
029 */
030 package edu.wisc.ssec.mcidasv.ui;
031
032 import java.awt.Color;
033 import java.awt.Component;
034 import java.awt.Graphics;
035 import java.awt.Graphics2D;
036 import java.awt.Insets;
037 import java.awt.RenderingHints;
038
039 import javax.swing.border.LineBorder;
040
041 /**
042 * This is a better version of LineBorder which allows you to show line only at one side or several
043 * sides and supports rounded corner.
044 */
045 public class PartialLineBorder extends LineBorder {
046
047 final static int NORTH = 1;
048 final static int SOUTH = 2;
049 final static int EAST = 4;
050 final static int WEST = 8;
051 final static int HORIZONTAL = NORTH | SOUTH;
052 final static int VERTICAL = EAST | WEST;
053 final static int ALL = VERTICAL | HORIZONTAL;
054
055 private int _sides = ALL;
056 private int _roundedCornerSize = 5;
057
058 public PartialLineBorder(Color color) {
059 super(color);
060 }
061
062 public PartialLineBorder(Color color, int thickness) {
063 super(color, thickness);
064 }
065
066 public PartialLineBorder(Color color, int thickness, boolean roundedCorners) {
067 super(color, thickness, roundedCorners);
068 }
069
070 public PartialLineBorder(Color color, int thickness, boolean roundedCorners, int roundedCornerSize) {
071 super(color, thickness, roundedCorners);
072 _roundedCornerSize = roundedCornerSize;
073 }
074
075 public PartialLineBorder(Color color, int thickness, int side) {
076 super(color, thickness);
077 _sides = side;
078 }
079
080 public int getSides() {
081 return _sides;
082 }
083
084 public void setSides(int sides) {
085 _sides = sides;
086 }
087
088 public int getRoundedCornerSize() {
089 return _roundedCornerSize;
090 }
091
092 public void setRoundedCornerSize(int roundedCornerSize) {
093 _roundedCornerSize = roundedCornerSize;
094 }
095
096 @Override
097 public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
098 Color oldColor = g.getColor();
099 int i;
100
101 g.setColor(lineColor);
102 for (i = 0; i < thickness; i++) {
103 if (_sides == ALL) {
104 if (!roundedCorners)
105 g.drawRect(x + i, y + i, width - i - i - 1, height - i - i - 1);
106 else {
107 Object o = setupShapeAntialiasing(g);
108 g.drawRoundRect(x + i, y + i, width - i - i - 1, height - i - i - 1, _roundedCornerSize, _roundedCornerSize);
109 restoreShapeAntialiasing(g, o);
110 }
111 }
112
113 else {
114 if ((_sides & NORTH) != 0) {
115 g.drawLine(x, y + i, x + width - 1, y + i);
116 }
117 if ((_sides & SOUTH) != 0) {
118 g.drawLine(x, y + height - i - 1, x + width - 1, y + height - i - 1);
119 }
120 if ((_sides & WEST) != 0) {
121 g.drawLine(x + i, y, x + i, y + height - 1);
122 }
123 if ((_sides & EAST) != 0) {
124 g.drawLine(x + width - i - 1, y, x + width - i - 1, y + height - 1);
125 }
126 }
127
128 }
129 g.setColor(oldColor);
130 }
131
132 @Override
133 public Insets getBorderInsets(Component c) {
134 Insets borderInsets = super.getBorderInsets(c);
135 if ((_sides & NORTH) == 0) {
136 borderInsets.top = 0;
137 }
138 if ((_sides & SOUTH) == 0) {
139 borderInsets.bottom = 0;
140 }
141 if ((_sides & WEST) == 0) {
142 borderInsets.left = 0;
143 }
144 if ((_sides & EAST) == 0) {
145 borderInsets.right = 0;
146 }
147 return borderInsets;
148 }
149
150 @Override
151 public Insets getBorderInsets(Component c, Insets insets) {
152 Insets borderInsets = super.getBorderInsets(c, insets);
153 if ((_sides & NORTH) == 0) {
154 borderInsets.top = 0;
155 }
156 if ((_sides & SOUTH) == 0) {
157 borderInsets.bottom = 0;
158 }
159 if ((_sides & WEST) == 0) {
160 borderInsets.left = 0;
161 }
162 if ((_sides & EAST) == 0) {
163 borderInsets.right = 0;
164 }
165 return borderInsets;
166 }
167
168 /**
169 * Setups the graphics to draw shape using anti-alias.
170 *
171 * @param g
172 * @return the old hints. You will need this value as the third parameter in {@link
173 * #restoreShapeAntialiasing(java.awt.Graphics,Object)}.
174 */
175 private static Object setupShapeAntialiasing(Graphics g) {
176 Graphics2D g2d = (Graphics2D) g;
177 Object oldHints = g2d.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
178 g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
179 return oldHints;
180 }
181
182 /**
183 * Restores the old setting for shape anti-alias.
184 *
185 * @param g
186 * @param oldHints the value returned from {@link #setupShapeAntialiasing(java.awt.Graphics)}.
187 */
188 private static void restoreShapeAntialiasing(Graphics g, Object oldHints) {
189 Graphics2D g2d = (Graphics2D) g;
190 g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, oldHints);
191 }
192 }