如何在Java swing中实现TabbedPane的四面阴影效果?

时间:2016-02-25 09:06:34

标签: java swing awt jtabbedpane nimbus

我想为Tabbedpane获得四个侧面阴影效果。

我的代码如下:

MianClass

import java.awt.FlowLayout;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.UIManager;

class NimbusBaseDemo extends JFrame {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    JTabbedPane tabbedPane;
    int i;

    private UIManager.LookAndFeelInfo[] lafs;

    public NimbusBaseDemo() {
        try {

            // Set nimbus look and feel. nimbusBase works only for it.
            new NimbusBaseUI();

        } catch (Exception e) {
            e.printStackTrace();
        }

        setTitle("Nimbus Base Demo");
        setSize(400, 400);
        setLayout(new FlowLayout());
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
        tabbedPane = new JTabbedPane();
        tabbedPane.addTab("World Cities", new CitiesPanel());
        tabbedPane.addTab("Colors ", new ColorsPanel());
        tabbedPane.addTab("World Cities", new CitiesPanel());

        add(tabbedPane);
    }

    public static void main(String args[]) {

        new NimbusBaseDemo();
    }

    class CitiesPanel extends JPanel {

        public CitiesPanel() {
            JButton b1 = new JButton("New York");
            add(b1);
            JButton b2 = new JButton("London");
            add(b2);
            JButton b3 = new JButton("Hong Kong");
            add(b3);
            JButton b4 = new JButton("Tokyo");
            add(b4);
        }
    }

    class ColorsPanel extends JPanel {

        public ColorsPanel() {

            JCheckBox cb1 = new JCheckBox("Red");
            cb1.setEnabled(true);
            add(cb1);

            JCheckBox cb2 = new JCheckBox("Green");
            cb2.setEnabled(true);
            add(cb2);
            JCheckBox cb3 = new JCheckBox("Blue");
            add(cb3);
        }
    }
}

我正在扩展 NimbusLookAndFeel 类,以获取选项卡式窗格的默认主题。通过这个所有我的标签窗格在我的项目中遵循相同的主题。

NimbusBaseUI类

import javax.swing.UIManager;
import javax.swing.plaf.nimbus.NimbusLookAndFeel;

public class NimbusBaseUI extends NimbusLookAndFeel {

