除非我插入打印语句,否则While循环不起作用-Java

时间:2020-03-01 19:27:25

标签: java swing

我正在为程序编写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循环?我该如何解决? (不添加打印说明)

2 个答案:

答案 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");
            }
        }
    }
}