在不使用try / catch的情况下调用抛出异常的匿名ActionListener中的方法

时间:2011-10-28 19:16:08

标签: java swing

public class Test {
public void buildGUI()
{
    JFrame frame = new JFrame();
    JButton send = new JButton("Send");
    send.addActionListener(new ActionListener()
    {
        public void actionPerformed(ActionEvent e)
        {
            send();
            frame.dispose();
        }
    });
    frame.add(send);
    frame.pack();
    frame.setVisible(true);
}
}

如果方法send()抛出MyException,我怎么会让那个异常从Swing线程迁移到我的类?

我想要对生成的异常做另外一个实例化它的类就像这样捕获异常。

public class AnotherTest
{
    public AnotherTest()
    {
         Test t = new Test();
         try
         {
             t.buildGUI();
         }
         catch(MyException e)
         {
             //do stuff.
         }
     }
}

这就是我想要在概念上发生的事情,但是我知道buildGUI将在调用actionPerformed之前结束。那么,我如何在AnotherTest中捕获actionPerformed中的潜在异常?

4 个答案:

答案 0 :(得分:1)

一个班级可能不会发生异常。只有方法才能。

一个类不是可以执行的东西。可以执行方法。

执行动作侦听器方法的是Swing事件派发线程。如果某个方法在侦听器中抛出异常,则唯一可以做的就是捕获它并以某种方式显示它:通过打开错误对话框,或将异常消息放在文本区域或任何其他内容。

    public void actionPerformed(ActionEvent e) {
        try {
            send();
        }
        catch (MyException e) {
            someTextArea.setText(e.getMessage());
        }
    }

如果你实际上想要从Swing EDT与主线程进行通信,你可以使用BlockingQueue,并在队列上调用主线程take,并将侦听器offer作为例外队列。

任何其他线程通信机制都可以。但请确保不要阻止EDT,否则整个GUI都会冻结。

答案 1 :(得分:1)

一个类不能抛出异常,只有方法可以这样才能使第一行出错。第二件事,您可以使用try ... catch()块来包围send()以处理该异常,您可以在其中执行某些错误恢复操作或显示错误消息或类似的内容,这仍然可以满足您的目的。 / p>

答案 2 :(得分:0)

那么,为什么不做呢?而是让send()调用逻辑运行的其他线程?如果该线程遇到异常,您可以在那里处理它。

没有办法在线程边界之间抛出异常。您可以通过设置一些外部标记,使send()传递有关外部世界发生的异常的信息,该标记对应用程序的其他线程可见。

答案 3 :(得分:0)

Swing不是Thread安全的,那么在try - catch - finally块内构建Swing GUI的想法更具反作用,你必须单独准备所有我们安全的代码块

1)我开始的方式非常糟糕 - >您的想法必须包含在invokeLater()中,如果有困难且长时间运行Stream, File I/O, DB Conenction,那么请尝试将其包装到invokAndWait()

但是从某些GUI加载这些数据,你有很多时间

2)在需要之前准备并加载数据(Stream, File I/O, DB Conenction),然后在需要时将这些对象放入GUI(would be wrapped into invokeLater

3)创建GUI(would be wrapped into invokeLater),显示此Container,然后加载数据(Stream, File I/O, DB Conenction)如果成功,则在GUI中添加显示这些数据

3)创建GUI(would be wrapped into invokeLater),显示此Container,仅为JComponents之一加载数据,如果成功,则显示此JComponent,同样为第2位。等等...

要求所有三个选项重定向(Stream, File I/O, DB Conenction)将这些数据(JComponent(s)的值)加载到Background Task(s),您有两种正确的方法,

使用

  • Runnable#Thread

  • SwingWorker