I noticed something similar to a bug when using JTabbedPane
in Windows Look And Feel
(on Windows 10).
The tabbed pane has a grey extra border on the right (2 pixels) and on the left (1 pixel).
That border is not visible if the tabbed pane is inside a JPanel
with the default background color (rgb: 240, 240, 240), but it shows up in a panel with a different background color (look screenshot below).
I also want to remove the 3 pixels white border under the tabs.
The only similar question i found on SO is this one: JTabbedPane in Windows L&F with unremovable border, but there isn't a solution which actually works (see code below).
In fact, changing TabbedPane.contentBorderInsets
could easily remove the white border below the tabs (by setting insets.top = -1
), but it breaks the UI when trying to remove the right border.
I tried different solutions, both using UIManager.opaque
and UIManager.background
and by manually overriding isOpaque ()
and getBackground ()
methods, i also tried to set a null Border
, without any positive result.
I think i found a kind of hack which should work on Windows 10, overriding getBorder ()
method in order to return a MatteBorder
with the same extra border dimension and the parent background as border color.
Also, to remove the top border under the tabs i'm using:
setBackground ((Color) UIManager.get ("TabbedPane.highlight"));
for the panels inside the tabs.
This is a screnshot (code at the end of the post) which shows some tries i did, the last one is the result which i expected to have:
Is there any better solution to remove that nasty border? I'm afraid the UI could break down on different LAFs with the code i'm using right now ...
Should i create a factory method to check if the current LAF is "Windows", something like:
if (UIManager.getLookAndFeel ().getName ().equals ("Windows") {
// Create "Custom" JTabbedPane, ovveriding getBorder method and setting panel background ...
}
else {
// Create default JTabbedPane ...
}
Thanks in advance, here there is the code i used:
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
public class TabbedPaneTest
{
public static void main (String [] a) {
SwingUtilities.invokeLater (new Runnable () {
@Override public void run () {
try {
UIManager.put ("TabbedPane.focus", new Color (0, 0, 0, 0));
UIManager.setLookAndFeel (UIManager.getSystemLookAndFeelClassName ());
createAndShowGUI ();
}
catch (Exception e) {
e.printStackTrace ();
}
}
});
}
private static void createAndShowGUI () {
JFrame frame = new JFrame ("Tabbed Pane Test");
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
frame.setContentPane (new MainPanel ());
frame.pack ();
frame.setLocationRelativeTo (null);
frame.setVisible (true);
}
}
class MainPanel extends JPanel
{
public MainPanel () {
String [] labels = {"Default", "Panel background", "Content border insets", "Content opaque", "Matte border/Panel background"};
Color [] backgrounds = {(Color) UIManager.get ("Panel.background"), Color.WHITE, Color.BLACK, Color.RED};
setLayout (new GridLayout (backgrounds.length + 1, labels.length, 20, 10));
for (int i = 0; i < labels.length; i ++) add (new JLabel (labels [i], JLabel.CENTER));
for (int i = 0; i < backgrounds.length; i ++) {
for (int j = 0; j < labels.length; j++) {
JPanel panel = new JPanel (new FlowLayout (FlowLayout.CENTER, 20, 10));
panel.add (createTabbedPane (j + 1));
panel.setBackground (backgrounds [i]);
add (panel);
}
}
setBorder (new EmptyBorder (5, 5, 5, 5));
}
private JTabbedPane createTabbedPane (int i) {
JTabbedPane tabbedPane;
if (i == 3) {
Insets oldValue = (Insets) UIManager.get ("TabbedPane.contentBorderInsets");
UIManager.put ("TabbedPane.contentBorderInsets", new Insets (-1, 2, 2, 2));
tabbedPane = new JTabbedPane ();
UIManager.put ("TabbedPane.contentBorderInsets", oldValue);
}
else if (i == 4) {
UIManager.put ("TabbedPane.contentOpaque", false);
tabbedPane = new JTabbedPane ();
UIManager.put ("TabbedPane.contentOpaque", true);
}
else if (i == 5) {
tabbedPane = new JTabbedPane () {
@Override public Border getBorder () {
Container parent = getParent ();
if (parent == null) return super.getBorder ();
return new MatteBorder (0, 0, 1, 2, parent.getBackground ());
}
};
}
else tabbedPane = new JTabbedPane ();
JPanel panel1 = new JPanel (new FlowLayout (FlowLayout.LEFT, 80, 50));
JPanel panel2 = new JPanel (new FlowLayout (FlowLayout.LEFT, 80, 50));
if (i == 2 || i == 5) {
Color highlightColor = (Color) UIManager.get ("TabbedPane.highlight");
panel1.setBackground (highlightColor);
panel2.setBackground (highlightColor);
}
tabbedPane.add ("Tab 1", panel1);
tabbedPane.add ("Tab 2", panel2);
return tabbedPane;
}
}