java swing中的setvisible方法挂起系统
我目前正在开发银行 gui 应用程序,我的 jdialog 的 setvisible 方法似乎有问题。用户提取有效金额后,我会弹出一个简单的对话框,显示“交易正在进行中”。在我的 dobackground 方法中,我不断轮询以检查是否已收到交易。我尝试使用 Swingworker,但我不明白为什么它不起作用。如果我删除 setvisible 调用,它工作正常,那么为什么 setvisible 会导致系统挂起?这是我的 jbutton mouselistener 中的代码:
SwingWorker<String,Integer> worker = new SwingWorker<String,Integer>(){
JDialog waitForTrans = new JDialog((JFrame)null,true);
public String doInBackground() throws Exception {
waitForTrans.add(new JLabel("Updating balance in system. Please Wait..."));
waitForTrans.setMinimumSize(new Dimension(300,100));
waitForTrans.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
waitForTrans.setVisible(true);
Bank.getInstance().sendTransaction(currentPin,"-"+withdraw);
while(!Bank.getInstance().hasCompletedTransaction){
}
return null;
}
public void done(){
try {
this.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
waitForTrans.setVisible(false);
newField.setText(String.valueOf(Bank.getInstance().getAccountList().get(currentPin).getBalance()));
}
};
worker.execute();
I have banking gui application that I am currently working on and there seems to be a problem with the setvisible method for my jdialog. After the user has withdrawn a valid amount I pop up a simple dialog that says "transaction in progress". In my dobackground method i keep polling to check if the transaction has been received. I tried using swingworker and I don't understand why it's not working. If i remove the setvisible call it works fine, so why does setvisible cause the system to hang? Here is the code that is inside my jbutton mouselistener:
SwingWorker<String,Integer> worker = new SwingWorker<String,Integer>(){
JDialog waitForTrans = new JDialog((JFrame)null,true);
public String doInBackground() throws Exception {
waitForTrans.add(new JLabel("Updating balance in system. Please Wait..."));
waitForTrans.setMinimumSize(new Dimension(300,100));
waitForTrans.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
waitForTrans.setVisible(true);
Bank.getInstance().sendTransaction(currentPin,"-"+withdraw);
while(!Bank.getInstance().hasCompletedTransaction){
}
return null;
}
public void done(){
try {
this.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
waitForTrans.setVisible(false);
newField.setText(String.valueOf(Bank.getInstance().getAccountList().get(currentPin).getBalance()));
}
};
worker.execute();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
首先,建议在 Swing Event-Dispatch 线程中执行所有 GUI 更新,即使用
SwingUtilites
类。其次,您的 JDialog 是模态的,因此会阻塞调用 setVisible(true) 方法的线程(在您的情况下是主线程,在以下情况下是 Swing 事件) - 调度线程)。
我并不是说下面的代码是完美的,但它应该让你走上正轨......
希望这会有所帮助。
First, it is recommended to do all the GUI updates in the Swing Event-Dispatch thread, i.e. using the
SwingUtilites
class.Second, your
JDialog
is modal and so blocks the thread in which thesetVisible(true)
method is called (in your case the Main thread, in the following case the Swing Event-Dispatch Thread).I do not say the following code is perfect, but it should put you on the track...
Hope this helps.
您正在显示一个模式对话框,因此在对话框关闭之前后台代码无法执行。
在 setVisible 之后添加 System.out.println(...) 语句,您将看到它永远不会执行。
You are displaying a modal dialog so the background code can't execute until the dialog is closed.
Add a System.out.println(...) statement after the setVisible and you will see it never executes.
setVisible
是一种影响 GUI 的方法,导致显示某些内容(并且,在像您这样的模态对话框的情况下,会阻塞直到对话框关闭)。除了在 Swing 事件调度线程上之外,决不应该调用它(与修改可见 UI 的其他所有内容一样)。您从SwingWorker
的doInBackground
方法调用它,该方法在后台线程上运行。要解决此问题,您需要做的是将
waitForClose
对话框设置为在SwingWorker< 上调用
execute
之前创建的final
变量。 /code>,然后在启动工作线程后立即调用setVisible
。您需要按此顺序执行此操作,否则模式对话框将阻止您启动工作程序。
setVisible
is a method that affects the GUI, causing something to be shown (and, in the case of a modal dialog like yours, block until the dialog is closed). It (like everything else that modifies the visible UI) should never be called except on the Swing event dispatch thread. You're calling it from thedoInBackground
method ofSwingWorker
, which runs on a background thread.What you need to do to fix this is make the
waitForClose
dialog afinal
variable that you create before callingexecute
on theSwingWorker
and then callsetVisible
on immediately after starting the worker.You need to do it in this order because otherwise the modal dialog will block you from starting the worker.
camickr 给你正确的答案。我想补充一点,您不得在事件调度线程之外修改 UI(如您在
#doInBackground
中所做的那样),Swing 是单线程的因此,违反此规则可能会导致用户界面中出现非常棘手的错误和奇怪的事情。camickr gives you correct answer. I want to add that you may not modify the UI outside the Event Dispatch Thread (as you do in
#doInBackground
), Swing is single threaded so violating this rule could lead to very tricky bugs and strange things in your UI.