Table Of Content
Simple Eclipse RCP 3 Application - View and Editor integration
View more Tutorials:
The document was written based on:
-
Eclipse: 4.4 (LUNA)
In this document, I will create an RCP application with advanced functionality. The basics of RCP will not be repeated. So if you're a beginner with RCP you should preview the document "RCP for beginners" before practicing this tutorial.
The problem is mentioned:
- Whenever you make data changes on the Editor, SAVE button will Enabled to allow users to click to save the data. Handling the data saving of Editor.
- View displays a list of departments. Users click to select one department on this View, it will be displayed on the Editor.
- Re- updates View when the data on Editor changes.
We quickly create a RCPTarget project, which used to declare RCP libraries and runtime environment.
- File/New/Project


- File/New/Other...







Enter:
- Name: Eclipse RCP
- Location: http://download.eclipse.org/eclipse/updates/4.4/


Click "Set as Target Platform" for libraries take effect on the entire project within the workspace.

Quick create a RCP Workbench project.
- File/New/Other...

Enter:
- Project Name: RCPApplication

Enter:
- Activator: org.o7planning.tutorial.rcpapplication.Activator


Enter:
- Package Name: org.o7planning.tutorial.rcpapplication

Project has been created:

You can test by right-clicking on the project, and select Run As/Eclipse Application.


This is an image after completing Project.

