Java 多个ShowMessage对话框能否中断swing?
这是简化的代码,在我的主JFrame类中按一个按钮就可以调用它。使用此代码,然后关闭其中一个生成的对话框,会导致Java会话中的所有活动窗口被锁定或消失Java 多个ShowMessage对话框能否中断swing?,java,swing,Java,Swing,这是简化的代码,在我的主JFrame类中按一个按钮就可以调用它。使用此代码,然后关闭其中一个生成的对话框,会导致Java会话中的所有活动窗口被锁定或消失 //Broken code private void buttonActionPerformed(java.awt.event.ActionEvent evt) { List<JFrame> frameList = new ArrayList<>(); frameList.add(new TestJFra
//Broken code
private void buttonActionPerformed(java.awt.event.ActionEvent evt) {
List<JFrame> frameList = new ArrayList<>();
frameList.add(new TestJFrame());
frameList.add(new TestJFrame());
frameList.forEach(frame -> frame.setVisible(true));
frameList.forEach(frame -> {
SwingUtilities.invokeLater(() -> {
JOptionPane.showMessageDialog(frame, "Msg", "Title", 0);
frame.setVisible(false);
frame.dispose();
});
});
}
我不想使用第二个,因为实际的代码是在一个后台线程中启动的,该线程正在通知一组侦听器,因此如果我使用第二个线程,它将阻塞线程并降低侦听器的速度,直到用户响应为止(当时我可能正在处理)。那么invokeLater()
会让我崩溃吗?这是预期的行为吗
注意:这是从我实际使用它的方式中提取出来的简化代码,但核心问题仍然存在(我有多个JFrame
s,如果有多个JOptionPane.showMessageDialog()
s放在invokeLater()上)
s对于不同的JFrame
s,这让我崩溃了。我用在Netbeans中创建的一个新的、独立的JFrame
类测试了上述代码,并且能够重现错误
编辑:我似乎无法在Windows中重现此错误,似乎只在Linux中发生。很可能是invokeLater()破坏了您的代码。如果您想执行此操作,请尝试使用简单的线程或
EventQueue.invokeLater(new Runnable()
{
public void run()
{ //Your joptionpane here
}
});`
很可能是invokeLater()破坏了您的代码。如果您想执行此操作,请尝试使用简单的线程或
EventQueue.invokeLater(new Runnable()
{
public void run()
{ //Your joptionpane here
}
});`
我宁愿使用 1) 单丝 2) 定时器任务 3) ScheduledExecutorService 使用以下方法之一。 这是一个使用计时器任务的示例
import java.util.Timer;
import java.util.TimerTask;
public class Task2 {
public static void main(String[] args) {
TimerTask task = new TimerTask() {
@Override
public void run() {
// task to run goes here
System.out.println("Hello !!!");
}
};
Timer timer = new Timer();
long delay = 0;
long intevalPeriod = 1 * 1000;
// schedules the task to be run in an interval
timer.scheduleAtFixedRate(task, delay,
intevalPeriod);
} // end of main
}
如果您不满意,可以稍后使用invoke。
但是请记住,永远不要使用invoke并等待,这是一个坏主意,我更喜欢使用 1) 单丝 2) 定时器任务 3) ScheduledExecutorService 使用以下方法之一。 这是一个使用计时器任务的示例
import java.util.Timer;
import java.util.TimerTask;
public class Task2 {
public static void main(String[] args) {
TimerTask task = new TimerTask() {
@Override
public void run() {
// task to run goes here
System.out.println("Hello !!!");
}
};
Timer timer = new Timer();
long delay = 0;
long intevalPeriod = 1 * 1000;
// schedules the task to be run in an interval
timer.scheduleAtFixedRate(task, delay,
intevalPeriod);
} // end of main
}
如果您不满意,可以稍后使用invoke。
但请记住,永远不要使用invoke and wait这是一个坏主意,我的方法是这样的,因为我知道问题出在锁定的窗口上,这些窗口正在等待事件完成,在swing中,事件与AWT EventQueue相关 以下是关于以下方面的一点说明: 因此,为了让您的窗口正常工作,我使用了Future类型: 从java文档: 未来表示异步计算的结果。方法 用于检查计算是否完成,以等待其完成 完成,并检索计算结果。结果 只能在计算已完成时使用方法get检索 完成,必要时阻塞,直到准备就绪
package com.stackoverflow.future;
导入java.util.ArrayList;
导入java.util.List;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入java.util.concurrent.Future;
导入java.util.concurrent.TimeUnit;
导入javax.swing.JFrame;
导入javax.swing.SwingUtilities;
导入javax.swing.SwingWorker;
导入com.stackoverflow.frame.MyFrame;
公共类MyWingWorker扩展SwingWorker{
@凌驾
受保护的Void doInBackground()引发异常{
final ExecutorService服务=Executors.newFixedThreadPool(1);
列表框架列表=新的ArrayList();
frameList.add(service.submit)(新SwingLoader(newmyframe()));
frameList.add(service.submit)(新SwingLoader(newmyframe()));
试一试{
service.shutdown();
服务。等待终止(5,时间单位。秒);
}捕获(中断异常例外){
例如printStackTrace();
}最后{
service.shutdownNow();
}
返回null;
}
公共静态void main(字符串[]args){
MySwingWorker MySwingWorker=新的MySwingWorker();
SwingUtilities.invokeLater(mySwingWorker);
}
}
加载程序:
package com.stackoverflow.future;
import java.util.concurrent.Callable;
import javax.swing.JFrame;
public class SwingLoader implements Callable<JFrame>{
private JFrame frame;
public SwingLoader(JFrame frame){
this.frame = frame;
}
@Override
public JFrame call() throws Exception {
frame.setVisible(true);
return frame;
}
}
package com.stackoverflow.future;
导入java.util.concurrent.Callable;
导入javax.swing.JFrame;
公共类SwingLoader实现可调用{
私有JFrame;
公共SwingLoader(JFrame){
this.frame=frame;
}
@凌驾
公共JFrame调用()引发异常{
frame.setVisible(true);
返回框;
}
}
注意:这段代码只是一个原型,为了给你提供思路,必须对其进行修改和清理,以达到预期的效果
这里是一个链接,其中包含每种类型的几个解释:
这是我的方法,据我所知,问题出在锁定的窗口上,这些窗口正在等待事件完成。在swing中,事件与AWT EventQueue相关 以下是关于以下方面的一点说明: 因此,为了让您的窗口正常工作,我使用了Future类型: 从java文档: 未来表示异步计算的结果。方法 用于检查计算是否完成,以等待其完成 完成,并检索计算结果。结果 只能在计算已完成时使用方法get检索 完成,必要时阻塞,直到准备就绪
package com.stackoverflow.future;
导入java.util.ArrayList;
导入java.util.List;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入java.util.concurrent.Future;
导入java.util.concurrent.TimeUnit;
导入javax.swing.JFrame;
导入javax.swing.SwingUtilities;
导入javax.swing.SwingWorker;
导入com.stackoverflow.frame.MyFrame;
公共类MyWingWorker扩展SwingWorker{
@凌驾
受保护的Void doInBackground()引发异常{
final ExecutorService服务=Executors.newFixedThreadPool(1);
列表框架列表=新的ArrayList();
frameList.add(service.submit)(新SwingLoader(newmyframe()));
frameList.add(service.submit)(新SwingLoader(newmyframe()));
试一试{