    public NimbusBaseUI() {
        super(); // Initialisation and installating
        try {
            new TabbedPaneTheme(this);
            UIManager.setLookAndFeel(this);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void initialize() {
        // TODO Auto-generated method stub
        super.initialize();
    }

}

最后,我写了一个Customer主题类来应用TabbedPane。这里我把tabbedpane属性参数放到NimbusLookAndFeel的getdefaults()方法中。

TabbedPaneTheme类

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.RenderingHints;

import javax.swing.Painter;
import javax.swing.plaf.ColorUIResource;

public class TabbedPaneTheme {
    private Color light, dark;
    private GradientPaint gradPaint;

    protected int strokeSize = 1;
    /** Color of shadow */
    /** Color of shadow */
    protected Color shadowColor = new Color(128, 128, 128, 140);
    // protected Color shadowColor = new Color(0,0,0);
    /** Sets if it drops shadow */
    protected boolean shady = true;
    /** Sets if it has an High Quality view */
    protected boolean highQuality = false;
    /** Double values for Horizontal and Vertical radius of corner arcs */
    protected Dimension arcs = new Dimension(10, 10);
    /** Distance between shadow border and opaque panel border */
    protected int shadowGap = 1;
    /** The offset of shadow. */
    protected int shadowOffset = 1; // width of the shadow
    /** The transparency value of shadow. ( 0 - 255) */
    protected int shadowAlpha = 130;

    public TabbedPaneTheme(NimbusBaseUI nimbusUI) {
        // TODO Auto-generated constructor stub

        nimbusUI.getDefaults().put(
                "TabbedPane:TabbedPaneTab[Enabled+Selected].shadow",
                ColorUIResource.BLUE);
        nimbusUI.getDefaults().put("TabbedPane:TabbedPaneTab.contentMargins",
                new Insets(0, 6, 10, 6)); // (// top, left, bottom, right)
        nimbusUI.getDefaults().put(
                "TabbedPane:TabbedPaneTabArea.contentMargins",
                new Insets(0, 0, -6, 0));
        nimbusUI.getDefaults().put("TabbedPane.tabAreaInsets",
                new Insets(2, -1, -1, -5));
        nimbusUI.getDefaults().put("TabbedPane.contentBorderInsets",
                new Insets(-1, -1, -1, -5));
        nimbusUI.getDefaults().put("TabbedPane.tabsOverlapBorder",
                new Insets(-5, -5, -5, -5));

        nimbusUI.getDefaults().put("Panel.opaque", false);
        nimbusUI.getDefaults().put("TabbedPane.shadow", new Color(255, 0, 0));
        nimbusUI.getDefaults().put("TabbedPane.focus", new Color(255, 0, 0));
        nimbusUI.getDefaults().put(
                "TabbedPane:TabbedPaneTab[Enabled+Selected].backgroundPainter",
                new TabbedPanePainter(new Color(255, 255, 255), new Color(255,
                        255, 255)));
        nimbusUI.getDefaults().put(
                "TabbedPane:TabbedPaneTab[Enabled+Selected].font",
                new Font("Myriad Pro", Font.BOLD, 12));
        nimbusUI.getDefaults().put(
                "TabbedPane:TabbedPaneTab[Enabled+Selected].textForeground",
                new Color(91, 113, 132));
        nimbusUI.getDefaults().put(
                "TabbedPane:TabbedPaneTab[Selected].backgroundPainter",
                new TabbedPanePainter(new Color(255, 255, 255), new Color(255,
                        255, 255)));
        nimbusUI.getDefaults().put("TabbedPane:TabbedPaneTab[Selected].font",
                new Font("Myriad Pro", Font.BOLD, 12));
        nimbusUI.getDefaults().put(
                "TabbedPane:TabbedPaneTab[Selected].textForeground",
                new Color(91, 113, 132));

        nimbusUI.getDefaults()
                .put("TabbedPane:TabbedPaneTab[Enabled+Selected+Pressed].backgroundPainter",
                        new TabbedPanePainter(new Color(255, 255, 255),
                                new Color(255, 255, 255)));
        nimbusUI.getDefaults().put(
                "TabbedPane:TabbedPaneTab[Enabled+Selected+Pressed].font",
                new Font("Myriad Pro", Font.BOLD, 12));
        nimbusUI.getDefaults()
                .put("TabbedPane:TabbedPaneTab[Enabled+Selected+Pressed].textForeground",
                        new Color(91, 113, 132));

        nimbusUI.getDefaults()
                .put("TabbedPane:TabbedPaneTab[Default+Enabled+Selected+Pressed+Focused].backgroundPainter",
                        new TabbedPanePainter(new Color(255, 255, 255),
                                new Color(255, 255, 255)));
        nimbusUI.getDefaults()
                .put("TabbedPane:TabbedPaneTab[Default+Enabled+Selected+Pressed+Focused].font",
                        new Font("Myriad Pro", Font.BOLD, 12));
        nimbusUI.getDefaults()
                .put("TabbedPane:TabbedPaneTab[Default+Enabled+Selected+Pressed+Focused].textForeground",
                        new Color(91, 113, 132));

        nimbusUI.getDefaults()
                .put("TabbedPane:TabbedPaneTab[Enabled+Selected+MouseOver].backgroundPainter",
                        new TabbedPanePainter(new Color(255, 255, 255),
                                new Color(255, 255, 255)));
        nimbusUI.getDefaults().put(
                "TabbedPane:TabbedPaneTab[Enabled+Selected+MouseOver].font",
                new Font("Myriad Pro", Font.BOLD, 12));
        nimbusUI.getDefaults()
                .put("TabbedPane:TabbedPaneTab[Enabled+Selected+MouseOver].textForeground",
                        new Color(91, 113, 132));

        nimbusUI.getDefaults()
                .put("TabbedPane:TabbedPaneTab[Focused+Selected+MouseOver].backgroundPainter",
                        new TabbedPanePainter(new Color(255, 255, 255),
                                new Color(255, 255, 255)));
        nimbusUI.getDefaults().put(
                "TabbedPane:TabbedPaneTab[Focused+Selected+MouseOver].font",
                new Font("Myriad Pro", Font.BOLD, 12));
        nimbusUI.getDefaults()
                .put("TabbedPane:TabbedPaneTab[Focused+Selected+MouseOver].textForeground",
                        new Color(91, 113, 132));

        nimbusUI.getDefaults().put(
                "TabbedPane:TabbedPaneTab[Focused+Selected].backgroundPainter",
                new TabbedPanePainter(new Color(255, 255, 255), new Color(255,
                        255, 255)));
        nimbusUI.getDefaults().put(
                "TabbedPane:TabbedPaneTab[Focused+Selected].font",
                new Font("Myriad Pro", Font.BOLD, 12));
        nimbusUI.getDefaults().put(
                "TabbedPane:TabbedPaneTab[Focused+Selected].textForeground",
                new Color(91, 113, 132));

        nimbusUI.getDefaults()
                .put("TabbedPane:TabbedPaneTab[Enabled+Selected+MouseOver+Pressed+Focused].backgroundPainter",
                        new TabbedPanePainter(new Color(255, 255, 255),
                                new Color(255, 255, 255)));
        nimbusUI.getDefaults()
                .put("TabbedPane:TabbedPaneTab[Enabled+Selected+MouseOver+Pressed+Focused].font",
                        new Font("Myriad Pro", Font.BOLD, 12));
        nimbusUI.getDefaults()
                .put("TabbedPane:TabbedPaneTab[Enabled+Selected+MouseOver+Pressed+Focused].textForeground",
                        new Color(91, 113, 132));

        nimbusUI.getDefaults().put(
                "TabbedPane:TabbedPaneTab[Enabled].backgroundPainter",
                new TabbedPanePainter(new Color(98, 97, 93), new Color(127,
                        127, 119)));
        nimbusUI.getDefaults().put(
                "TabbedPane:TabbedPaneTab[Enabled].textForeground",
                new Color(255, 255, 255));
        nimbusUI.getDefaults().put("TabbedPane:TabbedPaneTab[Enabled].font",
                new Font("Myriad Pro", Font.BOLD, 12));

        nimbusUI.getDefaults()
                .put("TabbedPane:TabbedPaneTab[Enabled+MouseOver].backgroundPainter",
                        new TabbedPanePainter(new Color(255, 255, 255),
                                new Color(255, 255, 255)));
        nimbusUI.getDefaults().put(
                "TabbedPane:TabbedPaneTab[Enabled+MouseOver].textForeground",
                new Color(91, 113, 132));
        nimbusUI.getDefaults().put(
                "TabbedPane:TabbedPaneTab[Enabled+MouseOver].font",
                new Font("Myriad Pro", Font.BOLD, 12));

        nimbusUI.getDefaults()
                .put("TabbedPane:TabbedPaneTabArea[Enabled+MouseOver].backgroundPainter",
                        new TabbedPane_TabView_Painter(
                                new Color(255, 255, 255), new Color(255, 255,
                                        255)));
        nimbusUI.getDefaults().put(
                "TabbedPane:TabbedPaneTabArea[Enabled].backgroundPainter",
                new TabbedPane_TabView_Painter(new Color(255, 255, 255),
                        new Color(255, 255, 255)));
        nimbusUI.getDefaults()
                .put("TabbedPane:TabbedPaneTabArea[Focused+Selected].backgroundPainter",
                        new TabbedPane_TabView_Painter(
                                new Color(255, 255, 255), new Color(255, 255,
                                        255)));
        nimbusUI.getDefaults()
                .put("TabbedPane:TabbedPaneTabArea[Focused+Selected+MouseOver].backgroundPainter",
                        new TabbedPane_TabView_Painter(
                                new Color(255, 255, 255), new Color(255, 255,
                                        255)));

        nimbusUI.getDefaults().put(
                "TabbedPane:TabbedPaneContent.[Enabled].backgroundPainter",
                new TabbedPane_TabContent_Painter(new Color(255, 255, 255),
                        new Color(255, 255, 255)));
        nimbusUI.getDefaults().put(
                "TabbedPane:TabbedPaneContent.[Selected].backgroundPainter",
                new TabbedPane_TabContent_Painter(new Color(255, 255, 255),
                        new Color(255, 255, 255)));
        nimbusUI.getDefaults().put(
                "TabbedPane:TabbedPaneContent.[Focused].backgroundPainter",
                new TabbedPane_TabContent_Painter(new Color(255, 255, 255),
                        new Color(255, 255, 255)));
        nimbusUI.getDefaults().put(
                "TabbedPane:TabbedPaneContent.[Default].backgroundPainter",
                new TabbedPane_TabContent_Painter(new Color(255, 255, 255),
                        new Color(255, 255, 255)));
        nimbusUI.getDefaults().put(
                "TabbedPane:TabbedPaneContent.backgroundPainter",
                new TabbedPane_TabContent_Painter(Color.WHITE, Color.WHITE));
        nimbusUI.getDefaults().put("TabbedPane:TabbedPaneContent.background",
                Color.WHITE);

        nimbusUI.getDefaults()
                .put("TabbedPane:TabbedPaneContent.[Enabled+MouseOver].backgroundPainter",
                        new TabbedPane_TabContent_Painter(new Color(255, 255,
                                255), new Color(255, 255, 255)));
        nimbusUI.getDefaults().put(
                "TabbedPane:TabbedPaneContent.[Selected].backgroundPainter",
                new TabbedPane_TabContent_Painter(new Color(255, 255, 255),
                        new Color(255, 255, 255)));
        nimbusUI.getDefaults()
                .put("TabbedPane:TabbedPaneContent.[Enabled+Selected].backgroundPainter",
                        new TabbedPane_TabContent_Painter(new Color(255, 255,
                                255), new Color(255, 255, 255)));
        nimbusUI.getDefaults()
                .put("TabbedPane:TabbedPaneContent.[Enabled+Focused].backgroundPainter",
                        new TabbedPane_TabContent_Painter(new Color(255, 255,
                                255), new Color(255, 255, 255)));
        nimbusUI.getDefaults().put(
                "TabbedPane:TabbedPaneContent.[Selected].backgroundPainter",
                new TabbedPane_TabContent_Painter(new Color(255, 255, 255),
                        new Color(255, 255, 255)));
        nimbusUI.getDefaults()
                .put("TabbedPane:TabbedPaneContent.[Enabled+Pressed].backgroundPainter",
                        new TabbedPane_TabContent_Painter(new Color(255, 255,
                                255), new Color(255, 255, 255)));
    }

    public class TabbedPane_TabContent_Painter implements Painter {
        private Color light, dark;
        private GradientPaint gradPaint;

        public TabbedPane_TabContent_Painter(Color light, Color dark) {
            this.light = light;
            this.dark = dark;
        }

        @Override
        public void paint(Graphics2D g, Object c, int w, int h) {
            Color shadowColorA = new Color(shadowColor.getRed(),
                    shadowColor.getGreen(), shadowColor.getBlue(), shadowAlpha);
            if (highQuality) {
                g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);
            }
            if (shady) {
                g.setColor(shadowColorA);
                g.fillRoundRect(0, 0, w - shadowGap, h - shadowGap, arcs.width,
                        arcs.height);
            } else {
                shadowGap = 1;
            }
            gradPaint = new GradientPaint((w / 2.0f), 0, new Color(255, 255,
                    255), (w / 2.0f), (h / 2.0f), new Color(255, 255, 255),
                    false);
            g.setPaint(gradPaint);
            g.fillRoundRect(shadowOffset,// X position
                    shadowOffset,// Y position
                    w - strokeSize - shadowOffset, // width
                    h - strokeSize - shadowOffset, // height
                    arcs.width, arcs.height);// arc Dimension
            g.setColor(new Color(188, 188, 187, 130));
            g.setStroke(new BasicStroke(strokeSize));
            g.drawRoundRect(shadowOffset,// X position
                    shadowOffset,// Y position
                    w - strokeSize - shadowOffset, // width
                    h - strokeSize - shadowOffset, // height
                    arcs.width, arcs.height);// arc Dimension
            g.setStroke(new BasicStroke());
        }
    }

    public class TabbedPane_TabView_Painter implements Painter {
        private Color light, dark;
        private GradientPaint gradPaint;

        public TabbedPane_TabView_Painter(Color light, Color dark) {
            this.light = light;
            this.dark = dark;
        }

        @Override
        public void paint(Graphics2D g, Object c, int w, int h) {
            Color shadowColor = Color.black;
            Color shadowColorA = new Color(shadowColor.getRed(),
                    shadowColor.getGreen(), shadowColor.getBlue(), 150);
            g.setColor(shadowColorA);
            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);
            gradPaint = new GradientPaint((w / 2.0f), 0, light, (w / 2.0f),
                    (h / 2.0f), dark, true);
            g.setPaint(gradPaint);
        }
    }

