JTabbedPane "пограничная ошибка" Windows LAF

Я заметил что-то похожее на ошибку при использовании JTabbedPane в Windows Look And Feel (на Windows 10).

Панель с вкладками имеет серую дополнительную рамку справа (2 пикселя) и слева (1 пиксель). Эта граница не видна, если панель с вкладками находится внутри JPanelс цветом фона по умолчанию (rgb: 240, 240, 240), но он отображается на панели с другим цветом фона (см. скриншот ниже).

Я также хочу удалить белую рамку размером 3 пикселя под вкладками.

Снимок экрана, показывающий JTabbedPane по умолчанию

Единственный похожий вопрос, который я нашел на 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;
    }
}

0 ответов

Другие вопросы по тегам