Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/370.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 如何让EDT等待后台线程?_Java_Multithreading_Backgroundworker_Swingworker_Event Dispatch Thread - Fatal编程技术网

Java 如何让EDT等待后台线程?

Java 如何让EDT等待后台线程?,java,multithreading,backgroundworker,swingworker,event-dispatch-thread,Java,Multithreading,Backgroundworker,Swingworker,Event Dispatch Thread,基于此,我正在尝试更新我的GUI。我的问题是,GUI更新在EDT中的一个新线程中被调用,这导致了我的许多不同的失败 下面的代码已准备好运行,它是me GUI更新的一个示例,是一个简单的倒计时: import java.awt.Component; import java.awt.Container; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import j

基于此,我正在尝试更新我的GUI。我的问题是,GUI更新在EDT中的一个新线程中被调用,这导致了我的许多不同的失败

下面的代码已准备好运行,它是me GUI更新的一个示例,是一个简单的倒计时:

import java.awt.Component;
import java.awt.Container;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

public class Chronometer2 {

int COUNT = 5000;


CountTask countTask;


    private static final Insets INSETS = new Insets(1, 1, 1, 1);


    public Chronometer2(){

        (countTask= new CountTask()).execute();

    }


    private static void addComponent(Container container, Component component, int gridx, int gridy,
            int gridwidth, int gridheight, int anchor, int fill) {

          GridBagConstraints gbc = new GridBagConstraints(gridx, gridy, gridwidth, gridheight, 1.0, 1.0,
        anchor, fill, INSETS, 0, 0);

          container.add(component, gbc);
          }

    public int returnCount(){

        System.out.println("My count: " + COUNT);
        return COUNT;
    }

       public void decreaseTime() {
            COUNT--;
        }

        public int getTime() {
            return COUNT;
        }


        private class CountTask extends SwingWorker<Void, Chronometer2>{

            @Override
            protected Void doInBackground() throws Exception {
                // TODO Auto-generated method stub



                final JFrame messageFrame = new JFrame();
                final JLabel message = new JLabel("Next query in " + COUNT/1000 + " seconds.");
                messageFrame.setLayout(new GridBagLayout());

                messageFrame.setTitle("Warning");
                messageFrame.setSize(500,100);
                messageFrame.setLocationRelativeTo(null);
                addComponent(messageFrame, message, 0, 0, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.CENTER);
                messageFrame.setVisible(true);

                final Timer timer = new Timer();
                 timer.schedule(new TimerTask() {

                     @Override
                     public void run() {


                             decreaseTime();
                                    message.setText("Preventing connection block. Next query in " + COUNT/1000 + " seconds.");

                                    if(getTime()==0){
                                        messageFrame.dispose();
                                        timer.cancel();
                                    }

                                }
                 }, 1, 1);
                return null;
            }

        }




public static void main(String[] args){
       SwingUtilities.invokeLater(new Runnable() {
           public void run() {
               new Chronometer2();
           }
       });
}

}
我还尝试使用
wait()
notifiy()
和计时器任务来处理这个问题,但问题是相同的;下面是准备运行的其他代码:

import java.awt.Component;
import java.awt.Container;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JFrame;
import javax.swing.JLabel;

public class Chronometer {


    private static final Insets INSETS = new Insets(1, 1, 1, 1);

