TabbedPane标签美化式样自定义
JTabbedPane标签美化式样自定义
通过继承BasicTabbedPaneUI类重写JTabbedPane标签式样,实现渐变的标签效果。
效果图:
相关代码:
1 public class TabbedPaneUI extends BasicTabbedPaneUI { 2 3 private Color selectColor; 4 private Color deSelectColor; 5 private int inclTab = 3; 6 private int anchoFocoV = inclTab; 7 private int anchoFocoH = 1; 8 private int anchoCarpetas = 18; 9 private Polygon shape; 10 private Color bgColor; 11 private Color frontColor; 12 13 private ColorSet selectedColorSet; 14 private ColorSet defaultColorSet; 15 private ColorSet hoverColorSet; 16 17 18 public TabbedPaneUI(String bgColorHex, String frontColorHex){ 19 setColor(bgColorHex,frontColorHex); 20 21 selectedColorSet = new ColorSet(); 22 selectedColorSet.topGradColor1 = Color.decode("#E0EEEE");//选中的最上层 23 selectedColorSet.topGradColor2 = Color.decode("#FFFFFF");//选中的第二层 24 selectedColorSet.bottomGradColor1 = Color.decode("#FFFFFF");//选中的第三层 25 selectedColorSet.bottomGradColor2 = Color.decode("#FFFFFF");//选中的最下层 26 defaultColorSet = new ColorSet(); 27 defaultColorSet.topGradColor1 = Color.decode("#FFFFFF");//未选的最上层 28 defaultColorSet.topGradColor2 = Color.decode("#DEEBFE"); 29 defaultColorSet.bottomGradColor1 = Color.decode("#D6E5F5"); 30 defaultColorSet.bottomGradColor2 = Color.decode("#D6E5F5"); 31 hoverColorSet = new ColorSet(); 32 hoverColorSet.topGradColor1 = Color.decode("#FFFFFF");//鼠标悬停最上层 33 hoverColorSet.topGradColor2 = Color.decode("#FFFFFF"); 34 hoverColorSet.bottomGradColor1 = Color.decode("#FFFFFF"); 35 hoverColorSet.bottomGradColor2 = Color.decode("#FFFFFF"); 36 37 } 38 // 39 // public static ComponentUI createUI(JComponent c) { 40 // return new TabbedPaneUI(); 41 // } 42 43 @Override 44 protected void installDefaults() { 45 super.installDefaults(); 46 RollOverListener l = new RollOverListener(); 47 tabPane.addMouseListener(l); 48 tabPane.addMouseMotionListener(l); 49 selectColor = new Color(250, 192, 192); 50 deSelectColor = new Color(197, 193, 168); 51 tabAreaInsets.right = anchoCarpetas; 52 } 53 54 public void setColor(String bgColorHex, String frontColorHex){ 55 bgColor = Color.decode(bgColorHex); 56 frontColor = Color.decode(frontColorHex); 57 } 58 59 @Override 60 protected void paintContentBorderTopEdge(Graphics g, int tabPlacement, 61 int selectedIndex, int x, int y, int w, int h) { 62 super.paintContentBorderTopEdge(g, tabPlacement, -1, x, y, w, h); 63 } 64 65 @Override 66 protected void paintTabArea(Graphics g, int tabPlacement, int selectedIndex) { 67 if (runCount > 1) { 68 int lines[] = new int[runCount]; 69 for (int i = 0; i < runCount; i++) { 70 lines[i] = rects[tabRuns[i]].y 71 + (tabPlacement == TOP ? maxTabHeight : 0); 72 } 73 Arrays.sort(lines); 74 if (tabPlacement == TOP) { 75 int fila = runCount; 76 for (int i = 0; i < lines.length - 1; i++, fila--) { 77 Polygon carp = new Polygon(); 78 carp.addPoint(0, lines[i]); 79 carp.addPoint(tabPane.getWidth() - 2 * fila - 2, lines[i]); 80 carp.addPoint(tabPane.getWidth() - 2 * fila, lines[i] + 3); 81 if (i < lines.length - 2) { 82 carp.addPoint(tabPane.getWidth() - 2 * fila, 83 lines[i + 1]); 84 carp.addPoint(0, lines[i + 1]); 85 } else { 86 carp.addPoint(tabPane.getWidth() - 2 * fila, lines[i] 87 + rects[selectedIndex].height); 88 carp.addPoint(0, lines[i] + rects[selectedIndex].height); 89 } 90 carp.addPoint(0, lines[i]); 91 g.setColor(hazAlfa(fila)); 92 g.fillPolygon(carp); 93 g.setColor(darkShadow.darker()); 94 g.drawPolygon(carp); 95 } 96 } else { 97 int fila = 0; 98 for (int i = 0; i < lines.length - 1; i++, fila++) { 99 Polygon carp = new Polygon(); 100 carp.addPoint(0, lines[i]); 101 carp.addPoint(tabPane.getWidth() - 2 * fila - 1, lines[i]); 102 carp.addPoint(tabPane.getWidth() - 2 * fila - 1, 103 lines[i + 1] - 3); 104 carp.addPoint(tabPane.getWidth() - 2 * fila - 3, 105 lines[i + 1]); 106 carp.addPoint(0, lines[i + 1]); 107 carp.addPoint(0, lines[i]); 108 g.setColor(hazAlfa(fila + 2)); 109 g.fillPolygon(carp); 110 g.setColor(darkShadow.darker()); 111 g.drawPolygon(carp); 112 } 113 } 114 } 115 super.paintTabArea(g, tabPlacement, selectedIndex); 116 } 117 118 @Override 119 protected void paintTabBackground(Graphics g, int tabPlacement, 120 int tabIndex, int x, int y, int w, int h, boolean isSelected) { 121 Graphics2D g2D = (Graphics2D) g; 122 ColorSet colorSet; 123 124 Rectangle rect = rects[tabIndex]; 125 if (isSelected) { 126 colorSet = selectedColorSet; 127 } else if (getRolloverTab() == tabIndex) { 128 colorSet = hoverColorSet; 129 } else { 130 colorSet = defaultColorSet; 131 } 132 g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 133 RenderingHints.VALUE_ANTIALIAS_ON); 134 int width = rect.width; 135 int xpos = rect.x; 136 int yPos = rect.y; 137 if (tabIndex > -1) { 138 width--; 139 xpos++; 140 yPos += 2; 141 } 142 143 g2D.setPaint(new GradientPaint(xpos, 0, colorSet.topGradColor1, xpos, 144 h / 2, colorSet.topGradColor2)); 145 g2D.fill(this.getUpArea(xpos, yPos, width, h - 2)); 146 147 g2D.setPaint(new GradientPaint(0, h / 2, colorSet.bottomGradColor1, 0, 148 h, colorSet.bottomGradColor2)); 149 g2D.fill(this.getDownArea(xpos, yPos, width, h - 2)); 150 151 } 152 153 private Shape getArea(int x, int y, int w, int h) { 154 RoundRectangle2D rect = new RoundRectangle2D.Float(x, y, w, h, 15, 15); 155 Area a = new Area(rect); 156 Rectangle2D rec = new Rectangle2D.Float(x, y + h / 2, w, h / 2); 157 Area b = new Area(rec); 158 a.add(b); 159 return a; 160 } 161 162 private Shape getUpArea(int x, int y, int w, int h) { 163 Rectangle2D rec = new Rectangle2D.Float(x, y, w, h / 3 ); 164 Area a = new Area(rec); 165 RoundRectangle2D rect = new RoundRectangle2D.Float(x, y, w, h, 15, 15); 166 Area b = new Area(rect); 167 a.intersect(b); 168 return a; 169 } 170 171 private Shape getDownArea(int x, int y, int w, int h) { 172 Rectangle2D rec = new Rectangle2D.Float(x, y + h / 3, w, h*2 / 3 +1); 173 Area a = new Area(rec); 174 RoundRectangle2D rect = new RoundRectangle2D.Float(x, y, w, h, 15, 15); 175 // Area b = new Area(rect); 176 // a.intersect(b); 177 return a; 178 } 179 private class ColorSet { 180 Color topGradColor1; 181 Color topGradColor2; 182 Color bottomGradColor1; 183 Color bottomGradColor2; 184 } 185 186 @Override 187 protected void paintText(Graphics g, int tabPlacement, Font font, 188 FontMetrics metrics, int tabIndex, String title, 189 Rectangle textRect, boolean isSelected) { 190 super.paintText(g, tabPlacement, font, metrics, tabIndex, title, 191 textRect, isSelected); 192 g.setFont(font); 193 View v = getTextViewForTab(tabIndex); 194 if (v != null) { 195 // html 196 v.paint(g, textRect); 197 } else { 198 // plain text 199 int mnemIndex = tabPane.getDisplayedMnemonicIndexAt(tabIndex); 200 if (tabPane.isEnabled() && tabPane.isEnabledAt(tabIndex)) { 201 g.setColor(tabPane.getForegroundAt(tabIndex)); 202 BasicGraphicsUtils 203 .drawStringUnderlineCharAt(g, title, mnemIndex, 204 textRect.x, textRect.y + metrics.getAscent()); 205 } else { // tab disabled 206 g.setColor(Color.BLACK); 207 BasicGraphicsUtils 208 .drawStringUnderlineCharAt(g, title, mnemIndex, 209 textRect.x, textRect.y + metrics.getAscent()); 210 g.setColor(tabPane.getBackgroundAt(tabIndex).darker()); 211 BasicGraphicsUtils.drawStringUnderlineCharAt(g, title, 212 mnemIndex, textRect.x - 1, 213 textRect.y + metrics.getAscent() - 1); 214 } 215 } 216 } 217 218 //固定tab标签宽度 219 @Override 220 protected int calculateTabWidth(int tabPlacement, int tabIndex, 221 FontMetrics metrics) { 222 return 120; 223 // return 10 + anchoFocoV 224 // + super.calculateTabWidth(tabPlacement, tabIndex, metrics); 225 } 226 227 @Override 228 protected int calculateTabHeight(int tabPlacement, int tabIndex, 229 int fontHeight) { 230 if (tabPlacement == LEFT || tabPlacement == RIGHT) { 231 return super.calculateTabHeight(tabPlacement, tabIndex, fontHeight); 232 } else { 233 return anchoFocoH 234 + super.calculateTabHeight(tabPlacement, tabIndex, 235 fontHeight); 236 } 237 } 238 239 protected int calculateMaxTabHeight(int tabPlacement) { 240 return 25; 241 } 242 //set tab title hight 243 @Override 244 protected void paintTabBorder(Graphics g, int tabPlacement, int tabIndex, 245 int x, int y, int w, int h, boolean isSelected) { 246 // if (isSelected) { 247 g.setColor(Color.decode("#afafaf")); 248 int[] xp = new int[] { x, x, x + 3, x + w - inclTab - 6, 249 x + w - inclTab - 3, x + w - inclTab, x + w - inclTab, x }; 250 int[] yp = new int[] { y + h, y + 3, y, y, y, y + 3, y + h, y + h }; 251 shape = new Polygon(xp, yp, xp.length); 252 Graphics2D g2D = (Graphics2D) g; 253 g2D.drawPolygon(shape); 254 g.setColor(Color.white); 255 g.drawLine(x, y + h, x + w - inclTab, y + h); 256 // } 257 } 258 259 protected int getTabLabelShiftY(int tabPlacement, int tabIndex, 260 boolean isSelected) { 261 return 0; 262 } 263 264 protected int getTabLabelShiftX(int tabPlacement, int tabIndex, 265 boolean isSelected) { 266 return 0; 267 } 268 269 @Override 270 protected void paintFocusIndicator(Graphics g, int tabPlacement, 271 Rectangle[] rects, int tabIndex, Rectangle iconRect, 272 Rectangle textRect, boolean isSelected) { 273 if (tabPane.hasFocus() || isSelected) { 274 // g.setColor(UIManager.getColor("ScrollBar.thumbShadow")); 275 // g.drawPolygon(shape); 276 } 277 } 278 279 protected Color hazAlfa(int fila) { 280 int alfa = 0; 281 if (fila >= 0) { 282 alfa = 50 + (fila > 7 ? 70 : 10 * fila); 283 } 284 return new Color(0, 0, 0, alfa); 285 } 286 287 private int lastRollOverTab = -1; 288 289 private class RollOverListener implements MouseMotionListener, 290 MouseListener { 291 public void mouseMoved(MouseEvent e) { 292 checkRollOver(); 293 } 294 295 public void mouseEntered(MouseEvent e) { 296 checkRollOver(); 297 } 298 299 public void mouseExited(MouseEvent e) { 300 tabPane.repaint(); 301 } 302 303 private void checkRollOver() { 304 int currentRollOver = getRolloverTab(); 305 if (currentRollOver != lastRollOverTab) { 306 lastRollOverTab = currentRollOver; 307 Rectangle tabsRect = new Rectangle(0, 0, tabPane.getWidth(), 308 tabPane.getHeight()+1); 309 tabPane.repaint(tabsRect); 310 } 311 } 312 } 313 }
关键点:
1. 继承BasicTabbedPaneUI类,这其中有我们必须要重写的一个方法:
public static ComponentUI createUI(JComponent c) {
return new XXXTabbedPaneUI();
}
其中XXXTabbedPaneUI就是自己实现的BasicTabbedPaneUI的子类的名字。
2.下面类出几个改变外观的重要的方法:
a. protectedvoid installDefaults() //可以改变一些BasicTabbedPaneUI中默认的属性。
b.protectedvoid paintTabArea(Graphics g, int tabPlacement, int selectedIndex) //绘制整个选项卡区域
c. protectedvoid paintTabBackground(Graphics g, int tabPlacement,
int tabIndex, int x, int y, int w, int h, boolean isSelected)
//绘制某个选项卡的背景色
d. protectedvoid paintContentBorder(Graphics g, int tabPlacement,
int selectedIndex) //绘制TabbedPane容器的四周边框样式。
e. protectedvoid paintFocusIndicator(Graphics g, int tabPlacement,
Rectangle[] rects, int tabIndex, Rectangle iconRect,
Rectangle textRect, boolean isSelected)
//绘制选中某个Tab后,获得焦点的样式。
3、具体paint()渲染可参考前篇: JButton自定义式样