我的问题是我有一个使用EditorParts的自定义应用程序,该应用程序保留在数据库中。用户可以打开多个编辑器,并在它们之间切换。我需要让用户在切换到下一个编辑器之前将所有未保存的更改保存在编辑器中(否则将其关闭)。
我创建了一个IPartListener2,并且收到partDeactivated通知。如果isDirty()== true,我弹出一个MessageDialog询问是否保存;因为我想调用editor.doSave()。
我的问题是那行不通。我再也看不到MessageDialog,因为会触发另一个partDeactivated。我想这是由编辑器上的MessageDialog引起的。
我已经研究过How to listen to lose focus event of a part in 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();
}
}
答案 0 :(得分:1)
您可能需要在deactivate事件结束后运行代码。您可以使用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。
答案 1 :(得分:0)
使用上述建议和Enumerating all my Eclipse editors?,我找到了一个很好的解决方案 我先检查所有编辑器,然后检查所有持久性编辑器-跳过自身和持久性对象。
感谢您的评论!
public class ConceptAcronymValidator implements IValidator {
private ConceptInstanceEditor myEditor;
public ConceptAcronymValidator(ConceptInstanceEditor editor) {
super();
this.myEditor = editor;
}
@Override
public IStatus validate(Object value) {
// check all Editors
for (IEditorReference editorRef: PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getEditorReferences()) {
IEditorPart editor = editorRef.getEditor(false);
if (editor != null) {
// don't check our own Editor
if (!editor.equals(myEditor)) {
ConceptInstanceEditor conceptEditor = (ConceptInstanceEditor)editor;
if (conceptEditor.getTxtAcronym().equals(value.toString())) {
return ValidationStatus.error("This Concept is already used by Editor <"+
conceptEditor.getConceptModel().getName().getValue(MultilingualString.EN)+
">");
}
}
}
}
// check all persisted Concepts
List<Concept> concepts = ReferenceServiceFactory.getService().getConcepts();
for (Concept concept: concepts) {
Concept myConcept = (Concept) myEditor.getConceptModel().getInstance();
// check if a new Editor
if (myConcept == null) {
if (concept.getAcronym().equals(value.toString())) {
return ValidationStatus.error("This Concept is already used by <"+
concept.getName().getValue(MultilingualString.EN)+
">");
}
}
else {
// don't check own Instance
if (!concept.equals(myConcept)) {
if (concept.getAcronym().equals(value.toString())) {
return ValidationStatus.error("This Concept is already used by <"+
concept.getName().getValue(MultilingualString.EN)+
">");
}
}
}
}
return Status.OK_STATUS;
}
}