JTabbedPane "пограничная ошибка" Windows LAF
Я заметил что-то похожее на ошибку при использовании JTabbedPane
в Windows Look And Feel
(на Windows 10).
Панель с вкладками имеет серую дополнительную рамку справа (2 пикселя) и слева (1 пиксель). Эта граница не видна, если панель с вкладками находится внутри JPanel
с цветом фона по умолчанию (rgb: 240, 240, 240), но он отображается на панели с другим цветом фона (см. скриншот ниже).
Я также хочу удалить белую рамку размером 3 пикселя под вкладками.
Единственный похожий вопрос, который я нашел на SO, - это: JTabbedPane в Windows L&F с несъемной границей, но не существует решения, которое действительно работает (см. Код ниже).
На самом деле меняется TabbedPane.contentBorderInsets
можно легко удалить белую рамку под вкладками (установив insets.top = -1
), но он нарушает интерфейс при попытке удалить правую границу.
Я пробовал разные решения, оба с использованием UIManager.opaque
а также UIManager.background
и вручную переопределяя isOpaque ()
а также getBackground ()
методы, я также пытался установить ноль Border
без какого-либо положительного результата.
Я думаю, что нашел какой-то взлом, который должен работать на Windows 10, переопределяя getBorder ()
метод для того, чтобы вернуть MatteBorder
с тем же дополнительным измерением границы и родительским фоном, что и цвет границы. Кроме того, чтобы удалить верхнюю границу под вкладками, я использую:
setBackground ((Color) UIManager.get ("TabbedPane.highlight"));
для панелей внутри вкладок.
Это скриншот (код в конце поста), который показывает некоторые попытки, которые я сделал, последняя - результат, который я ожидал получить:
Есть ли лучшее решение, чтобы убрать эту неприятную границу? Я боюсь, что пользовательский интерфейс может сломаться на разных 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;
}
}