Не удается остановить закрытие JFrame, когда пользователь нажимает «X» в правом верхнем углу окна

Я пытаюсь заставить проект groovy / griffon запрашивать пользователя перед закрытием главного окна. В Интернете есть множество примеров этого, и это кажется довольно простым: установите defaultCloseOperation на DO_NOTHING_ON_CLOSE, а затем пропустите вызов application.shutdown ().

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

Ниже показано начало кода создания представления:

@ArtifactProviderFor(GriffonView)
class TceView  {
  JFrame mainFrame 
  ...
  masterPage = builder.with {
    def masterApp = application(size: [890, 700], id: 'mainWindow',minimumSize: [890, 700],//[890, 700]
         title: application.configuration['application.title'] + " " + Launcher.version,
         iconImage: imageIcon('/tce_1.png').image,
         iconImages: [imageIcon('/tce_1.png').image,
                      imageIcon('/tce_1.png').image,
                      imageIcon('/tce_1.png').image],
         defaultCloseOperation: WindowConstants.DO_NOTHING_ON_CLOSE,
         windowClosing: { evt ->
             mainFrame = evt.source
             println("In windowClosing")

             // The below is to check to see if our frame is invisible or destroyed.  
             // It turns out that mainFrame is undefined when the timer ticks.
             def timer = new Timer(5000, new ActionListener() {
                 @Override
                 void actionPerformed(ActionEvent e) {
                     mainFrame.setVisible(true)
                 }
             })
             timer.start()

             if (false)
                 application.shutdown()
      }) {
      // all the other code
  }
}

В приведенном выше коде, если я устанавливаю application.shutdown () для запуска, программа завершается, когда в правом верхнем углу окна нажимается «x». Если пропустить application.shutdown (), окно закроется, но программа все еще будет запущена при нажатии «x».

Заранее благодарим за любую помощь, которую вы можете оказать!

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
52
1

Ответы 1

Один из способов решить эту проблему - использовать ShutdownHandler, как показано на https://github.com/aalmiray/griffon-examples/tree/master/shutdown.

В этом конкретном примере используются JavaFX и Java, но базовый код может быть переведен на Swing и Groovy.

Во-первых, необходимо определить реализацию интерфейса ShutdownHandler, подобную этой.

package org.kordamp.griffon.examples.shutdown;

import griffon.core.GriffonApplication;
import griffon.core.ShutdownHandler;
import griffon.core.i18n.MessageSource;
import griffon.core.threading.UIThreadManager;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;

import javax.annotation.Nonnull;
import javax.inject.Inject;
import javax.inject.Named;

public class MyShutdownHandler implements ShutdownHandler {
    private final MessageSource messageSource;
    private final UIThreadManager uiThreadManager;

    @Inject
    public MyShutdownHandler(@Nonnull @Named("applicationMessageSource") MessageSource messageSource, @Nonnull UIThreadManager uiThreadManager) {
        this.messageSource = messageSource;
        this.uiThreadManager = uiThreadManager;
    }

    @Override
    public boolean canShutdown(@Nonnull GriffonApplication application) {
        return uiThreadManager.runInsideUISync(() -> {
            Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
            alert.setTitle(msg(".alert.title"));
            alert.setHeaderText(msg(".alert.header"));
            alert.setContentText(msg(".alert.content"));
            return alert.showAndWait().orElse(ButtonType.CANCEL) != ButtonType.CANCEL;
        });
    }

    private String msg(String key) {
        return messageSource.getMessage(getClass().getName() + key);
    }

    @Override
    public void onShutdown(@Nonnull GriffonApplication application) {
        System.out.println("Saving workspace ...");
    }
}

Интерфейс ShutdownHandler определяет 2 метода, которые необходимо реализовать.

  1. canShutdown() возвращает истину, если процедура выключения может продолжаться, или ложь, чтобы остановить ее.
  2. onShutdown() выполняет определенную очистку при выполнении процедуры выключения.

В вашем случае вы реализуете первый метод с кодом, аналогичным тому, который у вас есть в обработчике windowClosing.

Последний бит - это регистрация этого обработчика завершения работы в приложении, вы можете сделать это в любое время, когда у вас есть доступ к экземпляру application. Вы можете сделать это в контроллере, обработчике событий или сценарии жизненного цикла. Ссылка, показанная ранее, выполняет эту регистрацию с помощью обработчика событий. Взгляните на ApplicationModule, найденный в этом примере.

Другие вопросы по теме