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中的潜在异常?
答案 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)
,您有两种正确的方法,{ p>
使用
Runnable#Thread
SwingWorker