我的java swing程序有些麻烦。当ExportWithoutEntryPointFrm
框架出现在自己的线程中时,我尝试停止我的主框架线程。
我用java.util.concurrent.Semaphore
实现了它。
出现的Frame只显示一个空框架,不会显示按钮,标签等,并且两个线程都被阻止。我认为有一个死锁,但我找不到它。
新警告框架的代码,将从主框架调用:
public class ExportWithoutEntryPointFrm extends javax.swing.JFrame implements Runnable
{
private Semaphore sema;
private boolean decision = false;
public ExportWithoutEntryPointFrm(Semaphore semaphore)
{
initComponents();
this.setLocationRelativeTo(null);
this.sema = semaphore;
}
@Override
public void run()
{
this.setVisible(true);
try
{
sema.acquire();
}
catch (InterruptedException e)
{
this.decision = false;
this.sema.release();
this.setVisible(false);
}
}
}
来自主框架的调用代码:
Semaphore waitForDecisionSema = new Semaphore(1, true);
ExportWithoutEntryPointFrm warningFrm = new ExportWithoutEntryPointFrm(waitForDecisionSema);
warningFrm.run();
waitForDecisionSema.acquire();
答案 0 :(得分:3)
首先,调用Runnable的run()方法并不会启动新线程。
其次,即使它确实如此,也只能从事件派发线程中使用像JFrame这样的Swing组件。
第三:因为一旦完成这一行,所有事情都是从一个线程,即EDT完成的:
waitForDecisionSema.acquire();
EDT被阻止等待某个其他线程释放信号量,这种情况永远不会发生,因此EDT会被永久阻止,使您的GUI无响应。
你真的需要重新考虑你的设计。但我不知道你想要达到的目标,所以很难提出建议。鉴于你的信号量的名称,我认为你正在寻找的是一个模态JDialog,它会阻止用户在对话框关闭之前使用对话框的父框架。 / p>
答案 1 :(得分:2)
当ExportWithoutEntryPointFrm框架出现在自己的线程中时,我尝试停止我的主框架线程
嗯,这是一个巨大的矛盾,Swing是一个单线程框架,你可以在不同的线程中操作组件/框架/窗口,它不会工作,你最终会在问题没有结束,死锁是最明显的。
首先查看Concurrency in Swing了解更多详情。
现在,您可以使用许多机制将长时间运行或阻止代码卸载到单独的线程,并仍然与Swing进行交互,Swing Timer
用于常规预定回调,SwingWorker
很长时间运行或可能阻止呼叫,但支持回拨到EDT,使其易于使用,甚至SwingUtilities.invokeLater
用于您没有其他选择的时间。
有关详细信息,请查看How to use Swing Timers和Worker Threads and SwingWorker
虽然根据你的描述,我建议你真正想要的是一个模态对话框,它会在对话框可见时阻止当前帧/代码执行,但这将允许UI继续响应给用户。
有关详细信息,请参阅How to Make Dialogs