【发布时间】:2015-04-29 02:33:46
【问题描述】:
我有一个 JRuby 脚本,它打开一个 Java 对话框来报告脚本的进度。
我正在捕获一个窗口关闭事件,并希望对话框等到 JRuby 脚本中的某些清理发生后,然后释放。相反,当用户按下右上角的红色 x 按钮时,对话框就会挂起。
如何正确调用 wait 方法来等待标志更改?我是否正确使用了锁对象?
一个 jruby 脚本调用这个对话框。
如果用户按下右上角的红色 X,对话框将捕获窗口关闭事件并设置“已取消”标志。
该脚本密切关注该标志,然后开始关闭一些长时间运行的任务以及其他什么。完成后,它会更新对话框上的标志,说明已进行清理。
同时,对话框正在循环,等待该标志更改。然后它调用 dispose()。
我尝试过使用睡眠。出于某种原因,这会扰乱我的 JRuby 和对话框之间的某些内容,清理工作正常,但对话框没有处理。
使用 wait 和 synchronize(this) 会生成 IllegalMonitorException,但脚本会清理干净,并且对话框会正确处理,除了异常。
看过很多其他关于如何同步等待方法的帖子,非常想了解这一点。
非常感谢您的帮助。
对话框类如下:
import javax.swing.*;
import java.awt.*;
public class MyDialog extends JDialog {
private boolean userCancelled;
private boolean scriptCleanedUp;
//private static Object lock = new Object();
public MyDialog(lock) {
userCancelled = false;
scriptCleanedUp = false;
setDefaultCloseOperation(2);
//[..] add various controls to dialog
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
// the jruby script keeps an eye on this flag to see if the user has cancelled the dialog
userCancelled = true;
/* once cancelled, wait for script to flag that it has performed its cleanup
*/
/* here is the problem area, what do I need to synchronize to use the wait method?
*/
while (!scriptCleanedUp) {
try {
synchronized (lock) {
lock.wait(1000000000);
}
// Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
dispose();
}
});
super.paint(super.getGraphics());
}
public boolean user_cancelled() { return userCancelled; }
public void setScriptCleanedUpToTrue() { this.scriptCleanedUp = true; }
public static void forBlock(MyDialogBlockInterface block)
{
MyDialog dialog = new MyDialog(new Object());
dialog.setVisible(true);
block.DoWork(dialog);
dialog.dispose();
}
}
如果有帮助,这就是 JRuby 脚本调用对话框的方式
MyDialog.forBlock do |dialog|
#do long running jruby task here
end
【问题讨论】:
-
JRuby 调用代码是否也显示某种类型的 Swing 窗口,例如 JFrame?
-
不,它没有。不知道这是否有帮助,但是围绕这个问题还有一些其他的 Swing 工作 - JRuby 代码正在由 Java 应用程序运行,并且该应用程序使用 Swing 作为接口。所以该应用程序正在运行 JRuby 代码,然后调用我的小对话框。