/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * 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: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.g2d.image.impl; import java.awt.Shape; import java.awt.geom.Rectangle2D; import java.lang.ref.WeakReference; import java.util.EnumSet; import org.simantics.g2d.image.Image; import org.simantics.scenegraph.Node; import org.simantics.scenegraph.g2d.G2DParentNode; import org.simantics.utils.datastructures.ListenerList; /** * ImageProxy keeps strong reference to an original image, but weak reference * from original image to proxy image. *

* Listeners attached to ImageProxy relays events from the original image. * * @author Toni Kalajainen */ public class ImageProxy implements Image { ListenerList list = null; /** Strong reference to the original image */ Image source; Node node = null; /** Listener for the original image */ WeakImageListener sourceListener; public ImageProxy(Image original) { if (original==null) throw new IllegalArgumentException("null arg"); this.source = original; } protected void notifyChanged() { ImageListener[] listeners; synchronized(this) { if (list==null) return; listeners = list.getListeners(); } for (ImageListener l : listeners) l.onContentChangedNotification(this); } @Override public synchronized void addImageListener(ImageListener listener) { if (list==null) list = new ListenerList(ImageListener.class); if (sourceListener==null) { sourceListener = new WeakImageListener(this); source.addImageListener(sourceListener); } list.add(listener); } @Override public synchronized void removeImageListener(ImageListener listener) { if (list==null) return; list.remove(listener); if (list.isEmpty()) { source.removeImageListener(sourceListener); } } static class WeakImageListener implements ImageListener { WeakReference ref; public WeakImageListener(ImageProxy img) { ref = new WeakReference(img); } @Override public void onContentChangedNotification(Image image) { ImageProxy i = ref.get(); if (i == null) { image.removeImageListener(this); } else { i.notifyChanged(); } } } @Override public Rectangle2D getBounds() { return source.getBounds(); } @Override public EnumSet getFeatures() { return source.getFeatures(); } @Override public Shape getOutline() { return source.getOutline(); } @Override public Node init(G2DParentNode parent) { this.node = source.init(parent); return this.node; } public synchronized void setSource(Image newSource) { if (newSource==null) throw new IllegalArgumentException("null"); if (source == newSource) return; Image oldSource = source; if(node != null) { node.remove(); // FIXME node = null; } source = newSource; if (sourceListener!=null) { oldSource.removeImageListener(sourceListener); newSource.addImageListener(sourceListener); } notifyChanged(); } }