Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Keimel2015-05-07 08:52:44 +0000
committerChristoph Keimel2015-05-07 09:49:02 +0000
commit947a9e5cad98ba6c7aa6f2aaa6954532268ba697 (patch)
tree0ef6b523fa94b119c6c145353cdd752201effd2c
parenta3032e51be29944cad52d0254701befa81fac93c (diff)
downloadorg.eclipse.efxclipse-947a9e5cad98ba6c7aa6f2aaa6954532268ba697.tar.gz
org.eclipse.efxclipse-947a9e5cad98ba6c7aa6f2aaa6954532268ba697.tar.xz
org.eclipse.efxclipse-947a9e5cad98ba6c7aa6f2aaa6954532268ba697.zip
Bug 466689 - [emf.edit] AdapterFactoryTreeItem runs out of memory when
model is loaded in the background Signed-off-by: Christoph Keimel <c.keimel@emsw.de> Change-Id: If5880a06524661fc852a8adcff170b5077015ed2
-rw-r--r--bundles/runtime/org.eclipse.fx.emf.edit.ui/src/org/eclipse/fx/emf/edit/ui/AdapterFactoryTreeItem.java144
-rw-r--r--demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/views/ContactsTreeTableView.java2
-rwxr-xr-xdemos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/views/ContactsTreeView.java2
3 files changed, 77 insertions, 71 deletions
diff --git a/bundles/runtime/org.eclipse.fx.emf.edit.ui/src/org/eclipse/fx/emf/edit/ui/AdapterFactoryTreeItem.java b/bundles/runtime/org.eclipse.fx.emf.edit.ui/src/org/eclipse/fx/emf/edit/ui/AdapterFactoryTreeItem.java
index f8fd05244..f347e988e 100644
--- a/bundles/runtime/org.eclipse.fx.emf.edit.ui/src/org/eclipse/fx/emf/edit/ui/AdapterFactoryTreeItem.java
+++ b/bundles/runtime/org.eclipse.fx.emf.edit.ui/src/org/eclipse/fx/emf/edit/ui/AdapterFactoryTreeItem.java
@@ -10,14 +10,12 @@
*******************************************************************************/
package org.eclipse.fx.emf.edit.ui;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
+import java.util.Optional;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
-import javafx.scene.control.Control;
-import javafx.scene.control.MultipleSelectionModel;
import javafx.scene.control.TreeItem;
import org.eclipse.emf.common.notify.AdapterFactory;
@@ -34,7 +32,6 @@ import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
public class AdapterFactoryTreeItem extends TreeItem<Object> {
final AdapterFactory adapterFactory;
- final Control view;
final ObservableList<TreeItem<Object>> children;
final ITreeItemContentProvider provider;
@@ -43,14 +40,11 @@ public class AdapterFactoryTreeItem extends TreeItem<Object> {
*
* @param object
* the object
- * @param treeView
- * the tree
* @param adapterFactory
* the factory
*/
- public AdapterFactoryTreeItem(Object object, Control treeView, AdapterFactory adapterFactory) {
+ public AdapterFactoryTreeItem(Object object, AdapterFactory adapterFactory) {
super(object);
- this.view = treeView;
this.adapterFactory = adapterFactory;
this.children = FXCollections.unmodifiableObservableList(super.getChildren());
@@ -61,14 +55,13 @@ public class AdapterFactoryTreeItem extends TreeItem<Object> {
((Notifier) object).eAdapters().add(new AdapterImpl() {
@Override
public void notifyChanged(Notification msg) {
- if (msg.getFeature() instanceof EReference)
- updateChildren();
+ if (!msg.isTouch() && msg.getFeature() instanceof EReference)
+ updateChildren(msg);
}
-
});
}
- updateChildren();
+ initializeChildren();
}
/**
@@ -79,71 +72,84 @@ public class AdapterFactoryTreeItem extends TreeItem<Object> {
public ObservableList<TreeItem<Object>> getChildren() {
return this.children;
}
+
+ void initializeChildren() {
+ if (this.provider == null)
+ return;
- /**
- * Recreates the child tree items using the {@link ITreeItemContentProvider} and restores the selection
- * and expanded state of the tree items.
- */
- void updateChildren() {
- ObservableList<TreeItem<Object>> childTreeItems = super.getChildren();
-
- MultipleSelectionModel<?> selectionModel = CellUtil.getSelectionModel(this.view);
- List<?> selection = selectionModel.getSelectedItems();
- ArrayList<Object> selectedItems = new ArrayList<>();
- ArrayList<TreeItem<?>> selectedTreeItems = new ArrayList<>();
- ArrayList<Object> expandedItems = new ArrayList<>();
-
- // remember the expanded items
- for (TreeItem<Object> childTreeItem : childTreeItems) {
- if (childTreeItem.isExpanded())
- expandedItems.add(childTreeItem.getValue());
+ // add the tree items
+ for (Object child : this.provider.getChildren(getValue())) {
+ addNewChild(child, Notification.NO_INDEX);
}
+ }
- // remember the selected items
- for (Object selectedTreeItem : selection) {
- for (TreeItem<Object> childTreeItem : childTreeItems) {
- if (selectedTreeItem == childTreeItem) {
- selectedTreeItems.add(childTreeItem);
- selectedItems.add(childTreeItem.getValue());
- }
+ void updateChildren(Notification msg) {
+ ObservableList<TreeItem<Object>> childTreeItems = super.getChildren();
+
+ switch (msg.getEventType()) {
+ case Notification.ADD:
+ addNewChild(msg.getNewValue(), msg.getPosition());
+ break;
+ case Notification.ADD_MANY:
+ List<?> newValues = (List<?>) msg.getNewValue();
+ int position = msg.getPosition();
+ if (position != Notification.NO_INDEX && position <= childTreeItems.size()) {
+ // reverse List, so items are added at correct position in backward order
+ Collections.reverse(newValues);
+ }
+ newValues.forEach(newValue -> {
+ addNewChild(newValue, position);
+ });
+ break;
+ case Notification.REMOVE:
+ removeChild(msg.getOldValue());
+ break;
+ case Notification.REMOVE_MANY:
+ List<?> oldValues = (List<?>) msg.getOldValue();
+ oldValues.forEach(oldValue -> {
+ removeChild(oldValue);
+ });
+ break;
+ case Notification.SET:
+ childTreeItems.clear();
+ initializeChildren();
+ break;
+ case Notification.RESOLVE:
+ initializeChildren();
+ break;
+ case Notification.MOVE:
+ int index = ((Integer)msg.getOldValue()).intValue();
+ if (index >= 0 && index < childTreeItems.size()) {
+ TreeItem<Object> treeItem = childTreeItems.get(index);
+ childTreeItems.remove(treeItem);
+ childTreeItems.add(msg.getPosition(), treeItem);
}
+ break;
}
+ }
- // clear the selection
- for (TreeItem<?> selectedTreeItem : selectedTreeItems) {
- int treeItemIndex = selectionModel.getSelectedItems().indexOf(selectedTreeItem);
- int selectionIndex = selectionModel.getSelectedIndices().get(treeItemIndex).intValue();
- selectionModel.clearSelection(selectionIndex);
+ private void addNewChild(Object value, int position) {
+ ObservableList<TreeItem<Object>> childTreeItems = super.getChildren();
+ AdapterFactoryTreeItem newTreeItem = new AdapterFactoryTreeItem(value, this.adapterFactory);
+ if (position == Notification.NO_INDEX || position > childTreeItems.size()) {
+ childTreeItems.add(newTreeItem);
+ } else {
+ childTreeItems.add(position, newTreeItem);
}
-
- // remove the old tree items
- childTreeItems.clear();
-
- if (this.provider == null)
- return;
-
- // add the new tree items
- for (Object child : this.provider.getChildren(getValue())) {
- AdapterFactoryTreeItem treeItem = new AdapterFactoryTreeItem(child, this.view, this.adapterFactory);
-
- childTreeItems.add(treeItem);
-
- // expand the new tree items
- if (expandedItems.contains(child))
- treeItem.setExpanded(true);
-
- // restore the selection
- if (selectedItems.contains(child) && "javafx.scene.control.TreeView$TreeViewBitSetSelectionModel".equals(selectionModel.getClass().getName())) { //$NON-NLS-1$
- try {
- Method m = selectionModel.getClass().getDeclaredMethod("select", new Class[] { TreeItem.class }); //$NON-NLS-1$
- m.setAccessible(true);
- m.invoke(selectionModel, treeItem);
- } catch (Exception e) {
- // do nothing
- }
- }
+ }
+
+ private void removeChild(Object value) {
+ TreeItem<Object> treeItem = findTreeItemForValue(value);
+ if (treeItem != null) {
+ super.getChildren().remove(treeItem);
}
+ }
+ private TreeItem<Object> findTreeItemForValue(Object value) {
+ Optional<TreeItem<Object>> first = super.getChildren().stream().filter(item -> {
+ return item.getValue().equals(value);
+ }).findFirst();
+ return first.orElse(null);
}
}
diff --git a/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/views/ContactsTreeTableView.java b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/views/ContactsTreeTableView.java
index aa638c295..d282aec32 100644
--- a/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/views/ContactsTreeTableView.java
+++ b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/views/ContactsTreeTableView.java
@@ -73,7 +73,7 @@ public class ContactsTreeTableView {
emailColumn.setCellValueFactory(new TreeTableProxyCellValueFactory());
treeTableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
- treeTableView.setRoot(new AdapterFactoryTreeItem(contactsManager.getRootGroup(), treeTableView, adapterFactory));
+ treeTableView.setRoot(new AdapterFactoryTreeItem(contactsManager.getRootGroup(), adapterFactory));
treeTableView.setShowRoot(false);
diff --git a/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/views/ContactsTreeView.java b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/views/ContactsTreeView.java
index 6f7db4699..5b0be0866 100755
--- a/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/views/ContactsTreeView.java
+++ b/demos/org.eclipse.fx.demo.contacts.app/src/org/eclipse/fx/demo/contacts/views/ContactsTreeView.java
@@ -43,7 +43,7 @@ public class ContactsTreeView {
// TreeView
TreeView<Object> treeView = new TreeView<>();
- treeView.setRoot(new AdapterFactoryTreeItem(contactsManager.getRootGroup(), treeView, contactsManager.getAdapterFactory()));
+ treeView.setRoot(new AdapterFactoryTreeItem(contactsManager.getRootGroup(), contactsManager.getAdapterFactory()));
AdapterFactoryTreeCellFactory treeCellFactory = new AdapterFactoryTreeCellFactory(contactsManager.getAdapterFactory());
// add edit support

Back to the top