Подтвердить что ты не робот

Как заставить поток ждать JFrame для закрытия в Java?

При запуске программы создается новый JFrame. Как только пользователь нажимает кнопку запуска, создается и запускается поток. Часть этого выполнения потоков заключается в проверке данных в форме и последующем выполнении с этими данными. После проверки данных поток вызывает dispose() в исходном фрейме, а затем создает новый JFrame, который действует как панель управления.

Существует также автоматический режим программы, который вообще не отображает графический интерфейс, этот режим считывает данные из файла конфигурации, а затем запускает поток выполнения и запускает все, но без панели управления.

Я хочу, чтобы программа заканчивалась после завершения потока, но в режиме графического интерфейса, только если пользователь закрыл панель управления. Можно ли заставить поток ждать закрытия кадра. Я предполагаю, что кадр запускается из его собственного потока? или это не так.

Спасибо.

4b9b3361

Ответ 1

Ответ, который вы выбрали, немного неудобен. Использование Thread.sleep(1000) будет проверять состояние окна каждую секунду. Это не проблема производительности, а просто плохой стиль кодирования. И у вас может быть время ответа в одну секунду.

Этот код немного лучше.

private static Object lock = new Object();
private static JFrame frame = new JFrame();
/**
 * @param args
 */
public static void main(String[] args) {

    frame.setSize(300, 300);
    frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
    frame.setVisible(true);

    Thread t = new Thread() {
        public void run() {
            synchronized(lock) {
                while (frame.isVisible())
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                System.out.println("Working now");
            }
        }
    };
    t.start();

    frame.addWindowListener(new WindowAdapter() {

        @Override
        public void windowClosing(WindowEvent arg0) {
            synchronized (lock) {
                frame.setVisible(false);
                lock.notify();
            }
        }

    });

    t.join();
}

Ответ 2

Все компоненты Swing, включая JFrame, управляются одним потоком, который называется Thread Dispatch Thread или EDT. (Можно вызвать методы для объектов Swing из других потоков, но это обычно небезопасно, за исключением нескольких случаев, которые здесь не актуальны.)

Вы, вероятно, достигнете того, чего хотите здесь, поставив код проверки и выполнения данных в свой собственный объект, который в противном случае полностью не осознает внешний мир. Затем вызовите его из одного из двух других объектов: одного, который управляет графическим интерфейсом, а другой, который работает в "автоматическом режиме".

Ответ 3

Вы можете ссылаться на свой поток на JFrame. Затем установите для JFrame операцию закрытия по умолчанию HIDE_ON_CLOSE. Если JFrame закрыт, вы можете остановить поток.

Пример кода:

import java.awt.Dimension;

import javax.swing.JFrame;

public class FrameExample extends JFrame {

    public FrameExample() {
        setSize(new Dimension(100, 100));
        setDefaultCloseOperation(HIDE_ON_CLOSE);
        setVisible(true);

    }

    private static class T implements Runnable {

        private FrameExample e;

    public T(FrameExample e) {
        this.e = e;
    }

    @Override
    public void run() {
        while (true) {
            if (e.isVisible()) {
                // do the validation
                System.out.println("validation");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e1) {
                    break;
                }
            }
        }
    }

}

public static void main(String[] args) {
    FrameExample frameExample = new FrameExample();

    new Thread(new T(frameExample)).start();
    }
}