Как уведомить Главную Теаду от actionEventListner - PullRequest
1 голос
/ 24 июня 2019

Я создаю новый объект JFrame в главном потоке и вызываю его функцию, которая вызывает wait (). Я хочу разбудить эту Основную тему.

  public static void main(String[] args) throws Exception {
        //some other large code
        var loginWin = new LoginWin();
        loginWin.setVisible(true);
        loginWin.waitForLogin();
        System.out.println("Login Finished");
        //code after login

    }

LoginWin расширяет JFrame и имеет кнопку, у которой есть действие Listener, подобное этому

    login.bsubmit.addActionListener(actionEvent -> {
        dataRecived();
    });

dataRecived () Функция: -

private void dataRecived() {

    passwd = login.passwd.getPassword();
    username = login.username.getText();
    iphost = login.iphost.getText();
    port = 9999;
    try {
        Integer.parseInt(login.port.getText());
    } catch (Exception e) {
        e.printStackTrace();
    }
    notify();
}

но когда я нажимаю кнопку login.bsubmit, я получаю следующее исключение: -

Exception in thread "AWT-EventQueue-0" java.lang.IllegalMonitorStateException
    at java.base/java.lang.Object.notify(Native Method)
    at smit.quiz.server.LoginWin.dataRecived(LoginWin.java:52)
    at smit.quiz.server.LoginWin.lambda$new$1(LoginWin.java:34)
    at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1967)
    at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2308)
    at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
    at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
    at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279)
    at java.desktop/java.awt.Component.processMouseEvent(Component.java:6632)
    at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3342)
    at java.desktop/java.awt.Component.processEvent(Component.java:6397)
    at java.desktop/java.awt.Container.processEvent(Container.java:2263)
    at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5008)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2321)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4840)
    at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4918)
    at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4547)
    at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4488)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2307)
    at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2762)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4840)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:772)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:389)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:743)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:389)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
    at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
    at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

1 Ответ

2 голосов
/ 24 июня 2019

Это исключение выдается, потому что вы вызываете Object.notify () без "удержания монитора объектов", то есть извне блока synchronized или метода экземпляра с модификатором synchronized:

Этот метод должен вызываться только потоком, который является владельцем монитора этого объекта. Поток становится владельцем монитора объекта одним из трех способов:

  • Путем выполнения метода синхронизированного экземпляра этого объекта.
  • Выполняя тело синхронизированного оператора, который синхронизируется на объекте.
  • Для объектов типа Class, путем выполнения синхронизированного статического метода этого класса.

Только один поток одновременно может владеть монитором объекта.

Выдает:
IllegalMonitorStateException - если текущий поток не является владельцем монитора этого объекта.


Тем не менее, плохая идея пытаться модифицировать объекты свинга из других потоков способами, для которых они явно не предназначены, см. Документы свинг-пакета :

Политика потоков Swing

Как правило, Swing не безопасен для потоков. Все компоненты Swing и связанные классы, если не указано иное, должен быть доступен в потоке диспетчеризации событий.

[...]

Поскольку все события доставляются в потоке диспетчеризации событий, необходимо соблюдать осторожность при обработке событий. В частности, долго выполняющаяся задача, такая как сетевая или интенсивная обработка, выполняемая в потоке диспетчеризации событий, блокирует поток диспетчеризации событий от отправки любых других событий. Пока поток диспетчеризации событий заблокирован, приложение полностью не реагирует на ввод данных пользователем. Обратитесь к SwingWorker для предпочтительного способа сделать такую ​​обработку при работе с Swing.

Дополнительную информацию по этой теме можно найти в учебнике Swing , в частности в разделе Параллельность в Swing .

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

...