当用户在窗口右上方点击“ X”时,无法停止JFrame的关闭

时间:2018-08-24 12:30:49

标签: java swing groovy griffon

我正在尝试获取一个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 :(得分:0)

解决此问题的一种方法是使用https://github.com/aalmiray/griffon-examples/tree/master/shutdown所示的ShutdownHandler

该特定示例使用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