Пока l oop не работает, если я не вставлю оператор печати - java - PullRequest
0 голосов
/ 01 марта 2020

Я пишу 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). Тем не менее, оно не вырвется за время l oop. Когда я добавляю оператор печати в while l oop, однако (как это):

while (decided == 0) {
    decided = w.getDecided();
    System.out.println(0);
}

Это исправляет себя. Если я запускаю его в режиме отладки (в eclipse), он исправляется. Почему оно не вырвалось из-за l oop без оператора print? И как я могу это исправить? (без добавления оператора печати)

Ответы [ 2 ]

3 голосов
/ 01 марта 2020

Не могу сказать наверняка, но с описанием это может быть проблемой видимости памяти.

Не могли бы вы попытаться объявить значение volatile?

private volatile short d = 0;
1 голос
/ 01 марта 2020

Ваша проблема в том, что JFrame является немодальным, то есть он не блокирует поток программы вызывающего кода, и поэтому ваше время l oop будет повторяться вечно, блокируя поток событий 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");
            }
        }
    }
}
...