]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.g2d/src/org/simantics/g2d/image/impl/ImageProxy.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.g2d / src / org / simantics / g2d / image / impl / ImageProxy.java
diff --git a/bundles/org.simantics.g2d/src/org/simantics/g2d/image/impl/ImageProxy.java b/bundles/org.simantics.g2d/src/org/simantics/g2d/image/impl/ImageProxy.java
new file mode 100644 (file)
index 0000000..abad207
--- /dev/null
@@ -0,0 +1,136 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.g2d.image.impl;\r
+\r
+import java.awt.Shape;\r
+import java.awt.geom.Rectangle2D;\r
+import java.lang.ref.WeakReference;\r
+import java.util.EnumSet;\r
+\r
+import org.simantics.g2d.image.Image;\r
+import org.simantics.scenegraph.Node;\r
+import org.simantics.scenegraph.g2d.G2DParentNode;\r
+import org.simantics.utils.datastructures.ListenerList;\r
+\r
+/**\r
+ * ImageProxy keeps strong reference to an original image, but weak reference\r
+ * from original image to proxy image.\r
+ * <p>\r
+ * Listeners attached to ImageProxy relays events from the original image.\r
+ *\r
+ * @author Toni Kalajainen <toni.kalajainen@vtt.fi>\r
+ */\r
+public class ImageProxy implements Image {\r
+\r
+    ListenerList<ImageListener> list = null;\r
+\r
+    /** Strong reference to the original image */\r
+    Image source;\r
+    Node node = null;\r
+    /** Listener for the original image */\r
+    WeakImageListener sourceListener;\r
+\r
+    public ImageProxy(Image original) {\r
+        if (original==null) throw new IllegalArgumentException("null arg");\r
+        this.source = original;\r
+    }\r
+\r
+    protected void notifyChanged()\r
+    {\r
+        ImageListener[] listeners;\r
+        synchronized(this) {\r
+            if (list==null) return;\r
+            listeners = list.getListeners();\r
+        }\r
+        for (ImageListener l : listeners)\r
+            l.onContentChangedNotification(this);\r
+    }\r
+\r
+    @Override\r
+    public synchronized void addImageListener(ImageListener listener) {\r
+        if (list==null) list = new ListenerList<ImageListener>(ImageListener.class);\r
+        if (sourceListener==null) {\r
+            sourceListener = new WeakImageListener(this);\r
+            source.addImageListener(sourceListener);\r
+        }\r
+        list.add(listener);\r
+    }\r
+\r
+    @Override\r
+    public synchronized void removeImageListener(ImageListener listener) {\r
+        if (list==null) return;\r
+        list.remove(listener);\r
+        if (list.isEmpty()) {\r
+            source.removeImageListener(sourceListener);\r
+        }\r
+    }\r
+\r
+    static class WeakImageListener implements ImageListener {\r
+        WeakReference<ImageProxy> ref;\r
+        public WeakImageListener(ImageProxy img)\r
+        {\r
+            ref = new WeakReference<ImageProxy>(img);\r
+        }\r
+\r
+        @Override\r
+        public void onContentChangedNotification(Image image) {\r
+            ImageProxy i = ref.get();\r
+            if (i == null) {\r
+                image.removeImageListener(this);\r
+            } else {\r
+                i.notifyChanged();\r
+            }\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public Rectangle2D getBounds() {\r
+        return source.getBounds();\r
+    }\r
+\r
+    @Override\r
+    public EnumSet<Feature> getFeatures() {\r
+        return source.getFeatures();\r
+    }\r
+\r
+    @Override\r
+    public Shape getOutline() {\r
+        return source.getOutline();\r
+    }\r
+\r
+    @Override\r
+    public Node init(G2DParentNode parent) {\r
+        this.node = source.init(parent);\r
+        return this.node;\r
+    }\r
+\r
+    public synchronized void setSource(Image newSource) {\r
+        if (newSource==null) throw new IllegalArgumentException("null");\r
+        if (source == newSource) return;\r
+        Image oldSource = source;\r
+        if(node != null) {\r
+            node.remove(); // FIXME\r
+            node = null;\r
+        }\r
+\r
+        source = newSource;\r
+\r
+        if (sourceListener!=null) {\r
+            oldSource.removeImageListener(sourceListener);\r
+            newSource.addImageListener(sourceListener);\r
+        }\r
+\r
+        notifyChanged();\r
+    }\r
+\r
+}\r
+\r