]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.g2d/src/org/simantics/g2d/image/impl/ImageProxy.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.g2d / src / org / simantics / g2d / image / impl / ImageProxy.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.g2d.image.impl;
13
14 import java.awt.Shape;
15 import java.awt.geom.Rectangle2D;
16 import java.lang.ref.WeakReference;
17 import java.util.EnumSet;
18
19 import org.simantics.g2d.image.Image;
20 import org.simantics.scenegraph.Node;
21 import org.simantics.scenegraph.g2d.G2DParentNode;
22 import org.simantics.utils.datastructures.ListenerList;
23
24 /**
25  * ImageProxy keeps strong reference to an original image, but weak reference
26  * from original image to proxy image.
27  * <p>
28  * Listeners attached to ImageProxy relays events from the original image.
29  *
30  * @author Toni Kalajainen <toni.kalajainen@vtt.fi>
31  */
32 public class ImageProxy implements Image {
33
34     ListenerList<ImageListener> list = null;
35
36     /** Strong reference to the original image */
37     Image source;
38     Node node = null;
39     /** Listener for the original image */
40     WeakImageListener sourceListener;
41
42     public ImageProxy(Image original) {
43         if (original==null) throw new IllegalArgumentException("null arg");
44         this.source = original;
45     }
46
47     protected void notifyChanged()
48     {
49         ImageListener[] listeners;
50         synchronized(this) {
51             if (list==null) return;
52             listeners = list.getListeners();
53         }
54         for (ImageListener l : listeners)
55             l.onContentChangedNotification(this);
56     }
57
58     @Override
59     public synchronized void addImageListener(ImageListener listener) {
60         if (list==null) list = new ListenerList<ImageListener>(ImageListener.class);
61         if (sourceListener==null) {
62             sourceListener = new WeakImageListener(this);
63             source.addImageListener(sourceListener);
64         }
65         list.add(listener);
66     }
67
68     @Override
69     public synchronized void removeImageListener(ImageListener listener) {
70         if (list==null) return;
71         list.remove(listener);
72         if (list.isEmpty()) {
73             source.removeImageListener(sourceListener);
74         }
75     }
76
77     static class WeakImageListener implements ImageListener {
78         WeakReference<ImageProxy> ref;
79         public WeakImageListener(ImageProxy img)
80         {
81             ref = new WeakReference<ImageProxy>(img);
82         }
83
84         @Override
85         public void onContentChangedNotification(Image image) {
86             ImageProxy i = ref.get();
87             if (i == null) {
88                 image.removeImageListener(this);
89             } else {
90                 i.notifyChanged();
91             }
92         }
93     }
94
95     @Override
96     public Rectangle2D getBounds() {
97         return source.getBounds();
98     }
99
100     @Override
101     public EnumSet<Feature> getFeatures() {
102         return source.getFeatures();
103     }
104
105     @Override
106     public Shape getOutline() {
107         return source.getOutline();
108     }
109
110     @Override
111     public Node init(G2DParentNode parent) {
112         this.node = source.init(parent);
113         return this.node;
114     }
115
116     public synchronized void setSource(Image newSource) {
117         if (newSource==null) throw new IllegalArgumentException("null");
118         if (source == newSource) return;
119         Image oldSource = source;
120         if(node != null) {
121             node.remove(); // FIXME
122             node = null;
123         }
124
125         source = newSource;
126
127         if (sourceListener!=null) {
128             oldSource.removeImageListener(sourceListener);
129             newSource.addImageListener(sourceListener);
130         }
131
132         notifyChanged();
133     }
134
135 }
136