Java 摆动右边框不适用于 Microsoft Windows

Java Swing right border not working on Microsoft Windows

我无法让标准 BorderFactory.createEmptyBorder 在 Java Swing 中正常工作。

我用一个简单的 Java 应用程序进行了尝试,该应用程序创建了一个 Spinner View 并在其周围声明了一个空边框。除了微调器视图的右侧外,边框无处不在。但这只发生在 Windows,在 OSX 它按预期工作。

澄清边框的使用:在我的实际应用程序中,我在微调器的外部有一个可见的边框,然后我想将文本居中放置在里面。我发现 createCompoundBorder 属性 对此非常有用。

import javax.swing.*;
import java.awt.*;
import javax.swing.border.Border;

class HelloWorldSwing {
    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel(
                UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {}
        
        Runnable guiCreator = new Runnable() {
            public void run() {
                JFrame fenster = new JFrame("Hallo Welt mit Swing");
                fenster.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                SpinnerNumberModel model = new SpinnerNumberModel(1,1,9,1);
                JSpinner spinner = new JSpinner(model);
                
                JFormattedTextField textField = ((JSpinner.DefaultEditor)spinner.getEditor()).getTextField();
                textField.setOpaque(true);
                // textField.setBackground(Color.);
                
                spinner.setBorder(BorderFactory.createEmptyBorder(50, 100, 50, 100));
                
                spinner.setUI(new javax.swing.plaf.basic.BasicSpinnerUI() {
                    protected Component createNextButton() {
                        Component c = new JButton();
                        c.setPreferredSize(new Dimension(0, 0));
                        c.setFocusable(false);
                        return c;
                    }

                    protected Component createPreviousButton() {
                        Component c = new JButton();
                        c.setPreferredSize(new Dimension(0, 0));
                        c.setFocusable(false);
                        return c;
                    }
                });
                spinner.setBackground(Color.LIGHT_GRAY);
                fenster.add(spinner);

                fenster.setSize(300, 200);
                fenster.setVisible(true);
            }
        };

        SwingUtilities.invokeLater(guiCreator);
    }
}

= 我不想找到一个解决方案来实现一个 UI 元素。这将是一个简单易行的解决方案(感谢 Andrew Thompson)。原因是我遇到这个错误只是一个小项目。在小型项目中,我最想要的是干净且美观的代码,这意味着通过尝试修复损坏的代码而不是通过解决方法来修复此类错误。

看起来 JSpinner 正在使用自定义布局管理器并且没有正确处理边框。

我修改了您的代码,使按钮的边框右边缘宽度减 1。我猜布局管理器在文本字段边缘和按钮之间留下了 1 像素的间隙。

似乎可以在 Windows 上运行,但它可能会搞砸 OSX?

import javax.swing.*;
import java.awt.*;
import javax.swing.border.Border;

class HelloWorldSwing {
    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel(
                UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {}

        Runnable guiCreator = new Runnable() {
            public void run() {
                JFrame fenster = new JFrame("Hallo Welt mit Swing");
                fenster.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                SpinnerNumberModel model = new SpinnerNumberModel(1,1,9,1);
                JSpinner spinner = new JSpinner(model);

                JFormattedTextField textField = ((JSpinner.DefaultEditor)spinner.getEditor()).getTextField();
                textField.setOpaque(true);
                // textField.setBackground(Color.);

                spinner.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 0));

                spinner.setUI(new javax.swing.plaf.basic.BasicSpinnerUI() {
                    protected Component createNextButton() {
                        Component c = new JButton();
                        c.setPreferredSize(new Dimension(9, 0));
                        c.setVisible(false);
                        return c;
                    }

                    protected Component createPreviousButton() {
                        Component c = new JButton();
                        c.setPreferredSize(new Dimension(9, 0));
                         c.setVisible(false);
                        return c;
                    }
                });
                spinner.setBackground(Color.LIGHT_GRAY);
                fenster.setLayout( new FlowLayout() );
                fenster.add(spinner);

                fenster.setSize(300, 200);
                fenster.setVisible(true);
            }
        };

        SwingUtilities.invokeLater(guiCreator);
    }
}

另一个解决方案是不使用 JSpinner。您可以轻松地使用 JTextField 并为 Up/Down 箭头编写自定义操作。多一点工作,但它适用于所有平台。

此外,由于您似乎担心创建额外的组件,因此在这方面效率会高得多。 JSpinner 本身是一个复杂的组件,而 JFormattedTextField 比简单的 JTextField 复杂得多。