Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Schindl2013-12-20 15:59:03 -0500
committerTom Schindl2013-12-20 15:59:03 -0500
commitb3cdb2e1de5af280d1b742ba044f31dae8254ede (patch)
tree3620bbcbcb95815255e8f824dfda972c1c75b377
parent6dc4c6f1dcbb5778cbcb19efa0a9a4e86df3f310 (diff)
downloadorg.eclipse.efxclipse-b3cdb2e1de5af280d1b742ba044f31dae8254ede.tar.gz
org.eclipse.efxclipse-b3cdb2e1de5af280d1b742ba044f31dae8254ede.tar.xz
org.eclipse.efxclipse-b3cdb2e1de5af280d1b742ba044f31dae8254ede.zip
Bug 424554 - Add possibility to create an IObservableList from another
IObservableList converting values from source to target
-rw-r--r--bundles/runtime/org.eclipse.fx.core.databinding.tests/.classpath7
-rw-r--r--bundles/runtime/org.eclipse.fx.core.databinding.tests/.gitignore1
-rw-r--r--bundles/runtime/org.eclipse.fx.core.databinding.tests/.project28
-rw-r--r--bundles/runtime/org.eclipse.fx.core.databinding.tests/.settings/org.eclipse.jdt.core.prefs7
-rw-r--r--bundles/runtime/org.eclipse.fx.core.databinding.tests/META-INF/MANIFEST.MF45
-rw-r--r--bundles/runtime/org.eclipse.fx.core.databinding.tests/build.properties4
-rw-r--r--bundles/runtime/org.eclipse.fx.core.databinding.tests/src/org/eclipse/fx/core/databinding/tests/AdapterFactoryTests.java58
-rw-r--r--bundles/runtime/org.eclipse.fx.core.databinding.tests/src/org/eclipse/fx/core/databinding/tests/RealmRunner.java49
-rwxr-xr-xbundles/runtime/org.eclipse.fx.core.databinding/src/org/eclipse/fx/core/databinding/AdapterFactory.java199
9 files changed, 395 insertions, 3 deletions
diff --git a/bundles/runtime/org.eclipse.fx.core.databinding.tests/.classpath b/bundles/runtime/org.eclipse.fx.core.databinding.tests/.classpath
new file mode 100644
index 000000000..eca7bdba8
--- /dev/null
+++ b/bundles/runtime/org.eclipse.fx.core.databinding.tests/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/runtime/org.eclipse.fx.core.databinding.tests/.gitignore b/bundles/runtime/org.eclipse.fx.core.databinding.tests/.gitignore
new file mode 100644
index 000000000..5e56e040e
--- /dev/null
+++ b/bundles/runtime/org.eclipse.fx.core.databinding.tests/.gitignore
@@ -0,0 +1 @@
+/bin
diff --git a/bundles/runtime/org.eclipse.fx.core.databinding.tests/.project b/bundles/runtime/org.eclipse.fx.core.databinding.tests/.project
new file mode 100644
index 000000000..e0460244c
--- /dev/null
+++ b/bundles/runtime/org.eclipse.fx.core.databinding.tests/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.fx.core.databinding.tests</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/bundles/runtime/org.eclipse.fx.core.databinding.tests/.settings/org.eclipse.jdt.core.prefs b/bundles/runtime/org.eclipse.fx.core.databinding.tests/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..0c68a61dc
--- /dev/null
+++ b/bundles/runtime/org.eclipse.fx.core.databinding.tests/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/bundles/runtime/org.eclipse.fx.core.databinding.tests/META-INF/MANIFEST.MF b/bundles/runtime/org.eclipse.fx.core.databinding.tests/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..ddd91a645
--- /dev/null
+++ b/bundles/runtime/org.eclipse.fx.core.databinding.tests/META-INF/MANIFEST.MF
@@ -0,0 +1,45 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Tests
+Bundle-SymbolicName: org.eclipse.fx.core.databinding.tests
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Require-Bundle: org.junit;bundle-version="4.11.0",
+ org.eclipse.core.databinding;bundle-version="1.4.1",
+ org.eclipse.core.databinding.property;bundle-version="1.4.200",
+ org.eclipse.fx.core.databinding;bundle-version="0.9.0"
+Import-Package: javafx.animation;version="2.2.0",
+ javafx.application;version="2.2.0",
+ javafx.beans;version="2.2.0",
+ javafx.beans.binding;version="2.2.0",
+ javafx.beans.property;version="2.2.0",
+ javafx.beans.property.adapter;version="2.2.0",
+ javafx.beans.value;version="2.2.0",
+ javafx.collections;version="2.2.0",
+ javafx.collections.transformation;version="8.0.0",
+ javafx.concurrent;version="2.2.0",
+ javafx.css;version="8.0.0",
+ javafx.embed.swing;version="2.2.0",
+ javafx.embed.swt;version="2.2.0",
+ javafx.event;version="2.2.0",
+ javafx.fxml;version="2.2.0",
+ javafx.geometry;version="2.2.0",
+ javafx.print;version="8.0.0",
+ javafx.scene;version="2.2.0",
+ javafx.scene.canvas;version="2.2.0",
+ javafx.scene.chart;version="2.2.0",
+ javafx.scene.control;version="2.2.0",
+ javafx.scene.control.cell;version="2.2.0",
+ javafx.scene.effect;version="2.2.0",
+ javafx.scene.image;version="2.2.0",
+ javafx.scene.input;version="2.2.0",
+ javafx.scene.layout;version="2.2.0",
+ javafx.scene.media;version="2.2.0",
+ javafx.scene.paint;version="2.2.0",
+ javafx.scene.shape;version="2.2.0",
+ javafx.scene.text;version="2.2.0",
+ javafx.scene.transform;version="2.2.0",
+ javafx.scene.web;version="2.2.0",
+ javafx.stage;version="2.2.0",
+ javafx.util;version="2.2.0",
+ javafx.util.converter;version="2.2.0"
diff --git a/bundles/runtime/org.eclipse.fx.core.databinding.tests/build.properties b/bundles/runtime/org.eclipse.fx.core.databinding.tests/build.properties
new file mode 100644
index 000000000..34d2e4d2d
--- /dev/null
+++ b/bundles/runtime/org.eclipse.fx.core.databinding.tests/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
diff --git a/bundles/runtime/org.eclipse.fx.core.databinding.tests/src/org/eclipse/fx/core/databinding/tests/AdapterFactoryTests.java b/bundles/runtime/org.eclipse.fx.core.databinding.tests/src/org/eclipse/fx/core/databinding/tests/AdapterFactoryTests.java
new file mode 100644
index 000000000..e56a094a1
--- /dev/null
+++ b/bundles/runtime/org.eclipse.fx.core.databinding.tests/src/org/eclipse/fx/core/databinding/tests/AdapterFactoryTests.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2012 BestSolution.at and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.fx.core.databinding.tests;
+
+import javafx.util.Callback;
+
+import org.eclipse.core.databinding.observable.list.IObservableList;
+import org.eclipse.core.databinding.observable.list.WritableList;
+import org.eclipse.fx.core.databinding.AdapterFactory;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+@RunWith(RealmRunner.class)
+public class AdapterFactoryTests {
+
+ @Test
+ public void convertObservableList() {
+ WritableList l = new WritableList();
+ l.add("1");
+ l.add("2");
+ l.add("3");
+ l.add("1");
+
+ IObservableList target = AdapterFactory.convertObservableList(l, new Callback<String, Integer>() {
+
+ @Override
+ public Integer call(String param) {
+ return Integer.parseInt(param);
+ }
+ });
+ assertEquals(l.size(), target.size());
+ assertEquals(((Integer)target.get(0)).intValue(), 1);
+ assertEquals(((Integer)target.get(1)).intValue(), 2);
+ assertEquals(((Integer)target.get(2)).intValue(), 3);
+ assertEquals(((Integer)target.get(3)).intValue(), 1);
+ l.add("4");
+ assertEquals(l.size(), target.size());
+ assertEquals(((Integer)target.get(4)).intValue(), 4);
+ l.remove("2");
+ assertEquals(l.size(), target.size());
+ assertEquals(((Integer)target.get(1)).intValue(), 3);
+ l.add(1,"2");
+ assertEquals(((Integer)target.get(1)).intValue(), 2);
+ }
+}
diff --git a/bundles/runtime/org.eclipse.fx.core.databinding.tests/src/org/eclipse/fx/core/databinding/tests/RealmRunner.java b/bundles/runtime/org.eclipse.fx.core.databinding.tests/src/org/eclipse/fx/core/databinding/tests/RealmRunner.java
new file mode 100644
index 000000000..2f787d0ee
--- /dev/null
+++ b/bundles/runtime/org.eclipse.fx.core.databinding.tests/src/org/eclipse/fx/core/databinding/tests/RealmRunner.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2013 __COMPANY/CONTRIBUTOR__ and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * tomschindl<__EMAIL__> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.fx.core.databinding.tests;
+
+import org.eclipse.core.databinding.observable.Realm;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.model.InitializationError;
+
+/**
+ *
+ */
+public class RealmRunner extends BlockJUnit4ClassRunner {
+ static class DummyRealm extends Realm {
+
+ @Override
+ public boolean isCurrent() {
+ return true;
+ }
+
+ }
+
+ /**
+ * @param klass
+ * @throws InitializationError
+ */
+ public RealmRunner(Class<?> klass) throws InitializationError {
+ super(klass);
+ }
+
+ @Override
+ public void run(RunNotifier notifier) {
+ Realm.runWithDefault(new DummyRealm(), new Runnable() {
+
+ @Override
+ public void run() {
+ RealmRunner.super.run(notifier);
+ }
+ });
+ }
+}
diff --git a/bundles/runtime/org.eclipse.fx.core.databinding/src/org/eclipse/fx/core/databinding/AdapterFactory.java b/bundles/runtime/org.eclipse.fx.core.databinding/src/org/eclipse/fx/core/databinding/AdapterFactory.java
index ec02eec4b..a3a358e48 100755
--- a/bundles/runtime/org.eclipse.fx.core.databinding/src/org/eclipse/fx/core/databinding/AdapterFactory.java
+++ b/bundles/runtime/org.eclipse.fx.core.databinding/src/org/eclipse/fx/core/databinding/AdapterFactory.java
@@ -17,6 +17,7 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
+import java.util.Map;
import java.util.Spliterator;
import java.util.function.Consumer;
@@ -28,15 +29,19 @@ import javafx.beans.value.WritableValue;
import javafx.collections.ListChangeListener;
import javafx.collections.ListChangeListener.Change;
import javafx.collections.ObservableList;
+import javafx.util.Callback;
import org.eclipse.core.databinding.observable.ChangeEvent;
import org.eclipse.core.databinding.observable.DisposeEvent;
import org.eclipse.core.databinding.observable.IChangeListener;
import org.eclipse.core.databinding.observable.IDisposeListener;
+import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.core.databinding.observable.list.IListChangeListener;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.observable.list.ListChangeEvent;
import org.eclipse.core.databinding.observable.list.ListDiffEntry;
+import org.eclipse.core.databinding.observable.list.ListDiffVisitor;
+import org.eclipse.core.databinding.observable.list.WritableList;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.observable.value.IValueChangeListener;
import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
@@ -537,9 +542,13 @@ public class AdapterFactory {
/**
* Bind an javafx observable value to a eclipse db observable
- * @param fxObs the javafx observable
- * @param dbObs the eclipse db observable
- * @param initialSync the initial sync direction
+ *
+ * @param fxObs
+ * the javafx observable
+ * @param dbObs
+ * the eclipse db observable
+ * @param initialSync
+ * the initial sync direction
*/
@SuppressWarnings("unchecked")
public static <E, F extends ObservableValue<E> & WritableValue<E>> void bind(F fxObs, IObservableValue dbObs, InitialSync initialSync) {
@@ -552,6 +561,190 @@ public class AdapterFactory {
do_bind(fxObs, wrapped);
}
+ /**
+ * Creates an <b>readonly</b> observable list which is backed by the source list but the values are converted using the
+ * converter
+ *
+ * @param source
+ * the source list
+ * @param converter
+ * the converter
+ * @return observable list with converter value
+ */
+ @SuppressWarnings("unchecked")
+ public static <S, T> IObservableList convertObservableList(IObservableList source, Callback<S, T> converter) {
+ ReadonlyWritableList target = new ReadonlyWritableList(source.getRealm());
+
+ try {
+ target.modifiable = true;
+ for (Object o : source) {
+ target.add(converter.call((S)o));
+ }
+ } finally {
+ target.modifiable = false;
+ }
+
+ source.addListChangeListener(new IListChangeListener() {
+
+ @Override
+ public void handleListChange(ListChangeEvent event) {
+ event.diff.accept(new ListDiffVisitor() {
+
+ @Override
+ public void handleRemove(int index, Object element) {
+ try {
+ target.modifiable = true;
+ target.remove(index);
+ } finally {
+ target.modifiable = false;
+ }
+ }
+
+ @Override
+ public void handleAdd(int index, Object element) {
+ try {
+ target.modifiable = true;
+ target.add(index, converter.call((S) element));
+ } finally {
+ target.modifiable = false;
+ }
+ }
+
+ @Override
+ public void handleReplace(int index, Object oldElement, Object newElement) {
+ try {
+ target.modifiable = true;
+ target.set(index, converter.call((S) newElement));
+ } finally {
+ target.modifiable = false;
+ }
+ }
+
+ @Override
+ public void handleMove(int oldIndex, int newIndex, Object element) {
+ try {
+ target.modifiable = true;
+ target.move(oldIndex, newIndex);
+ } finally {
+ target.modifiable = false;
+ }
+ }
+ });
+ }
+ });
+
+ return target;
+ }
+
+ static class ReadonlyWritableList extends WritableList {
+ boolean modifiable;
+
+ public ReadonlyWritableList(Realm r) {
+ super(r);
+ }
+
+ @Override
+ public Object set(int index, Object element) {
+ if( ! this.modifiable ) {
+ throw new UnsupportedOperationException("Unmodifiable list"); //$NON-NLS-1$
+ }
+ return super.set(index, element);
+ }
+
+ @Override
+ public Object move(int oldIndex, int newIndex) {
+ if( ! this.modifiable ) {
+ throw new UnsupportedOperationException("Unmodifiable list"); //$NON-NLS-1$
+ }
+ return super.move(oldIndex, newIndex);
+ }
+
+ @Override
+ public Object remove(int index) {
+ if( ! this.modifiable ) {
+ throw new UnsupportedOperationException("Unmodifiable list"); //$NON-NLS-1$
+ }
+ return super.remove(index);
+ }
+
+ @Override
+ public boolean add(Object element) {
+ if( ! this.modifiable ) {
+ throw new UnsupportedOperationException("Unmodifiable list"); //$NON-NLS-1$
+ }
+ return super.add(element);
+ }
+
+ @Override
+ public void add(int index, Object element) {
+ if( ! this.modifiable ) {
+ throw new UnsupportedOperationException("Unmodifiable list"); //$NON-NLS-1$
+ }
+ super.add(index, element);
+ }
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ public boolean addAll(Collection c) {
+ if( ! this.modifiable ) {
+ throw new UnsupportedOperationException("Unmodifiable list"); //$NON-NLS-1$
+ }
+ return super.addAll(c);
+ }
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ public boolean addAll(int index, Collection c) {
+ if( ! this.modifiable ) {
+ throw new UnsupportedOperationException("Unmodifiable list"); //$NON-NLS-1$
+ }
+ return super.addAll(index, c);
+ }
+
+ @Override
+ public boolean remove(Object o) {
+ if( ! this.modifiable ) {
+ throw new UnsupportedOperationException("Unmodifiable list"); //$NON-NLS-1$
+ }
+ return super.remove(o);
+ }
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ public boolean removeAll(Collection c) {
+ if( ! this.modifiable ) {
+ throw new UnsupportedOperationException("Unmodifiable list"); //$NON-NLS-1$
+ }
+ return super.removeAll(c);
+ }
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ public boolean retainAll(Collection c) {
+ if( ! this.modifiable ) {
+ throw new UnsupportedOperationException("Unmodifiable list"); //$NON-NLS-1$
+ }
+ return super.retainAll(c);
+ }
+
+ @Override
+ public void clear() {
+ if( ! this.modifiable ) {
+ throw new UnsupportedOperationException("Unmodifiable list"); //$NON-NLS-1$
+ }
+ super.clear();
+ }
+ }
+
+ static <S, T> T convertIt(S object, Callback<S, T> converter, Map<S, T> cache) {
+ T t = cache.get(object);
+ if (t == null) {
+ t =
+ cache.put(object, t);
+ }
+ return t;
+ }
+
private static <E, F extends ObservableValue<E> & WritableValue<E>> void do_bind(final F fxObs, final F dbObs) {
fxObs.addListener(new ChangeListener<E>() {
boolean syncing;

Back to the top