Как дождаться нажатия на кнопку в Swing?

300
23 августа 2017, 16:15

У меня в классе RegistrationFrame, который реализует интерфейс ActionListener, по нажатию на кнопку создается класс Person. В отдельном классе, Test, в отдельном потоке событий, я вызываю конструктор RegistrationFrame, после чего хочу выдернуть из экземпляра класса RegistrationFrame поле с классом Person, следующим образом:

public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                RegistrationFrame registrationFrame = new RegistrationFrame();
                System.out.println(registrationFrame.getPerson().toString());
            }
        });
    }

Очевидно, возникает NullPointerException, потому что программа не ждет нажатия кнопки(по которой создается экземпляр Person), и сразу же после вызова конструктора дергает еще не проинициализированного person. Как заставить программу ждать нажатия на кнопку? Весь jFrame у меня создается внутри конструктора RegistrationFrame, если нужно, могу добавить код.

Answer 1

Можно поступить наоборот: создать слушателя, который будет вызываться при каждом создании Person и с его помощью подписаться на создание объектов из внешнего класса.

Примитивный пример (код не компилировал):

  1. Создаем интерфейс-слушатель

    interface PersonListener {
        void personCreated(Person person);
    }
    
  2. Добавляем в RegistrationFrame метод добавления слушателя и вызов слушателей при создании Person

    class RegistrationFrame ... {
        private final List<PersonListener> personListeners = new ArrayList<PersonListener>();
        public void addPersonListener(PersonListener listener) {
            personListeners.add(listener);
        }
        private void notifyPersonListeners(Person person) {
            for(PersonListener listener: personListeners) {
                listener.personCreated(person);
            }
        }
            //... где-то в обработчике кнопки, в котором создается Person
            Person person = new Person();
            ...
            notifyPersonListeners(person);
    }
    
  3. В основном потоке слушаем создание Person

    RegistrationFrame registrationFrame = new RegistrationFrame();
    registrationFrame.addPersonListener(new PersonListener() {
        @Override
        void personCreated(Person person) {
            System.out.println(person.toString());
        }
    }
    

Так код по обработке новых объектов будет вызываться только при их создании. В реализацию PersonListener можно вшить вызов другого потока, если требуется.

READ ALSO
Google map APIv2 работает на Android 5.1, но не работает на 6.0.1

Google map APIv2 работает на Android 5.1, но не работает на 6.0.1

Столкнулся с этой проблемой при компиляции программы на реальном устройстве 60

338
Работа с json. Локализация

Работа с json. Локализация

Хочу реализовать систему выбора языкового файла для перевода текстаПолучил язык установленный в клиенте у игрока

275
Как правильно настроить criteria

Как правильно настроить criteria

Есть 2 сущности связанные многие-ко-многимЕсли я хочу получить все данные то result = session

364
Почему код не проходит условие? [дубликат]

Почему код не проходит условие? [дубликат]

На данный вопрос уже ответили:

266