Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.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 正在等待组件的IsDisployable_Java_Swing_Invokelater - Fatal编程技术网

Java 正在等待组件的IsDisployable

Java 正在等待组件的IsDisployable,java,swing,invokelater,Java,Swing,Invokelater,在测试游戏时,我有时会在组件不可显示时引发异常。我在isDisplayable()上添加了一个等待循环 似乎我的游戏需要几百毫秒才能显示出来 这是处理这个问题的明智方法吗 我正在测试通过套接字与服务器对话的游戏客户端 谢谢 编辑1:谢谢你的评论。我发现在gui完成构建和初始化之前,我正在将gui的中介(观察者)添加到模型(可观察者)中。更糟糕的是,我正在初始化一个面板,调用createImage返回null并抛出 import java.awt.*; import javax.swing.*;

在测试游戏时,我有时会在组件不可显示时引发异常。我在isDisplayable()上添加了一个等待循环

似乎我的游戏需要几百毫秒才能显示出来

这是处理这个问题的明智方法吗

我正在测试通过套接字与服务器对话的游戏客户端

谢谢

编辑1:谢谢你的评论。我发现在gui完成构建和初始化之前,我正在将gui的中介(观察者)添加到模型(可观察者)中。更糟糕的是,我正在初始化一个面板,调用createImage返回null并抛出

import java.awt.*;
import javax.swing.*;
public class WaitForFrameToBeVisible {
    JFrame frame=new JFrame("FrameDemo");
    private void createAndShowGUI() {
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JLabel emptyLabel=new JLabel("");
        emptyLabel.setPreferredSize(new Dimension(175,100));
        frame.getContentPane().add(emptyLabel,BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);
    }
    void run() throws Exception {
        System.out.println("waiting for frame to be displayable");
        long t0=System.nanoTime();
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
        while (!frame.isDisplayable())
            Thread.sleep(1);
        long dt=System.nanoTime()-t0;
        System.out.println("waited "+dt/1_000_000.+" ms. for frame to be displayable");
    }
    public static void main(String[] args) throws Exception {
        new WaitForFrameToBeVisible().run();
    }
}

您不需要使用
isDisplayable()
。您可以使用
invokeAndWait(…)
来执行以下操作:

 javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
     public void run() {
         createAndShowGUI();
     }
 });
 // control will reach here when the GUI will be created
请注意,通过这种方式,您实际上并不是在检查框架是否可见,而是在检查createAndShowGUI()是否已完成其工作

另一件事是您不应该在循环中调用
isDisplayable()
或任何类似的函数。这将消耗不必要的处理速度。而是使用wait notify


但就您的案例而言,使用
WindowListener
是一个非常好的主意,正如在评论中所建议的那样。

我会“猜测”您在Swing API构建和验证UI和尝试更新UI之间存在线程争用情况,但这很难说。不,就我个人而言,这不是解决问题的明智方法,Swing不是线程安全的,所以你冒着不同比赛条件的风险。我想尝试的是使用<代码> Windows WistListor ,并注意可见性的变化,但是您必须进一步测试100%个步骤,为什么在一个不是Swing /AWT线程的线程中做Swing的东西?也许还是等着吧?我正在测试通过套接字与服务器对话的游戏客户端。@RayTayek不太可能,组件“可显示”(通过帧的
pack
setVisible
)之前可以修改
层次结构。实际上,很难保证组件是可显示的,因为这在很大程度上取决于底层操作系统的实现。通常,我使用
WindowListener
,当窗口可见时,使用
invokeLater
只是为了“更”确定我可以对组件进行所需的更改。记住,Swing不是线程安全的,切勿尝试更改或检查EDT上下文外部组件的状态等待
invokeAndWait
返回不会保证帧可见或可显示,因为该过程可能会生成其他事件,这些事件会在
createAndShowGUI
完成后添加到EDT(并且
invokeAndWait
已返回)-这只是另一个竞争条件我想我在编写代码后解释过。但是,你甚至不应该费心提及它,它并没有真正解决问题,并引入了另一个可能的竞争条件。就像你永远不应该在EDT上下文之外修改组件一样,你永远不应该查询组件的状态我也是,因为这只是一个诱人的比赛条件:P