Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/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 无法在线程内更新JDialog GUI_Java_Swing_User Interface_Jdialog - Fatal编程技术网

Java 无法在线程内更新JDialog GUI

Java 无法在线程内更新JDialog GUI,java,swing,user-interface,jdialog,Java,Swing,User Interface,Jdialog,请看一下下面的代码 private class EmergencyAlertNotifier implements Runnable, ActionListener { JDialog dialog = new JDialog(); int number=0; JLabel message; JButton yes,no; String messageStr; public Emerge

请看一下下面的代码

private class EmergencyAlertNotifier implements Runnable, ActionListener
    {
        JDialog dialog = new JDialog();
        int number=0;

        JLabel message;
        JButton yes,no;

        String messageStr;

        public EmergencyAlertNotifier()
        {
            dialog.setLayout(new BorderLayout());

            //The JLabel which will display the number of seconds left
            //before alerting emergency services
            message = new JLabel();


             messageStr="number";

            yes = new JButton("OK");
            yes.addActionListener(this);
            no = new JButton("Cancel");
            no.addActionListener(this);

            JPanel btnPanel = new JPanel();
            btnPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
            btnPanel.add(yes);
            btnPanel.add(no);

            dialog.add(message,"Center");
            dialog.add(btnPanel,"South");

            dialog.setTitle("Ready To Notify Emergency Fire Services");
            dialog.setVisible(true);
            dialog.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        }

        @Override
        public void run() 
        {
            for(int i=10;i>0;i--)
            {
                message.setText(messageStr+i+" Sec.");


                try
                {
                    Thread.sleep(1000);
                }
                catch(Exception e)
                {
                    e.printStackTrace();
                }
            }


        }

        @Override
        public void actionPerformed(ActionEvent e) 
        {
            if(e.getSource()==yes)
            {

            }
            else
            {
                dialog.dispose();
            }
        }

    }
线程在上述类之外启动

 new Thread(new EmergencyAlertNotifier()).start();
我正在尝试使用线程中不断变化的数字更新JLabel。但是,JLabel不会出现在GUI中。为什么呢?请帮忙

  • 您的代码中存在一些问题,Swing中的
    一致性

  • 求求你,我无法对此发表评论

  • 直到
    SwingWorker
    将在官方API中实现之前,
    Runnable#Thread
    Workers Thread
    的标准解决方案

  • 生产代码使用
    Runnable#Thread
    而不是
    SwingWorker
    (我不同意API中实现的黑洞)

  • Runnable#Thread
    到Swing GUI的输出需要使用
    invokeLater
    ,对于
    Thread\u-safe
    setText
    append
    ,尤其是Java7与Java6相比也有一些变化)方法

  • 使用
    util.Timer
    进行
    倒计时
    ,而不是
    Thread.sleep()

修改代码,按预期工作

import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class EmergencyAlertNotifier implements Runnable, ActionListener {

    private JDialog dialog = new JDialog();
    private int number = 0;
    private JLabel message;
    private JButton yes, no;
    private String messageStr;
    private boolean runProcess = true;

    public EmergencyAlertNotifier() {
        dialog.setLayout(new GridLayout());
        //The JLabel which will display the number of seconds left
        //before alerting emergency services
        message = new JLabel();
        messageStr = "number";
        yes = new JButton("OK");
        yes.addActionListener(this);
        no = new JButton("Cancel");
        no.addActionListener(this);
        JPanel btnPanel = new JPanel();
        btnPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
        btnPanel.add(yes);
        btnPanel.add(no);
        dialog.add(message, "Center");
        dialog.add(btnPanel, "South");
        dialog.setTitle("Ready To Notify Emergency Fire Services");
        dialog.pack();
        dialog.setVisible(true);
        dialog.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        new Thread(this).start();
    }

    @Override
    public void run() {
        while (runProcess) {
            for (int i = 10; i > 0; i--) {
                message.setText(messageStr + " " + i + " Sec.");
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            runProcess = false;
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == yes) {
        } else {
            dialog.dispose();
        }
    }

    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                EmergencyAlertNotifier ean = new EmergencyAlertNotifier();
            }
        });
    }
}
  • 您的代码中存在一些问题,Swing中的
    一致性

  • 求求你,我无法对此发表评论

  • 直到
    SwingWorker
    将在官方API中实现之前,
    Runnable#Thread
    Workers Thread
    的标准解决方案

  • 生产代码使用
    Runnable#Thread
    而不是
    SwingWorker
    (我不同意API中实现的黑洞)

  • Runnable#Thread
    到Swing GUI的输出需要使用
    invokeLater
    ,对于
    Thread\u-safe
    setText
    append
    ,尤其是Java7与Java6相比也有一些变化)方法

  • 使用
    util.Timer
    进行
    倒计时
    ,而不是
    Thread.sleep()

