Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/385.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 当我将setVisible()函数放在函数的末尾时,将其放在函数的开头是否会有所不同?_Java_Jframe - Fatal编程技术网

Java 当我将setVisible()函数放在函数的末尾时,将其放在函数的开头是否会有所不同?

Java 当我将setVisible()函数放在函数的末尾时,将其放在函数的开头是否会有所不同?,java,jframe,Java,Jframe,我刚刚接触Java GUI编程,我遇到了一个问题,当我将setVisible()函数放在构造函数调用的函数的开头时,面板中的组件丢失了,但当它放在末尾时,它工作得很好。见下面的代码: public static void main(String[] args) { new MainClass(); } public MainClass() { setFrame(); } private void setFrame() { JFrame frame = new JF

我刚刚接触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()方法后添加它们的

Componet的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);

}

}

无法显示组件,因为在调用框架的setVisible()方法后添加了组件

Componet的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);

}

}

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

添加所有组件后,应在末尾调用
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
。这是真的。更重要的是:通常不应直接创建扩展JFrame的类。(在某些(罕见的!)情况下,这是合适的,但一般的指导原则应该是不要扩展
JFrame

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

添加所有组件后,应在末尾调用
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
。这是真的。更重要的是:通常不应直接创建扩展JFrame的类。(在某些(罕见的!)情况下,这是合适的,但一般的指导原则应该是不要扩展
JFrame

当您尝试时,您是否注意到任何差异?您应该在添加所有元素后在末尾调用setvisible您根本不应该从构造函数中调用它@talex这个问题是通往“为我工作”-bug…的艰难道路上的第一步。当你尝试时,你注意到任何差异吗?你应该在最后调用setvisible,在添加所有元素之后,你根本不应该从构造函数中调用它@talex这个问题是通往“为我工作”之路的第一步-臭虫。。。