/*************************************************** * * cismet GmbH, Saarbruecken, Germany * * ... and it just works. * ****************************************************/ /* * BackgroundRefreshingPanEventListener.java * * Created on 15. M\u00E4rz 2005, 11:22 */ package de.cismet.cismap.commons.gui.piccolo.eventlistener; import edu.umd.cs.piccolo.PNode; import edu.umd.cs.piccolo.event.PInputEvent; import edu.umd.cs.piccolo.event.PPanEventHandler; import edu.umd.cs.piccolo.nodes.PImage; import java.awt.Graphics; import java.awt.Image; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.List; import java.util.concurrent.locks.ReentrantReadWriteLock; import javax.swing.JComponent; import de.cismet.cismap.commons.gui.MappingComponent; import de.cismet.cismap.commons.interaction.CismapBroker; import de.cismet.tools.StaticDebuggingTools; /** * DOCUMENT ME! * * @author hell * @version $Revision$, $Date$ */ public class BackgroundRefreshingPanEventListener extends PPanEventHandler implements PropertyChangeListener { //~ Instance fields -------------------------------------------------------- PImage pi; boolean rasterServiceLayerVisible = true; private boolean imageBoosterActive = false; private final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(this.getClass()); private List<PNode> nodesToEnable = new ArrayList<PNode>(); private MappingComponent mappingComponent; private volatile Image image = null; private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); private boolean panStarted = false; //~ Constructors ----------------------------------------------------------- /** * Creates a new BackgroundRefreshingPanEventListener object. */ public BackgroundRefreshingPanEventListener() { setAutopan(false); } //~ Methods ---------------------------------------------------------------- @Override protected void dragActivityFinalStep(final edu.umd.cs.piccolo.event.PInputEvent pInputEvent) { // TODO // 1. DragBild unsichtbar machen // 2. Alle FeatureLayer die sichtbar sein sollen wieder sichtbar machen super.dragActivityFinalStep(pInputEvent); panStarted = false; // if (pInputEvent.getComponent() instanceof SimpleFeatureViewer) { // ((SimpleFeatureViewer)pInputEvent.getComponent()).refreshBackground(); // } if (pInputEvent.getComponent() instanceof MappingComponent) { final MappingComponent mc = (MappingComponent)pInputEvent.getComponent(); // mc.showHandles(false); if (imageBoosterActive) { // if (mappingComponent == null) { // mappingComponent = mc; // mc.getCamera().addPropertyChangeListener(this); // } mc.getRasterServiceLayer().setVisible(rasterServiceLayerVisible); mc.getDragPerformanceImproverLayer().setVisible(false); mc.getDragPerformanceImproverLayer().removeAllChildren(); for (final PNode node : nodesToEnable) { node.setVisible(true); } mc.getFeatureLayer().setVisible(true); } final Rectangle2D oldBounds = mc.getViewBounds(); final Rectangle2D newBounds = mc.getCamera().getViewBounds(); if (!newBounds.equals(oldBounds)) { mc.setNewViewBounds(newBounds); mc.queryServices(); } } // propertyChange(null); } /** * Override this method to get notified when the drag activity starts stepping. * * @param aEvent DOCUMENT ME! */ @Override protected void dragActivityFirstStep(final edu.umd.cs.piccolo.event.PInputEvent aEvent) { // 1. Schritt ein Bild des aktuellen PCanvas schiessen // 2. Dieses Bild als obersten Layer einblenden und richtig positionieren // 3. Alle FeatureLayer unsichtbar machen panStarted = true; if (aEvent.getComponent() instanceof MappingComponent) { final MappingComponent mc = (MappingComponent)aEvent.getComponent(); // mc.getHandleLayer().removeAllChildren(); imageBoosterActive = StaticDebuggingTools.checkHomeForFile("panPerformanceBooster"); if (imageBoosterActive) { if (log.isDebugEnabled()) { log.debug("isPanPerformanceBoosterEnabled"); // NOI18N } refreshImage(mc); mc.getDragPerformanceImproverLayer().setVisible(true); mc.getRasterServiceLayer().setVisible(false); for (int i = 0; i < mc.getMapServiceLayer().getChildrenCount(); ++i) { final PNode tmp = mc.getMapServiceLayer().getChild(i); if (tmp.getVisible()) { tmp.setVisible(false); nodesToEnable.add(tmp); } } mc.getFeatureLayer().setVisible(false); } } super.dragActivityFirstStep(aEvent); } /** * DOCUMENT ME! * * @param mc DOCUMENT ME! */ private void refreshImage(final MappingComponent mc) { // Hier gibts bei gro\u00DFen Bildern noch ein Performanceproblem // kann dadurch gel\u00F6st werden indem man diese Bild schon vorher erzeugt und // hier nur noch \u00FCberpr\u00FCft ob es aktualisiert werden muss. // evtl auch nur einen einfachen Layer nehmen. Vielleicht bringts das auch schon rasterServiceLayerVisible = mc.getRasterServiceLayer().getVisible(); // lock.readLock().lock(); // try { // if (image == null) { image = mc.getCamera().toImage(); // } pi = new PImage(image); // } finally { // lock.readLock().unlock(); // } mc.getDragPerformanceImproverLayer().removeAllChildren(); mc.getDragPerformanceImproverLayer().addChild(pi); // Point2D p2d= // new Point(0,0)); pi.scale(1 / mc.getCamera().getViewScale()); pi.setOffset(mc.getCamera().getViewBounds().getOrigin()); pi.setTransparency(0.5f); } /** * Draws an image from a component. * * @param component DOCUMENT ME! * * @return the given component as image */ private BufferedImage componentToImage(final JComponent component) { final BufferedImage img = new BufferedImage(component.getWidth(), component.getHeight(), BufferedImage.TYPE_INT_ARGB_PRE); final Graphics g = img.getGraphics(); g.setColor(component.getForeground()); g.setFont(component.getFont()); component.paintAll(g); return img.getSubimage(0, 0, img.getWidth(), img.getHeight()); } @Override public void mouseDragged(final PInputEvent e) { super.mouseDragged(e); CismapBroker.getInstance().fireMapBoundsChanged(); } @Override public void propertyChange(final PropertyChangeEvent evt) { if (!panStarted) { image = null; new Thread(new Runnable() { @Override public void run() { lock.writeLock().lock(); try { image = mappingComponent.getCamera().toImage(); // image = componentToImage(mappingComponent); } finally { lock.writeLock().unlock(); } } }).start(); } } }