首页 > 解决方案 > Eclipse EditorPart 保存在 partDeactivated 上

问题描述

我的问题是我有一个自定义应用程序,使用 EditorParts,它被持久化到数据库中。用户可以打开多个编辑器,并在它们之间切换。在切换到下一个编辑器(或关闭它)之前,我需要要求用户在编辑器中保存任何未保存的更改。

我创建了一个 IPartListener2,并收到了 partDeactivated 通知。如果 isDirty()==true,我会弹出一个 MessageDialog 询问是否保存;因为我想调用 editor.doSave()。

我的问题是这不起作用。我从来没有看到 MessageDialog,因为另一个 partDeactivated 触发。我猜,这是由编辑器上的 MessageDialog 引起的。

我研究了如何在 Eclipse E4 RCP 中收听失去焦点事件的一部分?,但这对我没有帮助。

感谢帮助 e4 初学者

public class DatasetAttachmentEditor {
        ... // code here
    @Override
    public void init(IEditorSite site, IEditorInput input)  throws PartInitException {
        ... // code here
        site.getPage().addPartListener(new EditorsPartListener(this));
    }
}

public class EditorsPartListener implements IPartListener2 {

    private IEditorPart editor;

    public EditorsPartListener(IEditorPart editor) {
        this.editor = editor;
    }

    @Override
    public void partClosed(IWorkbenchPartReference partRef) {
        if (partRef.getPage().getActiveEditor().getClass().getName().equals(editor.getClass().getName())) {
            partRef.getPage().removePartListener(this);
        }
    }

    @Override
    public void partDeactivated(IWorkbenchPartReference partRef) {

        if (!partRef.getClass().getName().equals("org.eclipse.ui.internal.EditorReference")) {
            System.out.println("partDeactivated: not a Editor="+partRef.getClass().getName());
            return;
        }

        if (!editor.isDirty()) {
            // if the editor is not dirty - do nothing
            return;
        }

        // ask if to save
        int choice = EditorPartSaveDialog(partRef.getPage().getActiveEditor());
        if(choice == MessageDialog.OK) {
            // save the Editor
            try {
                ProgressMonitorDialog progress = new ProgressMonitorDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());                
                progress.setCancelable(false);
                progress.run(false, false, new IRunnableWithProgress() {
                    @Override
                    public void run(IProgressMonitor monitor) {
                        // do the save
                        editor.doSave(monitor);
                    }
                });
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
        else {
            // don't save: just close it
            partRef.getPage().closeEditor(editor, false);
        }
    }

    @Override
    public void partActivated(IWorkbenchPartReference partRef) {
    }

    @Override
    public void partBroughtToTop(IWorkbenchPartReference partRef) {
    }

    @Override
    public void partOpened(IWorkbenchPartReference partRef) {
    }

    @Override
    public void partHidden(IWorkbenchPartReference partRef) {
    }

    @Override
    public void partVisible(IWorkbenchPartReference partRef) {
    }

    @Override
    public void partInputChanged(IWorkbenchPartReference partRef) {
    }

    /**
     * Asks the user to Save changes
     * @param editor
     * @return MessageDialog.OK to save, MessageDialog.CANCEL otherwise
     */
    private int EditorPartSaveDialog(IEditorPart editor) {

        // If save confirmation is required ..
        String message = NLS.bind("''{0}'' has been modified. Save changes?", LegacyActionTools.escapeMnemonics(editor.getTitle()));

        // Show a dialog.
        MessageDialog d = new MessageDialog(
                            Display.getCurrent().getActiveShell(),
                            "Save Editor", null, message,
                            MessageDialog.QUESTION,
                            0,
                            "Save",// MessageDialog 0x0 (OK)
                            "Don't Save: close"// MessageDialog 0x1 (CANCEL)
                        )
        return d.open();
    }
}

标签: eclipsefocuseclipse-rcp

解决方案


您可能需要在停用事件完成后运行您的代码。您可以使用Display.asyncExec.

就像是:

@Override
public void partDeactivated(IWorkbenchPartReference partRef) {

    if (!partRef.getClass().getName().equals("org.eclipse.ui.internal.EditorReference")) {
        System.out.println("partDeactivated: not a Editor="+partRef.getClass().getName());
        return;
    }

    if (!editor.isDirty()) {
        // if the editor is not dirty - do nothing
        return;
    }

    Display.getDefault().asyncExec(() ->
      {
        // TODO the rest of your deactivate code goes here
      });
}

(以上代码假设您使用的是 Java 8 或更高版本)

这是 3.x 兼容模式代码,而不是 e4。


推荐阅读