http://blog.chinaunix.net/uid-7570422-id-3136430.html
TabShapeTest.java
import java.awt.Color; import java.awt.Dimension; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.Shape; import java.awt.geom.Area; import java.awt.geom.Path2D; import java.awt.geom.Rectangle2D; import javax.swing.Icon; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTabbedPane; import javax.swing.SwingUtilities; import javax.swing.text.View; public class TabShapeTest extends JFrame{ /** * */ private static final long serialVersionUID = 1L; public static void main(String [] args) { new TabShapeTest().setVisible(true); } public TabShapeTest() { JTabbedPane tpShape = new JTabbedPane(); tpShape.setUI(new ShapeTabTabbedPaneUI()); add(tpShape); setPreferredSize(new Dimension(280,300)); tpShape.addTab("first",new JPanel()); tpShape.addTab("second?????", new JPanel()); tpShape.addTab("third", new JPanel()); tpShape.setBackgroundAt(1, Color.yellow); tpShape.setBackgroundAt(2, Color.BLUE); pack(); }
ShapeTabTabbedPaneUI.java
public static class ShapeTabTabbedPaneUI extends javax.swing.plaf.basic.BasicTabbedPaneUI { private Color selectedColor; protected void installDefaults() { super.installDefaults(); } public ShapeTabTabbedPaneUI() { } protected void paintTabBackground(Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h, boolean isSelected) { Graphics2D g2d = (Graphics2D) g; g.setColor(!isSelected || selectedColor == null? tabPane.getBackgroundAt(tabIndex) : selectedColor); switch(tabPlacement) { case LEFT: g.fillRect(x+1, y+1, w-1, h-3); break; case RIGHT: g.fillRect(x, y+1, w-2, h-3); break; case BOTTOM: g.fillRect(x+1, y, w-3, h-1); break; case TOP: default: //g.fillRect(x+1, y+1, w-3, h-1); g2d.fill(this.getTabArea(x+1, y+1, w-11, h-1)); } } private Shape getTabArea(int x, int y, int w, int h) { Rectangle2D rec = new Rectangle2D.Double(x, y, w, h ); Area aRec = new Area(rec); Path2D.Double triangle=new Path2D.Double(); triangle.moveTo(x+w, y); triangle.lineTo(x+w+10, y+h/2); triangle.lineTo(x+w, y+h); triangle.closePath(); aRec.add(new Area(triangle)); triangle.reset(); return aRec; } protected void paintTabBorder(Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h, boolean isSelected) { g.setColor(lightHighlight); switch (tabPlacement) { case LEFT: g.drawLine(x+1, y+h-2, x+1, y+h-2); // bottom-left highlight g.drawLine(x, y+2, x, y+h-3); // left highlight g.drawLine(x+1, y+1, x+1, y+1); // top-left highlight g.drawLine(x+2, y, x+w-1, y); // top highlight g.setColor(shadow); g.drawLine(x+2, y+h-2, x+w-1, y+h-2); // bottom shadow g.setColor(darkShadow); g.drawLine(x+2, y+h-1, x+w-1, y+h-1); // bottom dark shadow break; case RIGHT: g.drawLine(x, y, x+w-3, y); // top highlight g.setColor(shadow); g.drawLine(x, y+h-2, x+w-3, y+h-2); // bottom shadow g.drawLine(x+w-2, y+2, x+w-2, y+h-3); // right shadow g.setColor(darkShadow); g.drawLine(x+w-2, y+1, x+w-2, y+1); // top-right dark shadow g.drawLine(x+w-2, y+h-2, x+w-2, y+h-2); // bottom-right dark shadow g.drawLine(x+w-1, y+2, x+w-1, y+h-3); // right dark shadow g.drawLine(x, y+h-1, x+w-3, y+h-1); // bottom dark shadow break; case BOTTOM: g.drawLine(x, y, x, y+h-3); // left highlight g.drawLine(x+1, y+h-2, x+1, y+h-2); // bottom-left highlight g.setColor(shadow); g.drawLine(x+2, y+h-2, x+w-3, y+h-2); // bottom shadow g.drawLine(x+w-2, y, x+w-2, y+h-3); // right shadow g.setColor(darkShadow); g.drawLine(x+2, y+h-1, x+w-3, y+h-1); // bottom dark shadow g.drawLine(x+w-2, y+h-2, x+w-2, y+h-2); // bottom-right dark shadow g.drawLine(x+w-1, y, x+w-1, y+h-3); // right dark shadow break; case TOP: default: g.drawLine(x, y+2, x, y+h-1); // left highlight g.drawLine(x+1, y+1, x+1, y+1); // top-left highlight // g.drawLine(x+2, y, x+w-3, y); // top highlight g.drawLine(x+2,y, x+w-10, y); g.setColor(shadow); // g.drawLine(x+w-2, y+2, x+w-2, y+h-1); // right shadow g.drawLine(x+w-10,y, x+w-1, y+h/2-1); g.drawLine(x+w-1,y+h/2+1,x+w-10,y+h); g.setColor(darkShadow); //g.drawLine(x+w-1, y+2, x+w-1, y+h-1); // right dark-shadow //g.drawLine(x+w-2, y+1, x+w-2, y+1); // top-right shadow g.drawLine(x+w-1,y+h/2+2,x+w-10,y+h+1); } } protected void layoutLabel(int tabPlacement, FontMetrics metrics, int tabIndex, String title, Icon icon, Rectangle tabRect, Rectangle iconRect, Rectangle textRect, boolean isSelected ) { textRect.x = textRect.y = iconRect.x = iconRect.y = 0; View v = getTextViewForTab(tabIndex); if (v != null) { tabPane.putClientProperty("html", v); } SwingUtilities.layoutCompoundLabel(tabPane, metrics, title, icon, SwingUtilities.CENTER, SwingUtilities.CENTER, SwingUtilities.CENTER, SwingUtilities.TRAILING, tabRect, iconRect, textRect, textIconGap); tabPane.putClientProperty("html", null); int xNudge = getTabLabelShiftX(tabPlacement, tabIndex, isSelected); int yNudge = getTabLabelShiftY(tabPlacement, tabIndex, isSelected); iconRect.x += xNudge; iconRect.y += yNudge; textRect.y += yNudge; switch (tabPlacement) { case LEFT: textRect.x += xNudge; break; case RIGHT: textRect.x += xNudge; break; case BOTTOM: textRect.x += xNudge; break; case TOP: default: textRect.x += xNudge-4; } } } }