Controlling Color in Java Tabbed Pane

2019-01-24 14:31发布

问题:

I have been going nuts trying to figure this out.

I am trying to elimenate a light blue background that appears in a JTabbedPane. I've tried everything and nothing seems to work.

Below is my code. If you run it, it will show the tab, when selected with a light blue background and a thing blue border at the top. I want to control this color. But how?

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.plaf.ColorUIResource;
public class Main extends JFrame {
  JTabbedPane tab=new JTabbedPane();
  public Main() {
     setSize(300,300);
     setTitle("Test Tab pane");
     tab.add("First",new myPanel("First"));
     tab.add("Second",new myPanel("Second"));
     tab.add("Third",new myPanel("Third"));
     tab.add("Fourth",new myPanel("Fourth"));
     tab.addChangeListener(new ChangeTab());
     getContentPane().add(tab,BorderLayout.CENTER);
     setVisible(true);
     for(int i=0;i<tab.getTabCount();i++){
          if(i != tab.getSelectedIndex())
            tab.setBackgroundAt(i,Color.orange);
            tab.setForeground(Color.BLACK);
     }
     tab.setOpaque(true);
     UIManager.put("TabbedPane.contentAreaColor ",ColorUIResource.GREEN);
     UIManager.put("TabbedPane.selected",ColorUIResource.GREEN);
     UIManager.put("TabbedPane.background",ColorUIResource.GREEN);
     UIManager.put("TabbedPane.shadow",ColorUIResource.GREEN);
  }

  public static void main(String[] args) {
    Main main = new Main();
  }

  class ChangeTab implements ChangeListener{
    public void stateChanged(ChangeEvent e){
        tab.validate();
        System.out.println(tab.getSelectedIndex());
        for(int i=0;i<tab.getTabCount();i++){
          if(i != tab.getSelectedIndex())
            tab.setBackgroundAt(i,Color.orange);
        }

    }
  }

  class myPanel extends JPanel{
    public myPanel(String str){
       add(new JLabel(str));
    }
  }

}

回答1:

I used your example code, and what worked for me was moving the calls to UIManager.put() to a point where they would be executed before the JTabbedPane constructor was executed.

public class Main extends JFrame {
    JTabbedPane tab;

    public Main() {
       // ... other stuff
       UIManager.put("TabbedPane.contentAreaColor ",ColorUIResource.GREEN);
       UIManager.put("TabbedPane.selected",ColorUIResource.GREEN);
       UIManager.put("TabbedPane.background",ColorUIResource.GREEN);
       UIManager.put("TabbedPane.shadow",ColorUIResource.GREEN);

       // now construct the tabbed pane
       tab=new JTabbedPane();

       // ... other stuff
 }

There's also some other properties available (for the Metal L&F, at least):

UIManager.put("TabbedPane.borderColor", Color.RED);
UIManager.put("TabbedPane.darkShadow", ColorUIResource.RED);
UIManager.put("TabbedPane.light", ColorUIResource.RED);
UIManager.put("TabbedPane.highlight", ColorUIResource.RED);
UIManager.put("TabbedPane.focus", ColorUIResource.RED);
UIManager.put("TabbedPane.unselectedBackground", ColorUIResource.RED);
UIManager.put("TabbedPane.selectHighlight", ColorUIResource.RED);
UIManager.put("TabbedPane.tabAreaBackground", ColorUIResource.RED);
UIManager.put("TabbedPane.borderHightlightColor", ColorUIResource.RED);

These let you control most of the colours in the tab area.

I found with these settings there was still a very small blue-ish grey border around the content. I have searched for how to set this colour to no avail. The only solution I could find to get rid of this was:

UIManager.put("TabbedPane.contentBorderInsets", new Insets(0, 0, 0, 0));

Which is a sub-optimal solution.



回答2:

Check the results with these values.

UIManager.put("TabbedPane.contentAreaColor", Color.GREEN);
UIManager.put("TabbedPane.light", ColorUIResource.GREEN);
UIManager.put("TabbedPane.highlight", ColorUIResource.GREEN);
UIManager.put("TabbedPane.shadow", ColorUIResource.GREEN);
UIManager.put("TabbedPane.darkShadow", ColorUIResource.GREEN);
UIManager.put("TabbedPane.selected", ColorUIResource.GREEN);
UIManager.put("TabbedPane.borderHightlightColor", ColorUIResource.GREEN);

As you can see, the only way, to get the dark border on top of the panel the color you want is to set "borderHightlightColor" to the desired Color. Unfortunately, this has the side effects that can be seen (green border around all tabs). And still, there is this gray line between the green ones that comes from the background.

I think the only real solution to this is to override your MetalTabbedPaneUI. If you only set contentAreaColor and do empty overrides for the methods

paintContentBorderTopEdge(g, tabPlacement, selectedIndex, x, y, w, h);
paintContentBorderLeftEdge(g, tabPlacement, selectedIndex, x, y, w, h); 
paintContentBorderBottomEdge(g, tabPlacement, selectedIndex, x, y, w, h);
paintContentBorderRightEdge(g, tabPlacement, selectedIndex, x, y, w, h); 

the result should be near the one I suspect you want to get.



回答3:

Attempt 2: I fixed my border problem and changed look and feel manager. This still is not exactly what you are looking for though..

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 
import javax.swing.event.*; 
import javax.swing.plaf.ColorUIResource; 
public class Main extends JFrame { 
  JTabbedPane tab=new JTabbedPane(); 
  public Main() { 

     setBackground(Color.white);
     setSize(300,300); 
     setTitle("Test Tab pane"); 
     tab.add("First",new myPanel("First")); 
     tab.add("Second",new myPanel("Second")); 
     tab.add("Third",new myPanel("Third")); 
     tab.add("Fourth",new myPanel("Fourth")); 
     tab.addChangeListener(new ChangeTab()); 
     tab.setBackground(Color.white);
     tab.setForeground(Color.black);
     tab.setBorder(BorderFactory.createEmptyBorder());


     getContentPane().add(tab,BorderLayout.CENTER); 
     setVisible(true); 

  } 

  public static void main (String[] args) throws Exception { 
                           UIManager.setLookAndFeel(
            UIManager.getSystemLookAndFeelClassName());
    Main main = new Main(); 
  } 

  class ChangeTab implements ChangeListener{ 
    public void stateChanged(ChangeEvent e){ 
        tab.validate(); 
        System.out.println(tab.getSelectedIndex()); 

    } 
  } 

  class myPanel extends JPanel{ 
    public myPanel(String str){ 
       setBackground(Color.white); 
       setBorder(BorderFactory.createEmptyBorder());
       add(new JLabel(str)); 
    } 
  } 

}