当我把setVisible()函数放在函数的末尾时,它在函数的开头是否不同?

  • 本文关键字:函数 开头 是否 setVisible java jframe
  • 更新时间 :
  • 英文 :


我只是新的Java GUI编程,我有一个问题,我的面板内的组件是缺失的,当我把setVisible()函数在由构造函数调用的函数的开始,但它的工作很好,当它是在结束。参见下面的代码:

public static void main(String[] args) 
{
    new MainClass();
}
public MainClass()
{ 
    setFrame();
}
private void setFrame()
{
    JFrame frame = new JFrame();
    frame.setSize(400,400);
    frame.setResizable(false);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   // Some area where the object of my components inside the panel is created and initialized.
   // If I just place a label and a button, it will appear on the panel. However if I add the JTextArea, all the components in my panel is gone. Just like the code below.
    textArea1 = new JTextArea(20,34);
    textArea1.setWrapStyleWord(true);
    textArea1.setLineWrap(true);
    JScrollPane scroll = 
            new JScrollPane(textArea1, 
                    JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 
                    JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
    panel.add(scroll);
    frame.add(panel);
    // Works fine when setVisible(true); it placed here.
}

setVisible()函数放在方法的开头或结尾可能会出现什么问题?

正如在评论和其他答案中已经指出的:

请在添加完所有组件后,在最后调用setVisible(true)


这并没有直接回答你的问题。你的问题的答案是:是的,它有区别。如果您在添加所有组件之前调用setVisible,它可能工作,在某些情况下,与某些程序,在某些pc上,使用某些Java版本,使用某些操作系统-但是您总是必须预期在某些情况下它可能不像预期的那样工作。

你可以在stackoverflow和其他地方找到许多相关的问题。这些问题的常见症状是某些组件不能正确显示,然后在调整窗口大小时突然出现。(调整窗口大小基本上会触发布局和重新绘制)。


当您违反Swing的线程规则时,意外行为的可能性会增加。而且,在某种意义上,您确实违反了Swing的线程规则:您应该始终在事件分派线程上创建GUI !

import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class SomeSwingGUI
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                createAndShowGUI();
            }
        });
    }
    // This method may (and will) only be called
    // on the Event Dispatch Thread
    private static void createAndShowGUI()
    {
        JFrame f = new JFrame();
        // Add your components here        
        f.setVisible(true); // Do this last
    }
}

顺便说一句:Timothy Truckle在注释中指出,不应该从构造函数中调用setVisible。这是真的。更重要的是:您通常应该而不是直接创建extends JFrame。(在某些(罕见的)情况下,这是合适的,但一般的指导方针应该是而不是扩展JFrame)

组件不能显示,因为您在调用Frame的setVisible()方法后添加了它们。

组件的add()方法更改布局相关信息,并使组件层次结构失效。如果已经显示了容器,那么之后必须验证层次结构,以便显示添加的组件,就像这里指出的那样.

因此,为了显示项目,您应该调用框架的revalidate()方法,或者在添加所有组件后调用setVisible()。

除非没有特殊需要,否则你应该在添加完其他组件后调用setVisible()。

public class TestMain extends JFrame {
public static void main(String[] args) {
   JFrame test = new TestMain();
   //if the setVisible() is called too early, you have to revalidate
   test.revalidate();
}
public TestMain() { 
    setFrame();
}
private void setFrame() {
    setSize(400,400);
    setResizable(false);
    setLayout(new FlowLayout());
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JPanel panel = new JPanel(new FlowLayout());
    setVisible(true);
    JTextArea textArea1 = new JTextArea(25,15);
    textArea1.setWrapStyleWord(true);
    textArea1.setLineWrap(true);
    panel.add(textArea1);
    JScrollPane scroll = 
            new JScrollPane(panel, 
                    JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 
                    JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
    // this method invalidates the component hierarchy.
    getContentPane().add(scroll);
}

}

最新更新