JTabbedPane customize tab look

百般思念 提交于 2019-12-10 02:58:39

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!