在JTabbedPane
(在Windows 10上)使用Windows Look And Feel
时,我发现类似于错误的内容。
选项卡式窗格在右侧(2个像素)和左侧(1个像素)上有一个灰色的额外边框。
如果选项卡式窗格位于具有默认背景颜色(rgb:240,240,240)的JPanel
内,则该边框不可见,但它显示在具有不同背景颜色的面板中(如下面的截图)。
我还想删除标签下的3像素白色边框。
我在SO上找到的唯一类似问题是这个问题:JTabbedPane in Windows L&F with unremovable border,但没有一个实际有效的解决方案(见下面的代码)。
事实上,更改TabbedPane.contentBorderInsets
可以轻松删除标签下方的白色边框(通过设置insets.top = -1
),但在尝试删除右边框时会破坏用户界面。
我尝试了使用UIManager.opaque
和UIManager.background
的不同解决方案,并通过手动覆盖isOpaque ()
和getBackground ()
方法,我还尝试设置空Border
,没有任何积极的结果。
我认为我发现了一种应该适用于Windows 10的黑客攻击,覆盖getBorder ()
方法,以便返回具有相同额外边框维度的MatteBorder
和父背景作为边框颜色。
另外,要删除我正在使用的标签下的顶部边框:
setBackground ((Color) UIManager.get ("TabbedPane.highlight"));
表格中的面板。
这是一个screnshot(帖子末尾的代码),显示了我做过的一些尝试,最后一个是我期望的结果:
有没有更好的解决方案来消除那个令人讨厌的边界?我担心UI会因为我现在正在使用的代码而在不同的LAF上崩溃......
我应该创建一个工厂方法来检查当前的LAF是否为“Windows”,如:
if (UIManager.getLookAndFeel ().getName ().equals ("Windows") {
// Create "Custom" JTabbedPane, ovveriding getBorder method and setting panel background ...
}
else {
// Create default JTabbedPane ...
}
先谢谢,这里有我使用过的代码:
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;
}
}