Java 使用SwingUtilities.invokeLater创建弹出窗口
我正在网上写一个基于回合的游戏。我试图弹出一个窗口,在输入流准备好之前,它应该在前面。我像这样创建了SMT,但它似乎不起作用Java 使用SwingUtilities.invokeLater创建弹出窗口,java,swing,applet,jdialog,invokelater,Java,Swing,Applet,Jdialog,Invokelater,我正在网上写一个基于回合的游戏。我试图弹出一个窗口,在输入流准备好之前,它应该在前面。我像这样创建了SMT,但它似乎不起作用 class CustomBlockerDialog extends JDialog { /** * */ private static final long serialVersionUID = 1L; public CustomBlockerDialog(Frame owner, String text) { super(owner, true);
class CustomBlockerDialog extends JDialog {
/**
*
*/
private static final long serialVersionUID = 1L;
public CustomBlockerDialog(Frame owner, String text) {
super(owner, true);
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
setSize(300, 100); // Adjust if needed
setTitle("");
add(new JLabel(text, SwingConstants.CENTER));
}
}
final CustomBlockerDialog block = new CustomBlockerDialog(null, "Not your turn");
SwingUtilities.invokeLater(new Runnable() {//A
@Override
public void run() {
System.out.println("show");
block.setVisible(true);
}
});
boolean one_write_only = true;
while(in.ready()){ /* C*/
if(one_write_only){
System.out.println("waiting server");
one_write_only = false;
}
};
System.out.println("suppose to hide");
SwingUtilities.invokeLater(new Runnable() {//B
@Override
public void run() {
System.out.println("hide");
block.setVisible(false);
}
});
看起来“A”和“B”是在“C”之后执行的,我不知道为什么。您的问题一定是因为在Swing事件线程上调用了“C”,而不是在后台线程中,因为听起来像是“C”在阻止事件线程运行“A”。解决方案:确保未在Swing事件线程上调用“C”。此外,如果是这种情况,并且可以通过运行
SwingUtilities.isEventDispatchThread()
方法来测试,那么您就不需要所有其他可运行程序
// note that this all must be called on the Swing event thread:
final CustomBlockerDialog block = new CustomBlockerDialog(null, "Not your turn");
System.out.println("show");
// block.setVisible(true); // !! no this will freeze!
final SwingWorker<Void, Void> worker = new SwingWorker<>() {
public void doInBackground() throws Exception {
boolean one_write_only = true;
while(in.ready()){ /* C*/
if(one_write_only){
System.out.println("waiting server");
one_write_only = false;
}
}
}
}
worker.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChanged(PropertyChangeEvent pcEvt) {
if (pcEvt.getNewValue() == SwingWorker.StateValue.DONE) {
System.out.println("hide");
block.setVisible(false);
// call worker's get() method here and catch exceptions
}
}
});
worker.execute();
// moved to down here since the dialog is modal!!!
block.setVisible(true);
//请注意,必须在Swing事件线程上调用这一切:
最终CustomBlockerDialog block=新CustomBlockerDialog(null,“不轮到你”);
系统输出打印项次(“显示”);
//block.setVisible(true);/!!不,这会结冰的!
最终SwingWorker工人=新SwingWorker(){
public void doInBackground()引发异常{
布尔值one_write_only=true;
while(in.ready()){/*C*/
如果(仅一次写入){
System.out.println(“等待服务器”);
仅一次写入=错误;
}
}
}
}
worker.addPropertyChangeListener(新的PropertyChangeListener(){
公共作废属性更改(属性更改事件pcEvt){
if(pcEvt.getNewValue()==SwingWorker.StateValue.DONE){
System.out.println(“隐藏”);
block.setVisible(假);
//在此处调用worker的get()方法并捕获异常
}
}
});
worker.execute();
//由于对话框是模态的,所以移动到下面!!!
block.setVisible(true);
警告:未编译或测试的代码。可能会出现错误,因为它是即兴输入的。多亏了装满鳗鱼的气垫船,我创建了一个与我的情况略有不同的解决方案:
final SwingWorker<Object,Object> worker2 = new SwingWorker<Object, Object>() {
public Object doInBackground() throws Exception {
boolean one_write_only = true;
while(!in.ready()){ /* C*/
if(one_write_only){
System.out.println("waiting server");
one_write_only = false;
}
}
return one_write_only;
}
protected void done() {
try {
block.setVisible(false);
} catch (Exception ignore) {}
}
};
worker2.execute();
block.setVisible(true);
final SwingWorker worker 2=新SwingWorker(){
公共对象doInBackground()引发异常{
布尔值one_write_only=true;
而(!in.ready()){/*C*/
如果(仅一次写入){
System.out.println(“等待服务器”);
仅一次写入=错误;
}
}
仅返回一个_write_;
}
受保护的void done(){
试一试{
block.setVisible(假);
}捕获(异常忽略){}
}
};
worker2.execute();
block.setVisible(true);
很抱歉这么长时间没有发布。我记得,但我有很多工作要做。