在gui-event之后阻塞主线程

时间:2015-01-04 13:30:21

标签: java swing user-interface blocking event-dispatch-thread

我一直在制作一个程序,从文件中读取,识别常见的"帖子"在文件中,并对这些进行总结。我的问题是允许用户指定帖子的名称和搜索词的GUI事件不会像我想要的那样中断程序的运行。

我可以让它停止,但是GUI将无法正确显示。我已经尝试了一些解决方案,这些解决方案将在帖子的底部指定。

编辑:删除了编码转储并添加了一些类似于SSCCE的内容:

class SSCCE{
public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable(){
        @Override
        public void run(){
            new Gui();
        }
    });
}
}

class Gui implements ActionListener{

boolean runn=true;
JFrame wind2;
JTextField nameF, searchtermF;
JButton done;

Gui(){
    runEx();
}

public void runEx(){

    int i =0;
    while(runn){
        if(i==10)   break;
        System.out.println("Open window and record information given! One at the time!!!");
        System.out.println(" ");
        giveName("test");

        i++;
    }
}

public void giveName(String s){


    JLabel nameL = new JLabel("Give this post a name:");
    JLabel searchL = new JLabel("What do you want the searchterm to be?");

    wind2 = new JFrame("EazyMoney");
    wind2.setLayout(new BorderLayout());

    JPanel all = new JPanel();
    all.setLayout(new GridLayout(2,2));


    searchtermF = new JTextField(30);
    nameF=new JTextField(30);

    all.add(nameL);
    all.add(nameF);
    all.add(searchL);
    all.add(searchtermF);

    done = new JButton("Press when you have filled in the information!");
    done.addActionListener(this);

    String prn = "The post in question: " + s;
    JLabel header = new JLabel(prn);

    wind2.add(header, BorderLayout.NORTH);
    all.setVisible(true);
    wind2.add(all, BorderLayout.CENTER);
    wind2.add(done, BorderLayout.SOUTH);

    wind2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    wind2.pack();
    wind2.setLocationRelativeTo(null);
    wind2.validate();
    wind2.setVisible(true);
}

public void actionPerformed(ActionEvent e){
    System.out.println("Action recorded, new window can now be shown. All information stored.");
    System.out.println(" ");
}
}

我尝试的解决方案是:

  • 一个简单的块,它执行while(true){}并在调用g.giveName()的第一个实例后将变量设置为true。我使用ActionListener调用一个方法,然后在给出必要的输入时再次将变量更改为false。这导致了一个灰色的盒子,里面没有任何东西。
  • 制作与上述块相同的循环屏障。使用单独的线程调用g.giveName(),然后从动作侦听器调用await()。与上述结果相同。
  • 使readFile由单独的线程运行,并在invokeAndWait()函数上调用g.giveName()。给了cannot call invokeAndWait() from the EDT-thread,即使它是从一个新线程运行的。

我不能举出上面实例中使用的代码示例,因为我已经尝试了很多不同的解决方案而且不再拥有它。请注意它可能已被错误地实施,因此可能是我的问题的有效答案,即使我似乎无法让它工作!

最后注意事项:如果您想测试代码,可以在此处找到所有工作: https://github.com/Robiq/EazyMoneyWork

1 个答案:

答案 0 :(得分:0)

如果您需要在同一个线程上执行其他操作来避免阻止EDT,那么暂时创建一个新的事件队列。这是一些示例代码。在这种情况下,它会阻止当前线程等待其他事件发出信号,但您可以将其替换为需要长时间运行的进程。

首先检查您是否在EDT上运行:SwingUtilities.isEventDispatchThread。如果你是:

EventQueue tempEventQueue = new EventQueue();
Toolkit.getDefaultToolkit().getSystemEventQueue().push(tempEventQueue);
try {
    wait();
} catch (InterruptedException ex) {
    // stop waiting on interrupt
} finally {
    tempEventQueue.pop();
}

与此类似的是模态对话框在Swing中的工作方式。但总的来说,这不是一个好习惯。更好的是了解要监听哪些事件以执行特定操作。在您的情况下,用户事件不应该“停止”您的程序 - 它应该禁用不适当的组件,直到用户响应然后重新启用它们。

相关问题