问题
I want to customize the look of the tabs in JTabbedPane.
I want to start from the simplest and plainest behavior: no borders, solid color.
The problem is that a non-plainess still remains: the tabs slight margin overlap.

You see that since the second tab is selected, it is "brought to the fore". This is achieved by a slight margin overlap. Is there a (non tricky) way to disable this behavior?
simple, testable (just fix imports) code:
public class TabbedPane_LookStudy extends JFrame{
public static void main(String [] args) throws UnsupportedLookAndFeelException {
UIManager.setLookAndFeel(new NimbusLookAndFeel());
new TabbedPane_LookStudy().setVisible(true);
}
public TabbedPane_LookStudy() {
JTabbedPane tp = new JTabbedPane();
tp.setUI(new MyTabbedPaneUI());
add(tp);
tp.addTab("first",new JPanel());
tp.addTab("second", new JPanel());
tp.addTab("third", new JPanel());
setPreferredSize(new Dimension(180,100));
pack();
}
public static class MyTabbedPaneUI extends javax.swing.plaf.basic.BasicTabbedPaneUI {
@Override
protected void paintTab(Graphics g, int tabPlacement, Rectangle[] rects,
int tabIndex, Rectangle iconRect, Rectangle textRect) {
Color savedColor = g.getColor();
g.setColor(Color.PINK);
g.fillRect(rects[tabIndex].x, rects[tabIndex].y,
rects[tabIndex].width, rects[tabIndex].height);
g.setColor(Color.BLUE);
g.drawRect(rects[tabIndex].x, rects[tabIndex].y,
rects[tabIndex].width, rects[tabIndex].height);
g.setColor(savedColor);
}
}
}
回答1:
Correct way would be to implement Custom Look & Feel only. But if you want to play with XxxTabbedPaneUI
, then maybe this post can help you with that.
for Nimbus will be better to check aephyr code depot
回答2:
First (partial) solution.
I've located the "positioning" code.
It is the method calculateTabRects
in TabbedPaneLayout
, an inner class of BasicTabbedPaneUI. The method is extremely complex, but the good new is that the part that "raises in front" the tab is well commented and insulated in its own overridable method! It is padSelectedTab
.
Create a class that does nothing instead of raising the component is as simple as:
protected class MyTabbedPaneLayout extends TabbedPaneLayout { @Override protected void padSelectedTab(int tabPlacement, int selectedIndex) { //do nothing! //super.padSelectedTab(tabPlacement, selectedIndex); } }
Notice that it has to be an inner class of MyTabbedPane. It has to be instantiated by overriding MyTabbedPane.createLayoutManager:
@Override
protected LayoutManager createLayoutManager() {
//return super.createLayoutManager();
return new MyTabbedPaneLayout();
}
Very easy and actually working... except for a case.
The createLayoutManager instantiates TabbedPaneLayout if the tabLayoutPolicy is WRAP_TAB_LAYOUT, but instantiates TabbedPanelScrollLayout if tabLayoutPolicy is SCROLL_TAB_LAYOUT. The latter has private and not protected access, so it is not possible subclass it!
My createLayoutManager implmentation looses scrollable behavior.
回答3:
You can override paintContentBorderTopEdge in MyTabbedPaneUI so that it doesn't think any of the tabs are selected. This is not a pretty solution, but hacking UI classes rarely lends itself to one in my experience :)
@Override
protected void paintContentBorderTopEdge(Graphics g, int tabPlacement,
int selectedIndex, int x, int y, int w, int h) {
super.paintContentBorderTopEdge(g, tabPlacement, -1, x, y, w, h);
}
回答4:
You can put Html tags into the first parameter as following :
MyJTabbedPane.addTab("<html><h1 style='padding:20px;'>TEST</h1></html>", new JPanel());
来源:https://stackoverflow.com/questions/7859035/jtabbedpane-customize-tab-look