修改代码,按预期工作

import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class EmergencyAlertNotifier implements Runnable, ActionListener {

    private JDialog dialog = new JDialog();
    private int number = 0;
    private JLabel message;
    private JButton yes, no;
    private String messageStr;
    private boolean runProcess = true;

    public EmergencyAlertNotifier() {
        dialog.setLayout(new GridLayout());
        //The JLabel which will display the number of seconds left
        //before alerting emergency services
        message = new JLabel();
        messageStr = "number";
        yes = new JButton("OK");
        yes.addActionListener(this);
        no = new JButton("Cancel");
        no.addActionListener(this);
        JPanel btnPanel = new JPanel();
        btnPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
        btnPanel.add(yes);
        btnPanel.add(no);
        dialog.add(message, "Center");
        dialog.add(btnPanel, "South");
        dialog.setTitle("Ready To Notify Emergency Fire Services");
        dialog.pack();
        dialog.setVisible(true);
        dialog.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        new Thread(this).start();
    }

    @Override
    public void run() {
        while (runProcess) {
            for (int i = 10; i > 0; i--) {
                message.setText(messageStr + " " + i + " Sec.");
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            runProcess = false;
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == yes) {
        } else {
            dialog.dispose();
        }
    }

    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                EmergencyAlertNotifier ean = new EmergencyAlertNotifier();
            }
        });
    }
}

首先,永远不要从任何线程(事件调度线程除外)创建、修改或与任何UI组件交互,查看更多详细信息。其次,我看不到在哪里启动线程,因此您已经在EDT上下文中执行,这意味着您正在阻止它,阻止更新线程UI@MadProgrammer:谢谢你的回复。请看一下编辑好的,我设法解决了这个问题。谢谢大家的回复:)我建议你使用类似SwingWorker的东西。我能问一下你是怎么做到的吗?这正是我害怕的。你的线程违反了Swing的单线程规则。您应该只从事件调度线程创建/修改/与UI组件交互首先,永远不要从事件调度线程以外的任何线程创建、修改或与UI组件交互,查看更多详细信息。其次,我看不到在哪里启动线程,因此您已经在EDT上下文中执行,这意味着您正在阻止它,阻止更新线程UI@MadProgrammer:谢谢你的回复。请看一下编辑好的,我设法解决了这个问题。谢谢大家的回复:)我建议你使用类似SwingWorker的东西。我能问一下你是怎么做到的吗?这正是我害怕的。你的线程违反了Swing的单线程规则。您应该只从事件调度线程创建/修改UI组件,并与之交互。显示了使用
javax.swing.Timer的替代方法。感谢您的回复:)。我想你是对的。我的线程没有关闭,甚至GUI也没有了!啊,啊,啊!我正在使用TimerTanks获取建议mKorbel:)显示了使用
javax.swing.Timer
的替代方法。感谢您的回复:)。我想你是对的。我的线程没有关闭,甚至GUI也没有了!啊,啊,啊!我正和时间一起移动,希望得到建议(mKorbel:)