Reading program arguments in a RCP application? - eclipse-rcp

I have created an eclipse application and a product configuration.
In the product configuration on the "Launching" tab its possible to specify "Program arguments" and "VM Arguments".
Is it possible to access these arguments from the Application class? Currently this class looks like this:
public class Application implements IApplication {
#Override
public Object start(IApplicationContext context) throws Exception {
Map<?, ?> arguments = context.getArguments(); // this is empty!
// This actually does the trick but is a bit ugly - must be parsed
String[] strings = (String[]) context.getArguments()
.get("application.args");
Display display = PlatformUI.createDisplay();
try {
ApplicationWorkbenchAdvisor advisor = new ApplicationWorkbenchAdvisor();
int returnCode = PlatformUI.createAndRunWorkbench(display, advisor);
if (returnCode == PlatformUI.RETURN_RESTART) {
return IApplication.EXIT_RESTART;
} else {
return IApplication.EXIT_OK;
}
} finally {
display.dispose();
}
}
/*
* (non-Javadoc)
*
* #see org.eclipse.equinox.app.IApplication#stop()
*/
#Override
public void stop() {
final IWorkbench workbench = PlatformUI.getWorkbench();
if (workbench == null) {
return;
}
final Display display = workbench.getDisplay();
display.syncExec(new Runnable() {
#Override
public void run() {
if (!display.isDisposed()) {
workbench.close();
}
}
});
}
Are there a better way to extract the application args than:
// This actually does the trick but is a bit ugly
String[] strings = (String[]) context.getArguments()
.get("application.args");

Just
Platform.getCommandLineArgs();
See http://www.vogella.de/blog/2008/06/21/passing-parameters-to-eclipse-rcp-via-the-command-line/ for an example.

Related

Eclipse EditorPart save on partDeactivated

My problem is that I have a custom application, using EditorParts, which are persisted to a database. The user can open several Editors, and switch between them. I need to ask the user to save any unsaved changes in an Editor, before switching to the next Editor (or else close it).
I have created an IPartListener2, and I receive the partDeactivated notification. If isDirty()==true, I bring up a MessageDialog asking to save or not; because I want to call editor.doSave().
My problem is that does not work. I never see the MessageDialog, because another partDeactivated fires. I guess, this is caused by the MessageDialog over the Editor.
I have researched How to listen to lose focus event of a part in Eclipse E4 RCP?, but that did not help me.
thanks to help a e4 beginner
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();
}
}
You probably need to run your code after the deactivate event has finished. You can do this using Display.asyncExec.
Something like:
#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
});
}
(Above code assumes you are using Java 8 or later)
This is 3.x compatibility mode code, not e4.
I have found a great solution, using the suggestions above and Enumerating all my Eclipse editors?
I am checking all editors first, then all persisted editors - skipping itself and the persisted objects.
Thanks for your comments!
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;
}
}

Update ListView via AsyncTask or IntentService

I am trying to Update my Custom ListView which is fed by two String Arrays:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getStringArray(ARG_PARAM1);
mParam2 = getArguments().getStringArray(ARG_PARAM2);
}
setupListView();
}
private void setupListView() {
listItemList = new ArrayList();
if (mParam1 != null && mParam2 != null && mParam1.length == mParam2.length) {
for (int i = 0; i < mParam1.length; i++) {
listItemList.add(new MyListItem(mParam1[i], (mParam2[i]).substring(0, 75) + "..."));
}
} else {
listItemList.add(new MyListItem("Loading...", "Swipe Down for Update"));
}
mAdapter = new MyListAdapter(getActivity(), listItemList);
}
mParam1 and mParam2 are Values which are fetched by an XML parser (IntentService) class in the MainActivity which i can show if needed.
Now, if i am to fast, and the mPara1 and mPara2 is empty there won´t be any ListView shown. Now i want to solve this by some AsyncTask or IntentService whatever is useful. I tried AsyncTask, which didn´t work at all. I tried notifyDataSetChanged() which didn´t work too...
Now, how could i solve this....
Using AsyncTask i have the problem that i don´t know how to passt the two Arrays to publishProgress() correctly
THis is how my AsyncTask looks like:
class UpdateListView extends AsyncTask<Void, String, Void> {
private MyListAdapter adapter;
private ArrayList listItemList;
#Override
protected void onPreExecute() {
adapter = (MyListAdapter) mListView.getAdapter();
}
#Override
protected Void doInBackground(Void... params) {
for (String item1 : mParam1) {
publishProgress(item1);
}
return null;
}
#Override
protected void onProgressUpdate(String... values) {
adapter.add(new MyListItem(values[0], values[1]));
}
#Override
protected void onPostExecute(Void result) {
Log.d("onPostExecute", "Added successfully");
}
}
Okay solved it...My Fragments are running in same Activity where the Data is loaded in, so i just created getter and setter in MainActivity and access them in the needed Fragment via
String[] titles =(MainActivity) getActivity()).getTitlesArray();
String[] text=(MainActivity) getActivity()).getTextArray();
Whatever i do trying setting Bundle with
bundle.putStringArray(TITLES,titles);
doesn´t work. Should work using parceable/serializable class but didn´t try...

