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