    public class TabbedPanePainter implements Painter {
        private Color light, dark;
        private GradientPaint gradPaint;

        public TabbedPanePainter(Color light, Color dark) {
            this.light = light;
            this.dark = dark;
        }

        @Override
        public void paint(Graphics2D g, Object c, int w, int h) {
            Color shadowColor = Color.black;
            Color shadowColorA = new Color(shadowColor.getRed(),
                    shadowColor.getGreen(), shadowColor.getBlue(), 150);
            g.setColor(shadowColorA);
            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);
            gradPaint = new GradientPaint((w / 2.0f), 0, light, (w / 2.0f),
                    (h / 2.0f), dark, true);
            g.setPaint(gradPaint);
            // g.fillRect(2, 2, (w - 5), (h - 5));
            g.fillRoundRect(2, 2, (w - 5), (h - 5), 6, 6);
        }
    }
}

我得到了结果 enter image description here

但是我想对选中的tabbedpane TAB 阴影效果以及选中的tabbedpane TAB 的阴影实施。 喜欢这个

enter image description here

开始使用帮助&建议即可。

1 个答案:

答案 0 :(得分:1)

尽早获得更好的帮助:

这是我的尝试:

enter image description here

import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import javax.swing.plaf.nimbus.NimbusLookAndFeel;