Eclipse Plugin - How to open a wizard page in a command handler?

I write a plugin for eclipse. I have a button in the toolbar menu. and I want that on pressing on it - a wizard page dialog will be opened. I wrote already a class which extends wizard and implements IWizardPage, and I wrote also all the 5 relevant pages, I only don't find any way to open this in the command handler.
Here is the pieces of my code:
The command handler:
public class AddProjectHandler extends AbstractHandler {
#Override
public Object execute(ExecutionEvent event) throws ExecutionException {
return null;
}
}
The wizard page manager:
public class NewProjectWizardManager extends Wizard implements INewWizard {
private NewProjectWizardPage1 _page1;
private NewProjectWizardPage2 _page2;
private NewProjectWizardPage3 _page3;
private NewProjectWizardPage4 _page4;
private NewProjectWizardPage5 _page5;
// constructor
public NewProjectWizardManager() {
super();
setWindowTitle("New Project");
}
#Override
public void init(IWorkbench workbench, IStructuredSelection selection) {
}
#Override
public boolean performCancel() {
return true;
}
#Override
public void addPages() {
super.addPages();
_page1 = new NewProjectWizardPage1();
addPage(_page1);
_page2 = new NewProjectWizardPage2(_page1);
addPage(_page2);
_page3 = new NewProjectWizardPage3(_page1);
addPage(_page3);
_page4 = new NewProjectWizardPage4();
addPage(_page4);
_page5 = new NewProjectWizardPage5(_page1);
addPage(_page5);
}
#Override
public boolean canFinish() {
IWizardContainer container = getContainer();
if (_page5.equals(container.getCurrentPage())) {
return true;
} else {
return false;
}
}
#Override
public IWizardPage getNextPage(IWizardPage page) {
IWizardPage nextPage = super.getNextPage(page);
IWizardContainer container = getContainer();
if (nextPage != null) {
if (_page2.equals(container.getCurrentPage()) && _page2.isCheckFinishChecked())
nextPage = super.getNextPage(super.getNextPage(nextPage));
}
return nextPage;
}
#Override
public boolean performFinish() {
}
}
The plugin.xml pieces:
<command
categoryId="com.commands.category"
description="Add new Project"
id="com.commands.AddProject"
name="Add new Project">
</command>
<handler
class="com.handlers.AddProjectHandler"
commandId="com.commands.AddProject">
</handler>
Do you have any idea?
Use WizardDialog to show a wizard. Something like:
public Object execute(ExecutionEvent event) throws ExecutionException
{
Shell activeShell = HandlerUtil.getActiveShell(event);
IWizard wizard = new NewProjectWizardManager();
WizardDialog dialog = new WizardDialog(activeShell, wizard);
dialog.open();
return null;
}
I found the code below from org.eclipse.jdt.ui.actions.AbstractOpenWizardAction.
Before Eclipse3.4 you can extend this class to create an Action.but action is deprecated now,I wonder if Eclipse.org provide something like AbstractOpenWizardAction to do the same work in command-handler mode. I'v not found it yet.
public void run() {
Shell shell = getShell();
if (!(doCreateProjectFirstOnEmptyWorkspace(shell)))
return;
try {
INewWizard wizard = createWizard();
wizard.init(PlatformUI.getWorkbench(), getSelection());
WizardDialog dialog = new WizardDialog(shell, wizard);
PixelConverter converter = new PixelConverter(JFaceResources.getDialogFont());
dialog.setMinimumPageSize(converter.convertWidthInCharsToPixels(70),
converter.convertHeightInCharsToPixels(20));
dialog.create();
int res = dialog.open();
if ((res == 0) && (wizard instanceof NewElementWizard)) {
this.fCreatedElement = ((NewElementWizard) wizard).getCreatedElement();
}
notifyResult(res == 0);
} catch (CoreException e) {
String title = NewWizardMessages.AbstractOpenWizardAction_createerror_title;
String message = NewWizardMessages.AbstractOpenWizardAction_createerror_message;
ExceptionHandler.handle(e, shell, title, message);
}
}

