Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.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 JDialog中的组件未显示_Java_Swing_Jdialog - Fatal编程技术网

Java JDialog中的组件未显示

Java JDialog中的组件未显示,java,swing,jdialog,Java,Swing,Jdialog,首先:我知道这个问题似乎被问了几百万次,但其他问题的答案似乎都不适合我 有时,当我在下面的代码中运行Message.popup(String,int)时,文本显示正确,但有时JDialog是空的,就像根本没有添加组件一样 public class Message extends JDialog { private int width; private int height; private JLabel content; public Message(Stri

首先:我知道这个问题似乎被问了几百万次,但其他问题的答案似乎都不适合我

有时,当我在下面的代码中运行
Message.popup(String,int)
时,文本显示正确,但有时JDialog是空的,就像根本没有添加组件一样

public class Message extends JDialog {
    private int width;
    private int height;

    private JLabel content;

    public Message(String _content, int _margin) {
        super();
        this.content = new JLabel(_content);
        content.setFont(new Font("Monospaced", Font.BOLD, 20));
        this.margin = _margin;
        this.width = content.getPreferredSize().width + _margin;
        this.height = content.getPreferredSize().height + _margin;

        createComponents();
        setProperties();
    }

    public static void popup(String _content, int _time) {
      if (SwingUtilities.isEventDispatchThread()) {
        runPopup(_content, _time);
      }
      else {
        SwingUtilities.invokeLater(new Runnable() {
          @Override
          public void run() {
            runPopup(_content, _time);
          }
        });
      }
    }

    private static void runPopup(String _content, int _time) {
      final Message message = new Message(_content);
      new Timer(_time, new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent arg0) {
          message.dispose();
        }
      }).start();
    }

    private void createComponents() {
        setLayout(new BorderLayout());

        Box box = Box.createHorizontalBox();
        box.add(Box.createHorizontalGlue());
        box.add(content, BorderLayout.CENTER);
        box.add(Box.createHorizontalGlue());
        add(box);
    }

    private void setProperties() {
        setSize(width, height);
        setLocation(Coordinator.calculateCenteredWindowLocation(width, height));
        setUndecorated(true);
        setResizable(false);
        setTitle(content.getText());
        setVisible(true);
        update(getGraphics());
    }
}

没有
更新(getGraphics()),帧总是空的,但有了它,它取决于风向。。。(如图所示!)

您确定您的代码正在中执行吗?事实上,如果不是(这就是我所期望的,因为您
睡眠
当前线程,Swing通常不喜欢什么),那么您的帧将难以渲染


为了避免这些典型的Swing线程问题,请查看该类,它为您提供了确保在EDT中运行的方法。此外,您可以使用Swing(注意不要将其与
java.util.Timer
混淆)来重新封装线程,而不是直接休眠线程。

如@Riduidel所述,在事件调度线程或
EDT
上发生任何与Swing相关的事件都很重要。这是因为Swing不是线程安全的。调用
popup()
时,应执行以下操作

if(SwingUtilities.isEventDispatchThread()){
    Message.popup(...);
}
else{
    SwingUtilities.invokeLater(new Runnable(){
        @Override
        public void run(){
            Message.popup(...);
        }
    });
}
SwingUtilities.invokeLater(new Runnable(){
    @Override
    public void run(){
        Message.createAndShowDialog("Content", 5000); // wait 5 seconds before disposing dialog
    }
});
这将确保在
EDT
上创建
JFrame
。另外,从您发布的代码片段来看,
Message
似乎应该有一个私有构造函数。此外,既然您没有进行任何自定义渲染,为什么不直接创建一个
JFrame
成员变量而不是扩展类呢?--对我来说似乎有点多余

无论如何,您也不应该在
EDT
sleep
,因为这将使GUI显示为“冻结”,并阻止其他排队事件的执行。执行长时间运行的任务时,请使用或,如@Riduidel所述。但是,如果您喜欢使用,请使用如上所示的实用程序类将
Runnable
任务发布到
EventQueue
上,以便在
EDT
中执行

编辑

下面是我要做的(是的,它是有效的)

无论在何处调用
createAndShowDialog(…)
,请执行以下操作

if(SwingUtilities.isEventDispatchThread()){
    Message.popup(...);
}
else{
    SwingUtilities.invokeLater(new Runnable(){
        @Override
        public void run(){
            Message.popup(...);
        }
    });
}
SwingUtilities.invokeLater(new Runnable(){
    @Override
    public void run(){
        Message.createAndShowDialog("Content", 5000); // wait 5 seconds before disposing dialog
    }
});
永远不要使用update()方法或getGraphics()方法

调用update()用于AWT NOT Swing


如果您需要进行自定义绘制,则可以覆盖组件的paintComponent()方法,该方法已经可以访问图形对象。

@mre我现在意识到我对Swing一无所知;-)非常感谢所有关于这个问题的信息@奥塔鲁斯,如果你还有麻烦,请告诉我!:)@我还是有麻烦。我照你说的做了,包括计时器,但有时候,它还是不显示。如果有助于理解,当我最小化/还原帧时,显示的文本将消失。您的If(SwingUtilities.isEventDispatchThread())今天为我节省了大量时间@StephaneGrenier,很高兴听到!:)“.有时JFrame是空的”什么JFrame?为了更快地获得更好的帮助,请发布一篇文章(在你研究的数百万个线程中可能已经提到过几千次)。@Andrew对此表示抱歉,我更新了代码,现在它扩展了JDialog而不是JFrame。我的错!已经做出了改变。