public class NimbusTabbedPaneTest {
  public JComponent makeUI() {
    JTabbedPane tabbedPane = new JTabbedPane();
    tabbedPane.addTab("World Cities", new JScrollPane(new JTree()));
    tabbedPane.addTab("Colors ",      new JSplitPane());
    tabbedPane.addTab("World Cities", new JScrollPane(new JTextArea()));
    tabbedPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    return tabbedPane;
  }
  public static void main(String... args) {
    EventQueue.invokeLater(() -> {
      try {
        new NimbusBaseUI();
      } catch (Exception e) {
        e.printStackTrace();
      }
      JFrame f = new JFrame("Nimbus Base Demo");
      f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
      f.getContentPane().add(new NimbusTabbedPaneTest().makeUI());
      f.setSize(400, 400);
      f.setLocationRelativeTo(null);
      f.setVisible(true);
    });
  }
}

class NimbusBaseUI extends NimbusLookAndFeel {
  public NimbusBaseUI() {
    super();
    try {
      new TabbedPaneTheme(this);
      UIManager.setLookAndFeel(this);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

class TabbedPaneTheme {
  protected static int OVERPAINT = 6;
  protected static int shadowOffset = 1;
  protected static int strokeSize = 2;
  protected static Dimension arcs = new Dimension(10, 10);
  public TabbedPaneTheme(NimbusBaseUI nimbusUI) {
    UIDefaults d = nimbusUI.getDefaults();

    d.put("TabbedPane:TabbedPaneContent.contentMargins", new Insets(0, 5, 5, 5));
    //d.put("TabbedPane:TabbedPaneTab.contentMargins",     new Insets(2, 8, 3, 8));
    //d.put("TabbedPane:TabbedPaneTabArea.contentMargins", new Insets(3, 10, 4, 10));
    d.put("TabbedPane:TabbedPaneTabArea.contentMargins",
          new Insets(3, 10, OVERPAINT, 10));

    Painter<JComponent> tabAreaPainter = new TabAreaPainter();
    d.put("TabbedPane:TabbedPaneTabArea[Disabled].backgroundPainter",
          tabAreaPainter);
    d.put("TabbedPane:TabbedPaneTabArea[Enabled].backgroundPainter",
          tabAreaPainter);
    d.put("TabbedPane:TabbedPaneTabArea[Enabled+MouseOver].backgroundPainter",
          tabAreaPainter);
    d.put("TabbedPane:TabbedPaneTabArea[Enabled+Pressed].backgroundPainter",
          tabAreaPainter);

    d.put("TabbedPane:TabbedPaneContent.backgroundPainter",
          new TabContentPainter());

    Painter<JComponent> tabPainter = new TabPainter(Color.ORANGE, false);
    d.put("TabbedPane:TabbedPaneTab[Enabled+MouseOver].backgroundPainter",
          tabPainter);
    d.put("TabbedPane:TabbedPaneTab[Enabled+Pressed].backgroundPainter",
          tabPainter);
    d.put("TabbedPane:TabbedPaneTab[Enabled].backgroundPainter",
          tabPainter);

    Painter<JComponent> selectedTabPainter = new TabPainter(Color.WHITE, true);
    d.put("TabbedPane:TabbedPaneTab[Focused+MouseOver+Selected].backgroundPainter",
          selectedTabPainter);
    d.put("TabbedPane:TabbedPaneTab[Focused+Pressed+Selected].backgroundPainter",
          selectedTabPainter);
    d.put("TabbedPane:TabbedPaneTab[Focused+Selected].backgroundPainter",
          selectedTabPainter);
    d.put("TabbedPane:TabbedPaneTab[MouseOver+Selected].backgroundPainter",
          selectedTabPainter);
    d.put("TabbedPane:TabbedPaneTab[Selected].backgroundPainter",
          selectedTabPainter);
    d.put("TabbedPane:TabbedPaneTab[Pressed+Selected].backgroundPainter",
          selectedTabPainter);
  }

  private static class TabPainter implements Painter<JComponent> {
    private final Color color;
    private int r = 6;
    private int x = 3;
    private int y = 3;
    private boolean selected;
    public TabPainter(Color color, boolean selected) {
      this.color = color;
      this.selected = selected;
    }
    @Override public void paint(Graphics2D g, JComponent c, int width, int height) {
      int ex = selected ? OVERPAINT : 0;
      Graphics2D g2 = (Graphics2D) g.create(0, 0, width, height + ex);
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                          RenderingHints.VALUE_ANTIALIAS_ON);
      int w = width - 6 - 1;
      int h = height + r;
      for (int i = 0; i < 3; i++) {
        g2.setColor(new Color(0, 0, 0, 20));
        g2.fill(new RoundRectangle2D.Double(x - i, y - i, w + i + i, h, r, r));
      }
      g2.setColor(color);
      g2.fill(new RoundRectangle2D.Double(x, y, w, h + 4, r, r));
      g2.dispose();
    }
  }

  private static class TabAreaPainter implements Painter<JComponent> {
    @Override public void paint(Graphics2D g, JComponent c, int w, int h) {
      Graphics2D g2 = (Graphics2D) g.create(0, 0, w, h);
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                          RenderingHints.VALUE_ANTIALIAS_ON);

      RoundRectangle2D r = new RoundRectangle2D.Double(
        shadowOffset,// X position
        shadowOffset + h - OVERPAINT,// Y position
        w - strokeSize - shadowOffset, // width
        40, // height
        arcs.width, arcs.height);// arc Dimension

      g2.setPaint(Color.CYAN);
      g2.fill(r);
      g2.setColor(Color.RED);
      g2.setStroke(new BasicStroke(strokeSize));
      g2.draw(r);
      g2.dispose();
    }
  }

  private static class TabContentPainter implements Painter<JComponent> {
    @Override public void paint(Graphics2D g, JComponent c, int w, int h) {
      Graphics2D g2 = (Graphics2D) g.create(0, 0, w, h);
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                          RenderingHints.VALUE_ANTIALIAS_ON);

      g2.translate(0, -OVERPAINT);
      h += OVERPAINT;

      RoundRectangle2D r = new RoundRectangle2D.Double(
        shadowOffset,// X position
        shadowOffset,// Y position
        w - strokeSize - shadowOffset, // width
        h - strokeSize - shadowOffset, // height
        arcs.width, arcs.height);// arc Dimension

      g2.setPaint(Color.WHITE);
      g2.fill(r);
      g2.setColor(Color.ORANGE);
      g2.setStroke(new BasicStroke(strokeSize));
      g2.draw(r);
      g2.dispose();
    }
  }
}