Normally you can create Menu Items, Toolbar Items from the Commands, declared in plugin.xml. However, you can also create them through customized Action class, or Action(s) available in the RCP Workbench library.
ApplicationActionBarAdvisor.java
package org.o7planning.tutorial.rcpapplication; import org.eclipse.jface.action.ICoolBarManager; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.ToolBarManager; import org.eclipse.swt.SWT; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.actions.ActionFactory; import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; import org.eclipse.ui.application.ActionBarAdvisor; import org.eclipse.ui.application.IActionBarConfigurer; public class ApplicationActionBarAdvisor extends ActionBarAdvisor { private IWorkbenchAction saveAction; private IWorkbenchAction exitAction; private IWorkbenchAction aboutAction; public ApplicationActionBarAdvisor(IActionBarConfigurer configurer) { super(configurer); } @Override protected void makeActions(IWorkbenchWindow window) { saveAction = ActionFactory.SAVE.create(window); this.register(saveAction); exitAction = ActionFactory.QUIT.create(window); this.register(exitAction); aboutAction = ActionFactory.ABOUT.create(window); this.register(aboutAction); super.makeActions(window); } @Override protected void fillMenuBar(IMenuManager menuBar) { // File MenuManager fileMenu = new MenuManager("&File", "file"); menuBar.add(fileMenu); fileMenu.add(exitAction); // Help MenuManager helpMenu = new MenuManager("&Help", "help"); menuBar.add(helpMenu); helpMenu.add(aboutAction); super.fillMenuBar(menuBar); } @Override protected void fillCoolBar(ICoolBarManager coolBar) { IToolBarManager toolBar1 = new ToolBarManager(SWT.FLAT | SWT.RIGHT ); toolBar1.add(saveAction); coolBar.add(toolBar1); IToolBarManager toolBar2 = new ToolBarManager(SWT.FLAT | SWT.RIGHT ); toolBar2.add(exitAction); coolBar.add(toolBar2); } }

Data Model:
Department.java
package org.o7planning.tutorial.rcpapplication.model; public class Department { private Integer deptId; private String deptNo; private String deptName; private String location; public Department() { } public Department(Integer deptId, String deptNo, String deptName, String location) { this.deptId = deptId; this.deptNo = deptNo; this.deptName = deptName; this.deptName = deptName; } public Integer getDeptId() { return deptId; } public void setDeptId(Integer deptId) { this.deptId = deptId; } public String getDeptNo() { return deptNo; } public void setDeptNo(String deptNo) { this.deptNo = deptNo; } public String getDeptName() { return deptName; } public void setDeptName(String deptName) { this.deptName = deptName; } public String getLocation() { return location; } public void setLocation(String location) { this.location = location; } }
DepartmentDAO.java
package org.o7planning.tutorial.rcpapplication.model; import java.util.ArrayList; import java.util.List; public class DepartmentDAO { private static final List<Department> list = new ArrayList<Department>(); static { list.add(new Department(10, "D10", "ACCOUNTING", "NEW YORK")); list.add(new Department(20, "D20", "RESEARCH", "DALLAS")); list.add(new Department(30, "D30", "SALES", "CHICAGO")); list.add(new Department(40, "D40", "OPERATIONS", "BOSTON")); } public static List<Department> listDepartment() { return list; } public static int getMaxDeptId() { int max = 0; for (Department dept : list) { if (dept.getDeptId() > max) { max = dept.getDeptId(); } } return max; } public static Department findDepartment(int deptId) { for (Department dept : list) { if (dept.getDeptId() == deptId) { return dept; } } return null; } public static Department findDepartment(String deptNo) { for (Department dept : list) { if (dept.getDeptNo().equals(deptNo)) { return dept; } } return null; } public static void deleteDepartment(int deptId) { Department dept = findDepartment(deptId); if (dept == null) { return; } list.remove(dept); } public static Department updateDepartment(int deptId, String deptNo, String deptName, String location) throws DataException { Department dept = findDepartment(deptId); if (dept == null) { return null; } Department dept2 = findDepartment(deptNo); if (dept2 != null && dept2.getDeptId().intValue() != dept.getDeptId()) { throw new DataException("Unique Constraints error - deptNo: " + deptNo); } dept.setDeptNo(deptNo); dept.setDeptName(deptName); dept.setLocation(location); return dept; } public static Department insertDepartment(String deptNo, String deptName, String location) throws DataException { Department dept = findDepartment(deptNo); if (dept != null) { throw new DataException("Unique Constraints error - deptNo: " + deptNo); } dept = new Department(); int deptId = getMaxDeptId() + 1; dept.setDeptId(deptId); dept.setDeptNo(deptNo); dept.setDeptName(deptName); dept.setLocation(location); list.add(dept); return dept; } }
DataException.java
package org.o7planning.tutorial.rcpapplication.model; public class DataException extends Exception { private static final long serialVersionUID = 7155764478659670087L; public DataException(String message) { super(message); } }
Command:
DeptCommand.java
package org.o7planning.tutorial.rcpapplication.command; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IEditorReference; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PartInitException; import org.eclipse.ui.handlers.HandlerUtil; import org.o7planning.tutorial.rcpapplication.editor.DeptEditor; import org.o7planning.tutorial.rcpapplication.editor.DeptEditorInput; import org.o7planning.tutorial.rcpapplication.model.Department; public class DeptCommand extends AbstractHandler { public static final String ID = "command.dept"; @Override public Object execute(ExecutionEvent event) throws ExecutionException { // get the page IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event); IWorkbenchPage page = window.getActivePage(); // get the selection ISelection selection = HandlerUtil.getCurrentSelection(event); Object selectObj = null; // Having selected on DeptListView if (selection != null && !selection.isEmpty() && selection instanceof IStructuredSelection ) { selectObj = ((IStructuredSelection) selection).getFirstElement(); } // No Selection on DeptListView // (Create new Department). else { // Create new Department. selectObj = new Department(); } Department dept = (Department) selectObj; DeptEditorInput input = new DeptEditorInput(dept); boolean found = false; // Opening Editor references IEditorReference[] eRefs = page.getEditorReferences(); for (IEditorReference ref : eRefs) { IEditorPart editor = ref.getEditor(false); if (editor != null && editor instanceof DeptEditor) { // Restore DeptEditor deptEditor = (DeptEditor) ref.getEditor(true); found = true; boolean saved = true; // If editor is dirty, save it. if (deptEditor.isDirty()) { saved = page.saveEditor(deptEditor, true); } if (saved) { // Reset input for DeptEditor. page.reuseEditor(deptEditor, input); deptEditor.showData(); } } } if (!found) { try { page.openEditor(input, DeptEditor.ID); } catch (PartInitException e) { throw new RuntimeException(e); } } return null; } }
MyConstants.java
package org.o7planning.tutorial.rcpapplication.constant; public class MyConstants { public static final int EDITOR_DATA_CHANGED = 999999; }
Editor
AbstractBaseEditor.java
package org.o7planning.tutorial.rcpapplication.editor; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IEditorSite; import org.eclipse.ui.PartInitException; import org.eclipse.ui.part.EditorPart; import org.o7planning.tutorial.rcpapplication.constant.MyConstants; import org.o7planning.tutorial.rcpapplication.other.DirtyListener; import org.o7planning.tutorial.rcpapplication.other.DirtyUtils; public abstract class AbstractBaseEditor extends EditorPart { private boolean dirty; // Will be called before createPartControl @Override public void init(IEditorSite site, IEditorInput input) throws PartInitException { // Very Important!! setSite(site); setInput(input); } // When PROP_DIRTY change, this method will be called by the Workbench. // If the method returns true, the SAVE button will enabled, else disable. @Override public boolean isDirty() { return this.dirty; } // When changing the data editor, call this method to notify to Workbench. protected void setDirty(boolean dirty) { if (this.dirty != dirty) { this.dirty = dirty; // Notify PROP_DIRTY changes to Workbench. this.firePropertyChange(IEditorPart.PROP_DIRTY); } } @Override public void doSaveAs() { } @Override public boolean isSaveAsAllowed() { return false; } @Override public void setFocus() { } // Write code in createPartControl2(Composite) @Override public final void createPartControl(Composite parent) { this.createPartControl2(parent); this.showData(); this.setDirty(false); this.firePropertyChange(MyConstants.EDITOR_DATA_CHANGED); Control[] controls = this.registryDirtyControls(); DirtyListener listener = new DirtyListenerImpl(); DirtyUtils.registryDirty(listener, controls); } public abstract void showData( ); // Create controls in this method. protected abstract void createPartControl2(Composite parent); // If data in Control changed, it fire to Workbench. protected abstract Control[] registryDirtyControls(); class DirtyListenerImpl implements DirtyListener { @Override public void fireDirty() { // If has any change, fire to Editor. AbstractBaseEditor.this.setDirty(true); } } }
DeptEditor.java
package org.o7planning.tutorial.rcpapplication.editor; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IReusableEditor; import org.eclipse.ui.IWorkbenchPartConstants; import org.o7planning.tutorial.rcpapplication.constant.MyConstants; import org.o7planning.tutorial.rcpapplication.model.Department; import org.o7planning.tutorial.rcpapplication.model.DepartmentDAO; import org.o7planning.tutorial.rcpapplication.other.DirtyUtils; // IReusableEditor: Can setting new input value for this Editor. public class DeptEditor extends AbstractBaseEditor implements IReusableEditor { public static final String ID = "deptEditor"; private Integer deptId; private Text text_deptNo; private Text text_deptName; private Text text_location; public DeptEditor() { } /** * Create contents of the editor part. * * @param parent */ @Override public void createPartControl2(Composite parent) { Composite container = new Composite(parent, SWT.NONE); container.setLayout(new GridLayout(2, false)); Label lblDeptNo = new Label(container, SWT.NONE); lblDeptNo.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); lblDeptNo.setText("Dept No"); text_deptNo = new Text(container, SWT.BORDER); text_deptNo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); Label lblDeptName = new Label(container, SWT.NONE); lblDeptName.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); lblDeptName.setText("Dept Name"); text_deptName = new Text(container, SWT.BORDER); text_deptName.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); Label lblLocation = new Label(container, SWT.NONE); lblLocation.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); lblLocation.setText("Location"); text_location = new Text(container, SWT.BORDER); text_location.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); new Label(container, SWT.NONE); DirtyListenerImpl dirtyListener = new DirtyListenerImpl(); DirtyUtils.registryDirty(dirtyListener, this.text_deptName, this.text_deptNo, this.text_location); } @Override public void doSave(IProgressMonitor monitor) { try { String deptNo = this.text_deptNo.getText(); String deptName = this.text_deptName.getText(); String location = this.text_location.getText(); if (this.deptId != null) { Department dept = DepartmentDAO.updateDepartment(deptId, deptNo, deptName, location); this.setInput(new DeptEditorInput(dept)); this.setDirty(false); this.firePropertyChange(MyConstants.EDITOR_DATA_CHANGED); } else { Department dept = DepartmentDAO.insertDepartment(deptNo, deptName, location); this.setInput(new DeptEditorInput(dept)); this.setDirty(false); this.firePropertyChange(MyConstants.EDITOR_DATA_CHANGED); } } catch (Exception e) { MessageDialog.openError(this.getSite().getShell(), "Error", e.getMessage()); e.printStackTrace(); } } @Override protected Control[] registryDirtyControls() { return new Control[] { this.text_deptName, this.text_deptNo, this.text_location }; } @Override public void showData() { DeptEditorInput ip = (DeptEditorInput) this.getEditorInput(); Department dept = ip.getDept(); this.deptId = dept.getDeptId(); this.text_deptName.setText(dept.getDeptName() == null ? "" : dept .getDeptName()); this.text_deptNo.setText(dept.getDeptNo() == null ? "" : dept .getDeptNo()); this.text_location.setText(dept.getLocation() == null ? "" : dept .getLocation()); // Clear dirty. this.setDirty(false); } // Override setInput(..) with public (IReusableEditor) @Override public void setInput(IEditorInput input) { super.setInput(input); firePropertyChange(IWorkbenchPartConstants.PROP_INPUT); } public String getDeptInfo() { DeptEditorInput input = (DeptEditorInput) this.getEditorInput(); Department dept = input.getDept(); if (dept == null) { return ""; } String info = dept.getDeptNo() + " - " + dept.getDeptName() + " - " + dept.getLocation(); return info; } }
DeptEditorInput.java
package org.o7planning.tutorial.rcpapplication.editor; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IPersistableElement; import org.o7planning.tutorial.rcpapplication.model.Department; public class DeptEditorInput implements IEditorInput { private Department dept; public DeptEditorInput(Department dept) { this.dept = dept; } public Department getDept() { return dept; } @SuppressWarnings("rawtypes") @Override public Object getAdapter(Class adapter) { return null; } @Override public boolean exists() { return false; } @Override public ImageDescriptor getImageDescriptor() { return null; } @Override public String getName() { // Required!! return "Department"; } @Override public IPersistableElement getPersistable() { return null; } @Override public String getToolTipText() { // Required!! return "Department"; } }
Dirty Manager
DirtyListener.java
package org.o7planning.tutorial.rcpapplication.other; public interface DirtyListener { public void fireDirty(); }
DirtyUtils.java
package org.o7planning.tutorial.rcpapplication.other; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.events.VerifyEvent; import org.eclipse.swt.events.VerifyListener; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Text; public class DirtyUtils { public static void registryDirty(DirtyListener listener, Control... controls) { if (controls == null) { return; } for (Control control : controls) { if (control instanceof Text) { Text text = (Text) control; text.addVerifyListener(new VerifyListenerImpl(listener)); } // Checkbox or Radio button else if (control instanceof Button) { Button button = (Button) control; button.addSelectionListener(new SelectionListenerImpl(listener)); } // Not support else { throw new UnsupportedOperationException("Not support for " + control.getClass().getSimpleName()); } } } static class VerifyListenerImpl implements VerifyListener { private DirtyListener listener; public VerifyListenerImpl(DirtyListener listener) { this.listener = listener; } @Override public void verifyText(VerifyEvent arg0) { listener.fireDirty(); } } // For Button (Checkbox, Radio). static class SelectionListenerImpl implements SelectionListener { private DirtyListener listener; public SelectionListenerImpl(DirtyListener listener) { this.listener = listener; } @Override public void widgetDefaultSelected(SelectionEvent e) { } @Override public void widgetSelected(SelectionEvent e) { listener.fireDirty(); } } }
Content Provider & Label Provider:
AbstractTableContentLabelProvider.java
package org.o7planning.tutorial.rcpapplication.provider; import org.eclipse.jface.viewers.ILabelProviderListener; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.graphics.Image; public abstract class AbstractTableContentLabelProvider implements ITableLabelProvider, IStructuredContentProvider { @Override public void dispose() { } @Override public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { } @Override public void addListener(ILabelProviderListener listener) { } @Override public boolean isLabelProperty(Object element, String property) { return false; } @Override public void removeListener(ILabelProviderListener listener) { } @Override public Image getColumnImage(Object element, int columnIndex) { return null; } }
ApplicationWorkbenchWindowAdvisor.java
package org.o7planning.tutorial.rcpapplication; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IPartListener2; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchPartReference; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.application.ActionBarAdvisor; import org.eclipse.ui.application.IActionBarConfigurer; import org.eclipse.ui.application.IWorkbenchWindowConfigurer; import org.eclipse.ui.application.WorkbenchWindowAdvisor; import org.o7planning.tutorial.rcpapplication.editor.DeptEditor; import org.o7planning.tutorial.rcpapplication.view.DeptListView; import org.o7planning.tutorial.rcpapplication.view.DeptView; public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor { public ApplicationWorkbenchWindowAdvisor( IWorkbenchWindowConfigurer configurer) { super(configurer); } public ActionBarAdvisor createActionBarAdvisor( IActionBarConfigurer configurer) { return new ApplicationActionBarAdvisor(configurer); } public void preWindowOpen() { IWorkbenchWindowConfigurer configurer = getWindowConfigurer(); configurer.setInitialSize(new Point(400, 300)); configurer.setShowCoolBar(true); configurer.setShowStatusLine(true); configurer.setShowPerspectiveBar(true); configurer.setTitle("Hello RCP"); } @Override public void postWindowOpen() { Shell shell = getWindowConfigurer().getWindow().getShell(); shell.setMaximized(true); // Register at events related to the components of the page (View, Editor,..) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() .addPartListener(new IPartListener2() { @Override public void partActivated(IWorkbenchPartReference partRef) { } @Override public void partBroughtToTop(IWorkbenchPartReference partRef) { } @Override public void partClosed(IWorkbenchPartReference partRef) { } @Override public void partDeactivated(IWorkbenchPartReference partRef) { } @Override public void partHidden(IWorkbenchPartReference partRef) { } @Override public void partVisible(IWorkbenchPartReference partRef) { } @Override public void partInputChanged(IWorkbenchPartReference partRef) { } // When a View or Editor opened. @Override public void partOpened(IWorkbenchPartReference partRef) { System.out.println("Part OPENED: " + partRef.getPartName()); IWorkbenchPart part = partRef.getPart(false); if (part instanceof DeptListView) { DeptListView deptListView = (DeptListView) part; DeptEditor deptEditor = (DeptEditor) partRef .getPage().findView(DeptEditor.ID); // DeptListView listen to Property Change of DeptEditor. if (deptEditor != null) { deptEditor.addPropertyListener(deptListView); } } else if (part instanceof DeptView) { DeptView deptView = (DeptView) part; DeptEditor deptEditor = (DeptEditor) partRef .getPage().findView(DeptEditor.ID); // DeptView listen to Property Change of DeptEditor. if (deptEditor != null) { deptEditor.addPropertyListener(deptView); } } else if (part instanceof DeptEditor) { DeptEditor deptEditor = (DeptEditor) part; DeptView deptView = (DeptView) partRef.getPage() .findView(DeptView.ID); // DeptView listen to Property Change of DeptEditor. if (deptView != null) { deptEditor.addPropertyListener(deptView); } DeptListView deptListView = (DeptListView) partRef .getPage().findView(DeptListView.ID); // DeptListView listen to Property Change of DeptEditor. if (deptListView != null) { deptEditor.addPropertyListener(deptListView); } } } }); } }
- plugin.xml

plugin.xml
<?xml version="1.0" encoding="UTF-8"?> <?eclipse version="3.4"?> <plugin> <extension id="application" point="org.eclipse.core.runtime.applications"> <application> <run class="org.o7planning.tutorial.rcpapplication.Application"> </run> </application> </extension> <extension point="org.eclipse.ui.perspectives"> <perspective name="RCP Perspective" class="org.o7planning.tutorial.rcpapplication.Perspective" id="RCPApplication.perspective"> </perspective> </extension> <extension point="org.eclipse.ui.views"> <view class="org.o7planning.tutorial.rcpapplication.view.DeptView" id="view.dept" name="Dept" restorable="true"> </view> <view class="org.o7planning.tutorial.rcpapplication.view.DeptListView" id="view.deptList" name="Dept List" restorable="true"> </view> </extension> <extension point="org.eclipse.ui.editors"> <editor class="org.o7planning.tutorial.rcpapplication.editor.DeptEditor" default="false" id="deptEditor" name="Dept Editor"> </editor> </extension> <extension point="org.eclipse.ui.commands"> <command defaultHandler="org.o7planning.tutorial.rcpapplication.command.DeptCommand" id="command.dept" name="Dept Command"> </command> </extension> <extension point="org.eclipse.ui.perspectiveExtensions"> <perspectiveExtension targetID="*"> <view id="view.deptList" minimized="false" relationship="left" relative="org.eclipse.ui.editorss" visible="true"> </view> <view id="view.dept" minimized="false" relationship="right" relative="org.eclipse.ui.editorss" visible="true"> </view> </perspectiveExtension> </extension> <extension point="org.eclipse.ui.menus"> <menuContribution allPopups="false" locationURI="menu:org.eclipse.ui.main.menu"> <menu label="Functions"> <command commandId="command.dept" label="Open Dept" style="push"> </command> </menu> </menuContribution> </extension> </plugin>

When DeptEditor change, it should inform DeptListView and DeptView to update the information. DeptListView & DeptView necessary implements IPropertyListener. View & Editor listen to each other's events, you can write code in the postWindowOpen method of ApplicationWorkbenchWindowAdvisor:
deptEditor.addPropertyListener(deptView); deptEditor.addPropertyListener(deptListView);
// Register at events related to the components of the page (View, Editor,..) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() .addPartListener(new IPartListener2() { // When a View or Editor opened. @Override public void partOpened(IWorkbenchPartReference partRef) { System.out.println("Part OPENED: " + partRef.getPartName()); IWorkbenchPart part = partRef.getPart(false); if (part instanceof DeptListView) { DeptListView deptListView = (DeptListView) part; DeptEditor deptEditor = (DeptEditor) partRef .getPage().findView(DeptEditor.ID); // DeptListView listen to Property Change of DeptEditor. if (deptEditor != null) { deptEditor.addPropertyListener(deptListView); } } else if (part instanceof DeptView) { DeptView deptView = (DeptView) part; DeptEditor deptEditor = (DeptEditor) partRef .getPage().findView(DeptEditor.ID); // DeptView listen to Property Change of DeptEditor. if (deptEditor != null) { deptEditor.addPropertyListener(deptView); } } else if (part instanceof DeptEditor) { DeptEditor deptEditor = (DeptEditor) part; DeptView deptView = (DeptView) partRef.getPage() .findView(DeptView.ID); // DeptView listen to Property Change of DeptEditor. if (deptView != null) { deptEditor.addPropertyListener(deptView); } DeptListView deptListView = (DeptListView) partRef .getPage().findView(DeptListView.ID); // DeptListView listen to Property Change of DeptEditor. if (deptListView != null) { deptEditor.addPropertyListener(deptListView); } } } }); }
DeptListViewer: Contains a list of departments, when double click on a department it will be shown on DeptEditor.

Screen design:

On DeptListView you need setup SelectionProvider:
// Registration Provider Selection. this.getSite().setSelectionProvider(tableViewer);
Note:You can learn more about how to use this class at:
- TableViewer, TreeViewer,.. implements ISelectionProvider interface.

- AbstractBaseEditor.java (DeptEditor extends AbstractBaseEditor).
// When PROP_DIRTY change, this method will be called by the Workbench. // If the method returns true, the SAVE button will enabled, else disable. @Override public boolean isDirty() { return this.dirty; } // When changing the data editor, call this method to notify to Workbench. protected void setDirty(boolean dirty) { if (this.dirty != dirty) { this.dirty = dirty; // Notify PROP_DIRTY changes to Workbench. this.firePropertyChange(IEditorPart.PROP_DIRTY); } }
DeptCommand is command use to open DeptEditor.
Normally, a command will create an IEditorInput, open a new Editor and pass Input into. You can also search for available Editors on page, and newly pass IEditorInput, these editors are Editor can re-use (with a new Input), and it needs implements IReusableEditor.
Normally, a command will create an IEditorInput, open a new Editor and pass Input into. You can also search for available Editors on page, and newly pass IEditorInput, these editors are Editor can re-use (with a new Input), and it needs implements IReusableEditor.
Getting current page on the workbench window:
// Get the page IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event); IWorkbenchPage page = window.getActivePage();
Department dept = (Department) selectObj; DeptEditorInput input = new DeptEditorInput(dept); boolean found = false; // Opening Editor reference IEditorReference[] eRefs = page.getEditorReferences(); for (IEditorReference ref : eRefs) { IEditorPart editor = ref.getEditor(false); if (editor != null && editor instanceof DeptEditor) { // Restore DeptEditor deptEditor = (DeptEditor) ref.getEditor(true); found = true; boolean saved = true; // If editor is dirty, save it if (deptEditor.isDirty()) { saved = page.saveEditor(deptEditor, true); } if (saved) { // Set new input for DeptEditor page.reuseEditor(deptEditor, input); deptEditor.showData(); } } }
Note: If the first run the application does not show the view, right-click the Perspective Bar, select Reset.
![]()