How to properly hide editors, when switching between perspectives in eclipse rcp application
Join the DZone community and get the full member experience.
Join For FreeLong story short... In Eclipse RCP application it is not possible to hide editors, which are currently opened, when switching between perspectives. "Not possible" means, that it is not built in functionality (as for views), so it is needed to hack in order to make it working (hacking is always good, right?). Unfortunately, it brings some troubles and therefore more hacks. But still, if you need it, it should be done.
So, there is already a pretty good blog post about hiding editors: http://www.niallkelly.com/?p=1 . Unfortunately, if you make your editors to be persisted into memento, and then restored, when application is restarted, you will find an empty perspective. I spent some time, debugging the process, how editors are restored, but the answer was simple:
This code snippet the cruel job. Apparently, we don't want it to work like that and will try to improve it. In order to restore an editor from the memento we need to create an EditorInput object. We could use this object afterwards to check, if this editor is restored from memento or not (we still like hacks, right?:S), if so, we will not hide it:
Another problem was in this code snippet:
I hope that it will help someone. Any ideas/comments are very welcome.
Cheers,
AlexG
So, there is already a pretty good blog post about hiding editors: http://www.niallkelly.com/?p=1 . Unfortunately, if you make your editors to be persisted into memento, and then restored, when application is restarted, you will find an empty perspective. I spent some time, debugging the process, how editors are restored, but the answer was simple:
perspectiveActivated() { ... // Hide all the editors IEditorReference[] editors = page.getEditorReferences(); for (int i = 0; i < editors.length; i++) { page.hideEditor(editors[i]); } .. }
This code snippet the cruel job. Apparently, we don't want it to work like that and will try to improve it. In order to restore an editor from the memento we need to create an EditorInput object. We could use this object afterwards to check, if this editor is restored from memento or not (we still like hacks, right?:S), if so, we will not hide it:
// Hide all editors final IEditorReference[] editorReferences = workbenchPage.getEditorReferences(); for (final IEditorReference editorReference : editorReferences) { try { final IEditorInput editorInput = editorReference.getEditorInput(); if (editorInput instanceof AbstractBEEditorInput) { final AbstractBEEditorInput abstractBEEditorInput = (AbstractBEEditorInput) editorReference.getEditorInput(); if (!abstractBEEditorInput.isRestoredInput()) { workbenchPage.hideEditor(editorReference); } else { abstractBEEditorInput.setRestoredInput(false); } } } catch (final PartInitException e) { // log } }For sure, this not seem to be the most elegant solution, but still it can be used.
Another problem was in this code snippet:
// Find the editor reference that relates to this editor input IEditorReference[] editorRefs = page.findEditors(editorInput, null, IWorkbenchPage.MATCH_INPUT); if (editorRefs.length > 0) { editors.add(editorRefs[0]); perspectiveEditors.put(activePerspective.getId(), editors); }Sometimes it can not find editors by input (for me the reason was in overrided "equals" method in AbstractBEEditorInput object, which didn't work as excpected to match input).That is why I had to fix partOpened method to always find all opened editors:
public void partOpened(final IWorkbenchPart workbenchPart) { if (workbenchPart instanceof EditorPart) { final EditorPart editorPart = (EditorPart) workbenchPart; final IWorkbenchPage workbenchPage = editorPart.getSite().getPage(); final IPerspectiveDescriptor activePerspective = workbenchPage.getPerspective(); allEditorReferences = perspectiveIdToEditorReferencesMap.get(activePerspective.getId()); if (allEditorReferences == null) { allEditorReferences = new CopyOnWriteArrayList<IEditorReference>(); perspectiveIdToEditorReferencesMap.put(activePerspective.getId(), allEditorReferences); } // store editors, which are opened in current perspective allEditorReferences.addAll(Arrays.asList(workbenchPage.getEditorReferences())); } }The trick here is to have maps and lists from concurrent package. It is needed to avoid ConcurrentModificationException, which can occur, when application is restarted and you immediately switch perspective. I have fixed it in the following way:
private List<IEditorReference> allEditorReferences = new CopyOnWriteArrayList<IEditorReference>(); private final Map<String, List<IEditorReference>> perspectiveIdToEditorReferencesMap = new ConcurrentHashMap<String, List<IEditorReference>>(); private final HashMap<String, IEditorReference> perspectiveIdToLastActiveEditorMap = new HashMap<String, IEditorReference>(); ... synchronized (perspectiveIdToEditorReferencesMap) { allEditorReferences = perspectiveIdToEditorReferencesMap.get(perspectiveId); if (allEditorReferences != null) { synchronized (allEditorReferences) { for (final IEditorReference editorReference : allEditorReferences) { final IEditorInput editorInput = editorReference.getEditorInput(); workbenchPage.showEditor(editorReference); } } }
I hope that it will help someone. Any ideas/comments are very welcome.
Cheers,
AlexG
application
Eclipse
Opinions expressed by DZone contributors are their own.
Trending
-
How To Use Pandas and Matplotlib To Perform EDA In Python
-
Top 10 Engineering KPIs Technical Leaders Should Know
-
Microservices Decoded: Unraveling the Benefits, Challenges, and Best Practices for APIs
-
Building and Deploying Microservices With Spring Boot and Docker
Comments