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

Я пытаюсь заставить проект 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'.

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

1 Ответ

0 голосов
/ 25 августа 2018

Один из способов решить эту проблему - использовать 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() возвращает значение true, если процедура выключения может продолжаться, или значение false, чтобы остановить его.
  2. onShutdown() выполнить определенную очистку при выполнении процедуры выключения.

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

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

...