    private int TIMER = 3000;

public Chronometer(){

    double timeToNext = System.currentTimeMillis() + 30000;
        double timeDifference = 30000;

    final JFrame messageFrame = new JFrame();
    messageFrame.setLayout(new GridBagLayout());

    messageFrame.setTitle("Warning");
    final JLabel message = new JLabel("Next query in " + timeDifference/1000 + " seconds.");
    messageFrame.setSize(500,100);
    messageFrame.setLocationRelativeTo(null);
    addComponent(messageFrame, message, 0, 0, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.CENTER);
    messageFrame.setVisible(true);

    System.out.println(Thread.currentThread().getName());

     final Timer timer = new Timer();
     timer.schedule(new TimerTask() {

         @Override
         public void run() {



                synchronized (timer) {


                     decreaseTime();
                        message.setText("Preventing connection block. Next query in " + TIMER/1000 + " seconds.");

                        if(getTime()==0){

                            System.out.println("Im here");
                            timer.notify();
                            System.out.println("Im here 2");
                            messageFrame.dispose();
                            System.out.println("Im here 3");
                            timer.cancel();
                        }

                    }
             }
     }, 1, 1);

    synchronized (timer) {

       try {

            timer.wait();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

       System.out.println("Done");

 }



private static void addComponent(Container container, Component component, int gridx, int gridy,
        int gridwidth, int gridheight, int anchor, int fill) {

      GridBagConstraints gbc = new GridBagConstraints(gridx, gridy, gridwidth, gridheight, 1.0, 1.0,
    anchor, fill, INSETS, 0, 0);

      container.add(component, gbc);
      }

public void decreaseTime() {
    TIMER--;
}

public int getTime() {
    return TIMER;
}


public static void main(String[] args){

Chronometer c = new Chronometer();
}

}

所以,我有将近3天的时间在想,我该如何解决这个问题?欢迎提出任何建议;提前谢谢。

我找到了自己的答案。停止EDT将永远不是一个选项。从未。如果你想处理像我这样的问题,解决方法比我想象的要简单得多。在侦听器中触发操作之后,只需调用另一个线程来处理您想要的任何内容。这样可以防止EDT变忙并冻结GUI。通过这种方式,您将能够以尽可能多的方式锁定线程,我的意思是,同步方法、循环或其他您想要使用的方法。我的解决方案是阅读本文:。这真是一篇很棒的文章,让我对swing和threads有了新的认识。希望这对你也有帮助。

我找到了自己的答案。停止EDT将永远不是一个选项。从未。如果你想处理像我这样的问题,解决方法比我想象的要简单得多。在侦听器中触发操作之后,只需调用另一个线程来处理您想要的任何内容。这样可以防止EDT变忙并冻结GUI。通过这种方式,您将能够以尽可能多的方式锁定线程,我的意思是,同步方法、循环或其他您想要使用的方法。我的解决方案是阅读本文:。这真是一篇很棒的文章,让我对swing和threads有了新的认识。希望这对您也有帮助。

请阅读
SwingWorker
API。认为应该在EDT内部调用我的SwingWorker子类,而不是为它创建一个线程并在Swing实用程序内部运行,这是正确的吗?SwingWorker的要点是,您不必管理自己的线程。无论从哪个线程调用
execute
doInBackground
都将在后台线程上调用(由SwingWorker内部管理),并且
process
done
将在EDT上运行。请阅读
SwingWorker
API。认为应该在EDT内部调用我的SwingWorker子类,而不是为它创建一个线程并在Swing实用程序内部运行,这是正确的吗?SwingWorker的要点是,您不必管理自己的线程。无论从哪个线程调用
execute
doInBackground
都将在后台线程上调用(由SwingWorker内部管理),并且
process
done
将在EDT上运行。
import java.awt.Component;
import java.awt.Container;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JFrame;
import javax.swing.JLabel;

public class Chronometer {


    private static final Insets INSETS = new Insets(1, 1, 1, 1);

    private int TIMER = 3000;

public Chronometer(){

    double timeToNext = System.currentTimeMillis() + 30000;
        double timeDifference = 30000;

    final JFrame messageFrame = new JFrame();
    messageFrame.setLayout(new GridBagLayout());

    messageFrame.setTitle("Warning");
    final JLabel message = new JLabel("Next query in " + timeDifference/1000 + " seconds.");
    messageFrame.setSize(500,100);
    messageFrame.setLocationRelativeTo(null);
    addComponent(messageFrame, message, 0, 0, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.CENTER);
    messageFrame.setVisible(true);

    System.out.println(Thread.currentThread().getName());

     final Timer timer = new Timer();
     timer.schedule(new TimerTask() {

         @Override
         public void run() {



                synchronized (timer) {


                     decreaseTime();
                        message.setText("Preventing connection block. Next query in " + TIMER/1000 + " seconds.");

                        if(getTime()==0){

                            System.out.println("Im here");
                            timer.notify();
                            System.out.println("Im here 2");
                            messageFrame.dispose();
                            System.out.println("Im here 3");
                            timer.cancel();
                        }

                    }
             }
     }, 1, 1);

    synchronized (timer) {

       try {

            timer.wait();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

       System.out.println("Done");

 }



private static void addComponent(Container container, Component component, int gridx, int gridy,
        int gridwidth, int gridheight, int anchor, int fill) {

      GridBagConstraints gbc = new GridBagConstraints(gridx, gridy, gridwidth, gridheight, 1.0, 1.0,
    anchor, fill, INSETS, 0, 0);

      container.add(component, gbc);
      }

public void decreaseTime() {
    TIMER--;
}

public int getTime() {
    return TIMER;
}


public static void main(String[] args){

Chronometer c = new Chronometer();
}

}