How to remove "no data" labels from empty nodes in GWT?

I have a widget that inherits from CellTree. If the node not have the child elements, this node can be opened and shows "no data" label.
I'd like to see nodes without child's displayed as empty.
That's how I fill the tree. My DictionaryTreeDataProvider class (relevant part):
public class DictionaryTreeDataProvider extends ListDataProvider<MValue> {
private final DictionariesServiceAsync service = GWT.create(DictionariesService.class);
...
#Override
public void onRangeChanged(HasData<MValue> result) {
service.queryDictionaryValues(range, query, new AsyncCallback<SubsetResult<MValue>>() {
#Override
public void onFailure(Throwable t) {
}
#Override
public void onSuccess(SubsetResult<MValue> result) {
getList().clear();
for (MValue value : result.items) {
getList().add(value);
}
}
});
}
}
On the server side I make EJB call which fills SubsetResult.
I found that this problem fixed in version of GWT-2.5.0-rc2 (see https://groups.google.com/forum/#!topic/google-web-toolkit/d-rFUmyHTT4).
Now everything is OK, thanks to #moutellou.
I did as he suggested:
...
#Override
public void onSuccess(SubsetResult<MValue> result) {
if (result.length == 0) {
updateRowCount(-1, true);
return;
} else {
for (MValue value : result.items) {
// some checks here
getList().add(value);
}
}
}
...
Some alternative solution. Can be defined interface that extends the interface CellTree.Resources.
In this interface must specify the path to the CSS, which override the desired style.
Interface CellTree.Resources:
public class CellTree extends AbstractCellTree implements HasAnimation,
Focusable {
...
/**
* A ClientBundle that provides images for this widget.
*/
public interface Resources extends ClientBundle {
/**
* An image indicating a closed branch.
*/
#ImageOptions(flipRtl = true)
#Source("cellTreeClosedArrow.png")
ImageResource cellTreeClosedItem();
/**
* An image indicating that a node is loading.
*/
#ImageOptions(flipRtl = true)
ImageResource cellTreeLoading();
/**
* An image indicating an open branch.
*/
#ImageOptions(flipRtl = true)
#Source("cellTreeOpenArrow.png")
ImageResource cellTreeOpenItem();
/**
* The background used for selected items.
*/
#ImageOptions(repeatStyle = RepeatStyle.Horizontal, flipRtl = true)
ImageResource cellTreeSelectedBackground();
/**
* The styles used in this widget.
*/
#Source(Style.DEFAULT_CSS)
Style cellTreeStyle();
}
...
}
Interface CustomCellTreeResources, based on CellTree.Resources:
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.user.cellview.client.CellTree;
public interface CustomCellTreeResources extends CellTree.Resources {
static final String STYLE_PATH = "components/common/client/static/custom-cell-tree.css";
#Override
#ClientBundle.Source({CellTree.Style.DEFAULT_CSS, STYLE_PATH})
CellTree.Style cellTreeStyle();
}
Overriding rule:
.cellTreeEmptyMessage {
display: none;
}
Create an instance:
private final static CellTree.Resources customCellTreeResources =
GWT.create(CustomCellTreeResources.class);
And next need to explicitly pass customCellTreeResources to the CellTree class constructor.
Message is not displayed more.
Mandatory: before filing the list, ie, before clicking on a node, the list should be cleaned( getList().clear();):
#Override
public void onRangeChanged(HasData<MValue> result) {
service.queryDictionaryValues(range, query,
new AsyncCallback<SubsetResult<MValue>>() {
#Override
public void onFailure(Throwable t) {}
#Override
public void onSuccess(SubsetResult<MValue> result) {
getList().clear();
for (MValue value : result.items) {
getList().add(value);
}
}
});
}
This is how I removed the no data label in my DataProvider
//Fetch children
int size = children.size();
if (size == 0) {
updateRowCount(-1, true); //Method called on AsyncDataProvider
return;
}
In the TreeViewModel, make sure that the isLeaf method returns true if the argument value has no children. Example:
#Override
public boolean isLeaf(Object value) {
if (value instanceof DepartmentDto) {
DepartmentDto department = (DepartmentDto) value;
return department.getEmployees().isEmpty();
} else if (value instanceof EmployeeDto) {
return true;
} else {
return false;
}
}
In this case, a department should declare itself as a leaf only if it has no employees, an employee will declare itself as a leaf, and default to false.
Note that value many also be an internal GWT node. In this example, it might not necessarily be just DepartmentDto and EmployeeDto.

GEF + EMF: Why doesn't my editor remove the Figure for a removed object when refreshChildren() is called?

I have implemented a GEF editor for a graph-like EMF model, with a remove command for a certain type of node in the graph. I think I've done all the necessary steps in order to make this set up work (vainolo's blog has been a great help).
However, when I'm deleting a model element, the view doesn't get refreshed, i.e., the figure for the model element isn't removed from the editor view, and I have no idea why. I'd be extremely grateful if somebody could have a look at my sources and point me to any problems (and possibly solutions :)). Many thanks in advance!
Below are what I think are the important classes for this issue. Please do let me know should I add further code/edit the code, etc. (I've left out code that I thought doesn't help, e.g., getters and setters, class variables). Thanks!
DiagramEditPart
public class DiagramEditPart extends AbstractGraphicalEditPart {
public DiagramEditPart(Diagram model) {
this.setModel(model);
adapter = new DiagramAdapter();
}
#Override protected IFigure createFigure() {
Figure figure = new FreeformLayer();
return figure;
}
#Override protected void createEditPolicies() {
installEditPolicy(EditPolicy.LAYOUT_ROLE, new DiagramXYLayoutPolicy());
}
#Override protected List<EObject> getModelChildren() {
List<EObject> allModelObjects = new ArrayList<EObject>();
if (((Diagram) getModel()).getMyNodes() != null)
allModelObjects.addAll(((Diagram) getModel()).getMyNodes());
return allModelObjects;
}
#Override public void activate() {
if(!isActive()) {
((Diagram) getModel()).eAdapters().add(adapter);
}
super.activate();
}
#Override public void deactivate() {
if(isActive()) {
((Diagram) getModel()).eAdapters().remove(adapter);
}
super.deactivate();
}
public class DiagramAdapter implements Adapter {
#Override public void notifyChanged(Notification notification) {
switch (notification.getEventType()) {
case Notification.REMOVE: refreshChildren();
break;
default:
break;
}
}
#Override public Notifier getTarget() {
return (Diagram) getModel();
}
#Override public void setTarget(Notifier newTarget) {
// Do nothing.
}
#Override public boolean isAdapterForType(Object type) {
return type.equals(Diagram.class);
}
}
}
MyNodeEditPart
public class MyNodeEditPart extends AbstractGraphicalEditPart {
public MyNodeEditPart(MyNode model) {
this.setModel(model);
adapter = new MyNodeAdapter();
}
#Override protected IFigure createFigure() {
return new MyNodeFigure();
}
#Override protected void createEditPolicies() {
installEditPolicy(EditPolicy.COMPONENT_ROLE, new MyNodeComponentEditPolicy());
}
#Override protected void refreshVisuals() {
MyNodeFigure figure = (MyNodeFigure) getFigure();
DiagramEditPart parent = (DiagramEditPart) getParent();
Dimension labelSize = figure.getLabel().getPreferredSize();
Rectangle layout = new Rectangle((getParent().getChildren().indexOf(this) * 50),
(getParent().getChildren().indexOf(this) * 50), (labelSize.width + 20),
(labelSize.height + 20));
parent.setLayoutConstraint(this, figure, layout);
}
public List<Edge> getModelSourceConnections() {
if ((MyNode) getModel() != null && ((MyNode) getModel()).getDiagram() != null) {
ArrayList<Edge> sourceConnections = new ArrayList<Edge>();
for (Edge edge : ((MyNode) getModel()).getDiagram().getOutEdges(((MyNode) getModel()).getId())) {
sourceConnections.add(edge);
}
return sourceConnections;
}
return null;
}
// + the same method for targetconnections
#Override public void activate() {
if (!isActive()) {
((MyNode) getModel()).eAdapters().add(adapter);
}
super.activate();
}
#Override public void deactivate() {
if (isActive()) {
((MyNode) getModel()).eAdapters().remove(adapter);
}
super.deactivate();
}
public class MyNodeAdapter implements Adapter {
#Override
public void notifyChanged(Notification notification) {
refreshVisuals();
}
#Override
public Notifier getTarget() {
return (MyNode) getModel();
}
#Override
public void setTarget(Notifier newTarget) {
// Do nothing
}
#Override
public boolean isAdapterForType(Object type) {
return type.equals(MyNode.class);
}
}
}
MyNodeComponentEditPolicy
public class MyNodeComponentEditPolicy extends ComponentEditPolicy {
#Override
protected Command createDeleteCommand(GroupRequest deleteRequest) {
DeleteMyNodeCommand nodeDeleteCommand = new DeleteMyNodeCommand((MyNode) getHost().getModel());
return nodeDeleteCommand;
}
}
DeleteMyNodeCommand
public class DeleteMyNodeCommand extends Command {
public DeleteMyNodeCommand(MyNode model) {
this.node = model;
this.graph = node.getDiagram();
}
#Override public void execute() {
getMyNode().setDiagram(null);
System.out.println("Is the model still present in the graph? " + getGraph().getMyNodes().contains(getMyNode()));
// Returns false, i.e., graph doesn't contain model object at this point!
}
#Override public void undo() {
getMyNode().setDiagram(getGraph());
}
}
EDIT
Re execc's comment: Yes, refreshChildren() is being called. I've tested this by overriding it and adding a simple System.err line, which is being displayed on the console on deletion of a node:
#Override
public void refreshChildren() {
super.refreshChildren();
System.err.println("refreshChildren() IS being called!");
}
EDIT 2
The funny (well...) thing is, when I close the editor and persist the model, then re-open the same file, the node isn't painted anymore, and is not present in the model. But what does this mean? Am I working on a stale model? Or is refreshing/getting the model children not working properly?
EDIT 3
I've just found a peculiar thing, which might explain the isues I have? In the getModelChildren() method I call allModelObjects.addAll(((Diagram) getModel()).getMyNodes());, and getMyNodes() returns an unmodifiable EList. I found out when I tried to do something along the lines of ((Diagram) getModel()).getMyNodes().remove(getMyNode()) in the delete command, and it threw an UnsupportedOperationException... Hm.
EDIT 4
Er, somebody kill me please?
I've double-checked whether I'm handling the same Diagram object at all times, and while doing this I stumbled across a very embarassing thing:
The getModelChildren() method in DiagramEditPart in the last version read approx. like this:
#Override protected List<EObject> getModelChildren() {
List<EObject> allModelObjects = new ArrayList<EObject>();
EList<MyNode> nodes = ((Diagram) getModel()).getMyNodes();
for (MyNode node : nodes) {
if (node.getDiagram() != null); // ### D'Uh! ###
allModelObjects.add(node);
}
return allModelObjects;
}
I'd like to apologize for stealing everyone's time! Your suggestions were very helpful, and indeed helped my to finally track down the bug!
I've also learned a number of lessons, amongst them: Always paste the original code, over-simplifaction may cloak your bugs! And I've learned a lot about EMF, Adapter, and GEF. Still:
There is one semi-colon too many in line 5 of the following part of the code, namely after the if statement: if (node.getDiagram() != null);:
1 #Override protected List<EObject> getModelChildren() {
2 List<EObject> allModelObjects = new ArrayList<EObject>();
3 EList<MyNode> nodes = ((Diagram) getModel()).getMyNodes();
4 for (MyNode node : nodes) {
5 if (node.getDiagram() != null);
6 allModelObjects.add(node);
7 }
8 return allModelObjects;
9 }