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 }