处理 Java RCP 应用程序中工作台窗口的关闭

发布于 2024-12-07 21:19:36 字数 3982 浏览 0 评论 0原文

我正在编写一个 Eclipse RCP,我想询问用户在应用程序关闭时是否备份数据库。从“文件”>“退出”菜单中执行此操作很容易,因为我定义了一个命令退出:

public class ExitCommand extends AbstractHandler implements IHandler {

@Override
public Object execute(ExecutionEvent event) throws ExecutionException {
    final IWorkbench workbench = PlatformUI.getWorkbench();
    if (workbench == null)
        return null;

    // Ask whether the user wants to back up the information
    Shell shell = new Shell(workbench.getDisplay());
    MessageBox messageBox = new MessageBox(shell, SWT.ICON_QUESTION
            | SWT.YES | SWT.NO);
    messageBox.setMessage("You are leaving CatSysPD. Do you want to make a backup of the DataBase? (recommended)");
    messageBox.setText("On Exit Backup");
    int response = messageBox.open();
    if (response == SWT.YES){
        new BackupDataBaseAction(shell);
    }

    final Display display = workbench.getDisplay();
    display.syncExec(new Runnable() {
        public void run() {
            if (!display.isDisposed())
                workbench.close();
        }
    });
    return null;
}}

然后我将其链接到一个名为“退出”的菜单条目,并且此操作正确。但是,用户也可以通过按“关闭窗口”按钮来关闭应用程序。有什么办法可以捕捉到这个事件吗?

我在上一个主题中找到了一条建议(请参阅此处) 使用 shutdownHook。然而,我想要执行的线程必须打开一个对话框,据我所知,这不能由外部线程完成。

谢谢你!

编辑 我在此处添加我正在使用的 shutdownHook 的代码。在应用程序类中: public class Application Implements IApplication {

final double NIDAQmxPortingVersionDependency = 1.001;

public final static String PLUGIN_ID = "CatsysPD";
private static Logger logger = Logger.getLogger(Application.class
        .toString());

/*
 * (non-Javadoc)
 * 
 * @see org.eclipse.equinox.app.IApplication#start(org.eclipse.equinox.app.
 * IApplicationContext)
 */
public Object start(IApplicationContext context) {
    logger.info("Starting the application");
    Display display = PlatformUI.createDisplay();
    systemCheck(display);
    initializeApplication(display);
    try {
        int returnCode = PlatformUI.createAndRunWorkbench(display,
                new ApplicationWorkbenchAdvisor());
        if (returnCode == PlatformUI.RETURN_RESTART) {
            return IApplication.EXIT_RESTART;
        }
        BackupOnExitHook backupOnExitHook = new BackupOnExitHook(PlatformUI.getWorkbench().getDisplay());
        Runtime.getRuntime().addShutdownHook(backupOnExitHook);
        return IApplication.EXIT_OK;
    } finally {
        display.dispose();
    }
}

private void systemCheck(Display display) {...}

public void stop() {...}

public void initializeApplication(Display display) {...}

private class BackupOnExitHook extends Thread {

    private Display display;

    public BackupOnExitHook(Display display){
        this.display = display;
    }

    @Override
    public void run(){
        display.syncExec(new Runnable(){

            @Override
            public void run() {
                MessageBox messageBox = new MessageBox(new Shell(display), SWT.ICON_QUESTION
                        | SWT.YES | SWT.NO);
                messageBox.setMessage("You are leaving CatSysPD. Do you want to make a backup of the DataBase? (recommended)");
                messageBox.setText("On Exit Backup");
                int response = messageBox.open();
                if (response == SWT.YES){
                    new BackupDataBaseAction(new Shell(display));
                }
            }});


    }

}
}

当我尝试运行它时得到的错误是:

Exception in thread "Thread-5" org.eclipse.swt.SWTException: Device is disposed
at org.eclipse.swt.SWT.error(SWT.java:4083)
at org.eclipse.swt.SWT.error(SWT.java:3998)
at org.eclipse.swt.SWT.error(SWT.java:3969)
at org.eclipse.swt.widgets.Display.error(Display.java:1249)
at org.eclipse.swt.widgets.Display.syncExec(Display.java:4581)
at dk.catsys.pd.Application$BackupOnExitHook.run(Application.java:128)

