【问题标题】:Java Swing : why must resize frame, so that can show components have addedJava Swing:为什么必须调整框架大小,这样才能显示组件已添加
【发布时间】:2023-12-29 15:29:01
【问题描述】:

我有一个简单的 Swing GUI。 (不仅如此,我写的所有摇摆GUI)。运行它时,除了空白屏幕,它什么都不显示,直到我调整主框架的大小,所以每个组件都重新绘制,我可以显示它们。

这是我的简单代码:

public static void main(String[] args) {
        JFrame frame = new JFrame("JScroll Pane Test");
        frame.setVisible(true);
        frame.setSize(new Dimension(800, 600));

        JTextArea txtNotes = new JTextArea();
        txtNotes.setText("Hello World");
        JScrollPane scrollPane = new JScrollPane(txtNotes);
        frame.add(scrollPane);
}

所以,我的问题是:当我开始这个课程时,框架会出现我添加的所有组件,直到我调整框架大小。

谢谢:)

【问题讨论】:

    标签: java swing layout jframe jscrollpane


    【解决方案1】:
    • JFrame 可见后,不要将组件添加到JFrame (setVisible(true))

    • 在框架上调用setSize() 而不是调用pack()(导致JFrame 调整大小以适应其子组件的首选大小和布局)并让LayoutManager 处理大小并不是很好的做法。

    • 使用EDT(事件调度线程)

    • 如@Gilbert Le Blanc 所说(给他+1)打电话给JFrame#setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE),否则即使JFrame 已关闭,您的EDT/初始线程仍将保持活动状态关闭

    像这样:

    public static void main(String[] args) {
            //Create GUI on EDT Thread
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
    
                      JFrame frame = new JFrame("JScroll Pane Test");
                      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
    
                      JTextArea txtNotes = new JTextArea();
                      txtNotes.setText("Hello World");
                      JScrollPane scrollPane = new JScrollPane(txtNotes);
                      frame.add(scrollPane);//add components
    
                      frame.pack();
                      frame.setVisible(true);//show (after adding components)
                }
            });
    }
    

    【讨论】:

    • 我认为您的意思是“在框架可见后不要向框架添加组件”
    • 非常感谢@DavidKroukamp 的帮助
    【解决方案2】:

    您的简单代码缺少一些东西。

    您必须调用 SwingUtilities 才能将 Swing 组件放在事件分派线程上。

    您应该在JFrame 上拨打setDefaultCloseOperation

    您必须以正确的顺序调用JFrame 方法。 setSizepack方法被调用,然后setVisible方法被最后调用。

    public class SimpleFrame implements Runnable {
    
        @Override
        public void run() {
            JFrame frame = new JFrame("JScroll Pane Test");
    
            JTextArea txtNotes = new JTextArea();
            txtNotes.setText("Hello World");
            JScrollPane scrollPane = new JScrollPane(txtNotes);
            frame.add(scrollPane);
    
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);    
            frame.setSize(new Dimension(800, 600));
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new SimpleFrame());
        }
    
    }
    

    【讨论】: