我想在JTabbedPane中自定义选项卡的外观
我想从最简单和最简洁的行为开始:没有边界,纯色
问题是仍然存在不稳定性:标签略有重叠边缘。
您会看到,自从选择了第二个标签后,它就会“脱颖而出”。 这是通过略微的边缘重叠来实现的。 是否有(非常棘手的)方法来禁用此行为?
简单,可测试(只是修复导入)代码:
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);
}
}
}
答案 0 :(得分:4)
答案 1 :(得分:2)
第一(部分)解决方案。
我找到了“定位”代码。
它是calculateTabRects
中的方法TabbedPaneLayout
,是BasicTabbedPaneUI的内部类。这种方法非常复杂,但好的新方法是“在前面提升”标签的部分在其自己的可覆盖方法中得到很好的评论和绝缘!它是padSelectedTab
创建一个不执行任何操作而不是提升组件的类就像这样简单:
protected class MyTabbedPaneLayout extends TabbedPaneLayout { @Override protected void padSelectedTab(int tabPlacement, int selectedIndex) { //do nothing! //super.padSelectedTab(tabPlacement, selectedIndex); } }
请注意,它必须是MyTabbedPane的内部类。它必须通过重写MyTabbedPane.createLayoutManager:
来实例化@Override
protected LayoutManager createLayoutManager() {
//return super.createLayoutManager();
return new MyTabbedPaneLayout();
}
非常容易并且实际工作......除了案例。
如果tabLayoutPolicy是WRAP_TAB_LAYOUT,则createLayoutManager实例化TabbedPaneLayout,但如果tabLayoutPolicy是SCROLL_TAB_LAYOUT,则实例化TabbedPanelScrollLayout。后者有私有而且没有受保护的访问权限,因此不可能将其子类化!
我的createLayoutManager implmentation失去了可滚动的行为。
答案 2 :(得分:1)
您可以在MyTabbedPaneUI中覆盖paintContentBorderTopEdge,以便它不会认为选择了任何选项卡。这不是一个很好的解决方案,但是根据我的经验,黑客用户界面很少适合用于其中一个:)
@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);
}
答案 3 :(得分:1)
您可以将Html标记放入第一个参数中,如下所示:
MyJTabbedPane.addTab("<html><h1 style='padding:20px;'>TEST</h1></html>", new JPanel());