JTabbedPane - set default border around tabs..?

2020-02-01 14:44发布

问题:

I am using a JTabbedPane in my application. I have added two tabs which are instances of a custom class "ContentPanel". This extends JPanel and sets the background, border etc etc. Basically it means I dont have to set the properties of each JPanel I want to apply this colour scheme to. I notice that not only does their border appear but another border (which, I think, is blue - at least on my screen) appears around this border, connected to the tab "selectors" themselves (i.e. the buttons you click on to get the appropriate view). I would like to change this border as it just looks odd against a gold / brown colour scheme. Does anyone have any idea how to do this? I have tried JTabbedPane.setBorder(Border b) but that doesnt work. That simply sets a border around the entire thing, including the tab selectors.. not what I want.

Any help with this would be greatly appreciated.

回答1:

These colors are defined in the Look and Feel. If you look at the code for BasicTabbedPaneUI, you will notice that installDefaults() sets a bunch of protected Color instance variables. The keys they are defined against in the L&F are also available here.

protected void installDefaults() {
    LookAndFeel.installColorsAndFont(tabPane, "TabbedPane.background",
                                "TabbedPane.foreground", "TabbedPane.font");     
    highlight = UIManager.getColor("TabbedPane.light");
    lightHighlight = UIManager.getColor("TabbedPane.highlight");
    shadow = UIManager.getColor("TabbedPane.shadow");
    darkShadow = UIManager.getColor("TabbedPane.darkShadow");
    //...
    // a lot more stuff
    //...
}

If you do not want to go as far as define your own L&F, you have the ability to set a custom UI delegate on your tabbed pane:

myTabbedPane.setUI(new BasicTabbedPaneUI() {
   @Override
   protected void installDefaults() {
       super.installDefaults();
       highlight = Color.pink;
       lightHighlight = Color.green;
       shadow = Color.red;
       darkShadow = Color.cyan;
       focus = Color.yellow;
   }
});

you may of course want to change those color settings. As set, you will see which vars are used where.



回答2:

None affecting L&F and JVM run-time system-wide settings code solution.

Create your own tabbed-pane class and nested tabbed-pane-UI class to deal with the issue for a "specific" class of tabbed-pane. The code below is original: (The last answer was 2010, but this may be useful too.)

public class DisplayTabbedPane extends JTabbedPane implements 
     MouseListener, ChangeListener {

    public DisplayTabbedPane() {

        setTabPlacement(SwingConstants.BOTTOM);

        // UIManager.put("TabbedPane.contentBorderInsets", new Insets(0, 0, 0, 0)); 
        // works but is a JVM system wide change rather than a specific change
        NoInsetTabbedPaneUI ui = new NoInsetTabbedPaneUI();

        // this will build the L&F settings for various tabbed UI components.
        setUI( ui );

        // override the content border insets to remove the tabbed-pane
        // blue border around the pane
        ui.overrideContentBorderInsetsOfUI();

    }

    /**
     * Class to modify the UI layout of tabbed-pane which we wish to override
     * in some way. This modification only applies to objects of this class.
     * Doing UIManager.put("TabbedPane.contentBorderInsets", new Insets(0, 0, 0, 0)); 
     * would affect all tabbed-panes in the JVM run-time.
     * 
     * This is free to use, no copyright but is "AS IS".
     */
    class NoInsetTabbedPaneUI extends MetalTabbedPaneUI {
        /**
         * Create tabbed-pane-UI object to allow fine control of the
         * L&F of this specific object.
         */
        NoInsetTabbedPaneUI(){
            super();
        }
        /**
         * Override the content border insets of the UI which represent
         * the L&F of the border around the pane. In this case only care
         * about having a bottom inset.
         */
        public void overrideContentBorderInsetsOfUI(){
            this.contentBorderInsets.top = 0;
            this.contentBorderInsets.left = 0;
            this.contentBorderInsets.right = 0;
            this.contentBorderInsets.bottom = 2;        
        }
    }
    ........

}


回答3:

Change Look And Feel with "UIManager"

            UIManager.getLookAndFeelDefaults().put("TabbedPane:TabbedPaneTab[Enabled].backgroundPainter", new BackgroundPainter(Color.white));
            UIManager.getLookAndFeelDefaults().put("TabbedPane:TabbedPaneTab[Enabled+MouseOver].backgroundPainter", new BackgroundPainter(Color.white));
            UIManager.getLookAndFeelDefaults().put("TabbedPane:TabbedPaneTab[Enabled+Pressed].backgroundPainter", new BackgroundPainter(Color.white));
            UIManager.getLookAndFeelDefaults().put("TabbedPane:TabbedPaneTab[Focused+MouseOver+Selected].backgroundPainter", new BackgroundPainter(Color.white));
            UIManager.getLookAndFeelDefaults().put("TabbedPane:TabbedPaneTab[Focused+Pressed+Selected].backgroundPainter", new BackgroundPainter(Color.white));
            UIManager.getLookAndFeelDefaults().put("TabbedPane:TabbedPaneTab[Focused+Selected].backgroundPainter", new BackgroundPainter(Color.GRAY));
            UIManager.getLookAndFeelDefaults().put("TabbedPane:TabbedPaneTab[MouseOver+Selected].backgroundPainter", new BackgroundPainter(Color.white));
            UIManager.getLookAndFeelDefaults().put("TabbedPane:TabbedPaneTab[Pressed+Selected].backgroundPainter", new BackgroundPainter(Color.white));
            UIManager.getLookAndFeelDefaults().put("TabbedPane:TabbedPaneTab[Selected].backgroundPainter", new BackgroundPainter(Color.white));

BackgroundPainter class

public class BackgroundPainter implements Painter<JComponent> {

private Color color = null;

BackgroundPainter(Color c) {
    color = c;
}

@Override
public void paint(Graphics2D g, JComponent object, int width, int height) {
    if (color != null) {
        g.setColor(color);
        g.fillRect(0, 0, width - 1, height - 1);
    }
}

}