我正在为程序编写GUI,该程序允许用户接受或拒绝发送到侦听服务器套接字的请求。我通过使用DoYouAcceptWindow
和另一些打开它的代码来完成此操作。
DoYouAcceptWindow.java
中的代码如下
public class DoYouAcceptWindow extends JFrame implements MouseListener{
private short d = 0;
private JButton accept;
public DoYouAcceptWindow() {
setLayout(new FlowLayout());
accept = new JButton("Accept");
accept.addMouseListener(this);
add(accept);
pack();
setVisible(true);
}
public short getDecided() {
return d;
}
@Override
public void mouseClicked(MouseEvent e) {
if (e.getSource().equals(accept)) {
System.out.println("Accepted");
d = 2;
}
}
}
(我从中删除了许多不必要的功能,并具有拒绝请求的能力,以使其更易于阅读)
以及使用上述类的代码:
while (true) {
DoYouAcceptWindow w = new DoYouAcceptWindow();
short decided = w.getDecided();
while (decided == 0) {
decided = w.getDecided();
}
System.out.println("Done!");
w.dispose();
if (w.getDecided() == 2) {
break;
}
}
(此代码还删除了许多不必要的部分)
当您按下按钮时,它会像应有的那样打印“已接受”(我假设它设置d = 1或2)。但是,它不会脱离while循环。但是,当我将打印语句添加到while循环中时(像这样):
while (decided == 0) {
decided = w.getDecided();
System.out.println(0);
}
它会自行修复。如果我在调试模式下(在Eclipse中)运行它,它会自行修复。如果没有print语句,为什么不退出while循环?我该如何解决? (不添加打印说明)
答案 0 :(得分:3)
不能肯定地说,但是根据描述,这可能是内存可见性问题。
您可以尝试将值声明为volatile吗?
private volatile short d = 0;
答案 1 :(得分:1)
您的问题是JFrame是非模式的,这意味着它不会阻塞调用代码的程序流,因此您的while循环将永远重复,从而阻塞了Swing事件线程,并使您的应用程序变得无用。
一种解决方案是使用模式对话框,例如模式JDialog或JOptionPane(实际上是伪装的模式JDialog)。
例如
import javax.swing.*;
public class DoYouAcceptEg {
public static void main(String[] args) {
int response = JOptionPane.DEFAULT_OPTION;
while (response != JOptionPane.YES_OPTION && response != JOptionPane.NO_OPTION) {
response = JOptionPane.showConfirmDialog(null, "Do you accept?",
"Accept?", JOptionPane.YES_NO_OPTION, JOptionPane.PLAIN_MESSAGE);
if (response == JOptionPane.YES_OPTION) {
System.out.println("Accepted");
} else if (response == JOptionPane.NO_OPTION) {
System.out.println("Rejected");
} else {
System.out.println("Undecided");
}
}
}
}