再次感谢。

I'm writing an Eclipse RCP and I want to ask the user whether to backup the database when the application is closed. Doing it from the File>Exit menu was easy as I defined a command exit:

public class ExitCommand extends AbstractHandler implements IHandler {

@Override
public Object execute(ExecutionEvent event) throws ExecutionException {
    final IWorkbench workbench = PlatformUI.getWorkbench();
    if (workbench == null)
        return null;

    // Ask whether the user wants to back up the information
    Shell shell = new Shell(workbench.getDisplay());
    MessageBox messageBox = new MessageBox(shell, SWT.ICON_QUESTION
            | SWT.YES | SWT.NO);
    messageBox.setMessage("You are leaving CatSysPD. Do you want to make a backup of the DataBase? (recommended)");
    messageBox.setText("On Exit Backup");
    int response = messageBox.open();
    if (response == SWT.YES){
        new BackupDataBaseAction(shell);
    }

    final Display display = workbench.getDisplay();
    display.syncExec(new Runnable() {
        public void run() {
            if (!display.isDisposed())
                workbench.close();
        }
    });
    return null;
}}

I then linked this to a menu entry called Exit and this work right. However the user could close the application also by pressing the "close window" button. Is there any way of catching this event?

I found a suggestion in a previous topic (see here) using a shutdownHook. However the thread that I want execute has to open a dialog and, as I understand, this cannot be done by an external thread.

Thank you!

Edit
I add here the code for the shutdownHook I'm using. In the Application class:
public class Application implements IApplication {

final double NIDAQmxPortingVersionDependency = 1.001;

public final static String PLUGIN_ID = "CatsysPD";
private static Logger logger = Logger.getLogger(Application.class
        .toString());

/*
 * (non-Javadoc)
 * 
 * @see org.eclipse.equinox.app.IApplication#start(org.eclipse.equinox.app.
 * IApplicationContext)
 */
public Object start(IApplicationContext context) {
    logger.info("Starting the application");
    Display display = PlatformUI.createDisplay();
    systemCheck(display);
    initializeApplication(display);
    try {
        int returnCode = PlatformUI.createAndRunWorkbench(display,
                new ApplicationWorkbenchAdvisor());
        if (returnCode == PlatformUI.RETURN_RESTART) {
            return IApplication.EXIT_RESTART;
        }
        BackupOnExitHook backupOnExitHook = new BackupOnExitHook(PlatformUI.getWorkbench().getDisplay());
        Runtime.getRuntime().addShutdownHook(backupOnExitHook);
        return IApplication.EXIT_OK;
    } finally {
        display.dispose();
    }
}

private void systemCheck(Display display) {...}

public void stop() {...}

public void initializeApplication(Display display) {...}

private class BackupOnExitHook extends Thread {

    private Display display;

    public BackupOnExitHook(Display display){
        this.display = display;
    }

    @Override
    public void run(){
        display.syncExec(new Runnable(){

            @Override
            public void run() {
                MessageBox messageBox = new MessageBox(new Shell(display), SWT.ICON_QUESTION
                        | SWT.YES | SWT.NO);
                messageBox.setMessage("You are leaving CatSysPD. Do you want to make a backup of the DataBase? (recommended)");
                messageBox.setText("On Exit Backup");
                int response = messageBox.open();
                if (response == SWT.YES){
                    new BackupDataBaseAction(new Shell(display));
                }
            }});


    }

}
}

The error I get when I try to run it is:

Exception in thread "Thread-5" org.eclipse.swt.SWTException: Device is disposed
at org.eclipse.swt.SWT.error(SWT.java:4083)
at org.eclipse.swt.SWT.error(SWT.java:3998)
at org.eclipse.swt.SWT.error(SWT.java:3969)
at org.eclipse.swt.widgets.Display.error(Display.java:1249)
at org.eclipse.swt.widgets.Display.syncExec(Display.java:4581)
at dk.catsys.pd.Application$BackupOnExitHook.run(Application.java:128)

Thanks again.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文