001: /**
002: * <copyright></copyright> $Id: RenderExecutorImpl.java 25815 2007-06-12 12:33:58Z vitalus $
003: */package net.refractions.udig.project.internal.render.impl;
004:
005: import java.awt.Dimension;
006: import java.awt.Graphics2D;
007: import java.awt.Point;
008: import java.awt.Rectangle;
009: import java.text.MessageFormat;
010: import java.util.Iterator;
011: import java.util.List;
012: import java.util.concurrent.atomic.AtomicBoolean;
013:
014: import net.refractions.udig.project.ILayer;
015: import net.refractions.udig.project.internal.Layer;
016: import net.refractions.udig.project.internal.Messages;
017: import net.refractions.udig.project.internal.ProjectPackage;
018: import net.refractions.udig.project.internal.ProjectPlugin;
019: import net.refractions.udig.project.internal.impl.SynchronizedEList;
020: import net.refractions.udig.project.internal.render.ExecutorVisitor;
021: import net.refractions.udig.project.internal.render.RenderContext;
022: import net.refractions.udig.project.internal.render.RenderExecutor;
023: import net.refractions.udig.project.internal.render.RenderManager;
024: import net.refractions.udig.project.internal.render.RenderPackage;
025: import net.refractions.udig.project.internal.render.Renderer;
026: import net.refractions.udig.project.internal.render.SelectionLayer;
027: import net.refractions.udig.project.render.ILabelPainter;
028: import net.refractions.udig.project.render.IRenderContext;
029: import net.refractions.udig.project.render.IRenderer;
030: import net.refractions.udig.project.render.RenderException;
031:
032: import org.eclipse.core.runtime.IProgressMonitor;
033: import org.eclipse.core.runtime.IStatus;
034: import org.eclipse.core.runtime.NullProgressMonitor;
035: import org.eclipse.core.runtime.Status;
036: import org.eclipse.core.runtime.SubProgressMonitor;
037: import org.eclipse.core.runtime.jobs.IJobChangeEvent;
038: import org.eclipse.core.runtime.jobs.IJobChangeListener;
039: import org.eclipse.core.runtime.jobs.ISchedulingRule;
040: import org.eclipse.core.runtime.jobs.Job;
041: import org.eclipse.core.runtime.jobs.JobChangeAdapter;
042: import org.eclipse.emf.common.notify.Adapter;
043: import org.eclipse.emf.common.notify.Notification;
044: import org.eclipse.emf.common.notify.impl.AdapterImpl;
045: import org.eclipse.emf.ecore.EClass;
046: import org.eclipse.emf.ecore.EStructuralFeature;
047: import org.eclipse.emf.ecore.impl.ENotificationImpl;
048:
049: import com.vividsolutions.jts.geom.Coordinate;
050: import com.vividsolutions.jts.geom.Envelope;
051:
052: /**
053: * Runs a renderer in its own thread. Is responsible for stopping the thread. Does not do composite
054: * renderer or multilayer renderers.
055: *
056: * @author Jesse
057: * @since 1.0.0
058: */
059: public class RenderExecutorImpl extends RendererImpl implements
060: RenderExecutor {
061: /**
062: * Listens to a layer for visibility events and styling events. <b>Public ONLY for testing
063: * purposes</b>
064: *
065: * @author Jesse
066: * @since 1.0.0
067: */
068: public static class LayerListener extends AdapterImpl {
069: protected RenderExecutorImpl executor;
070:
071: LayerListener(RenderExecutorImpl executor) {
072: this .executor = executor;
073: }
074:
075: /**
076: * @see org.eclipse.emf.common.notify.impl.AdapterImpl#notifyChanged(org.eclipse.emf.common.notify.Notification)
077: */
078: public void notifyChanged(Notification msg) {
079: Layer layer = (Layer) msg.getNotifier();
080: switch (msg.getFeatureID(Layer.class)) {
081: case ProjectPackage.LAYER__STYLE_BLACKBOARD:
082: if (executor.getContext().getLayer() instanceof SelectionLayer)
083: return;
084:
085: styleBlackboardChanged(msg);
086: break;
087: case ProjectPackage.LAYER__VISIBLE:
088: if (executor.getContext().getLayer() instanceof SelectionLayer)
089: return;
090: if (msg.getNewBooleanValue())
091: layerVisible(layer, msg);
092: else
093: layerNotVisible(layer, msg);
094: break;
095:
096: default:
097: break;
098: }
099: }
100:
101: protected void layerNotVisible(Layer layer, Notification msg) {
102: RenderContext context2 = executor.getContext();
103: context2.getLabelPainter().disableLayer(
104: context2.getLayer().getID().toString());
105: if (executor.getState() == RENDERING) {
106: executor.stopRendering();
107: context2.setStatus(ILayer.DONE);
108: context2.setStatusMessage(""); //$NON-NLS-1$
109:
110: executor.setState(NEVER);
111: } else {
112: RenderManager renderManager = (RenderManager) layer
113: .getMapInternal().getRenderManager();
114: if (renderManager != null) {
115: try {
116: RenderExecutorImpl renderExecutorImpl = ((RenderExecutorImpl) renderManager
117: .getRenderExecutor());
118: ((CompositeRendererImpl) renderExecutorImpl
119: .getRenderer()).refreshImage();
120: renderExecutorImpl.setState(IRenderer.DONE);
121: } catch (RenderException e) {
122: ProjectPlugin.log("", e); //$NON-NLS-1$
123: }
124: }
125: }
126: }
127:
128: protected void layerVisible(Layer layer, Notification msg) {
129: RenderContext context2 = executor.getContext();
130: context2.getLabelPainter().enableLayer(
131: context2.getLayer().getID().toString());
132: if (executor.getState() == IRenderer.RENDERING)
133: return;
134: if (executor.getState() != IRenderer.DONE || executor.dirty) {
135: executor.getRenderer().setState(RENDER_REQUEST);
136: } else {
137: RenderManager renderManager = (RenderManager) layer
138: .getMapInternal().getRenderManager();
139: if (renderManager != null) {
140: try {
141: RenderExecutorImpl renderExecutorImpl = ((RenderExecutorImpl) renderManager
142: .getRenderExecutor());
143: ((CompositeRendererImpl) renderExecutorImpl
144: .getRenderer()).refreshImage();
145: renderExecutorImpl.setState(IRenderer.DONE);
146: } catch (RenderException e) {
147: ProjectPlugin.log("", e); //$NON-NLS-1$
148: }
149: }
150:
151: }
152:
153: }
154:
155: protected void styleBlackboardChanged(Notification msg) {
156: executor.getContext().getRenderManager().refresh(
157: (ILayer) msg.getNotifier(), null);
158: }
159: }
160:
161: protected static class RendererListener extends AdapterImpl {
162:
163: protected RenderExecutor executor;
164:
165: RendererListener(RenderExecutor executor) {
166: this .executor = executor;
167: }
168:
169: /**
170: * @see org.eclipse.emf.common.notify.impl.AdapterImpl#notifyChanged(org.eclipse.emf.common.notify.Notification)
171: */
172: public void notifyChanged(Notification msg) {
173: if (msg.getNotifier() instanceof Renderer) {
174: if (msg.getFeatureID(Renderer.class) == RenderPackage.RENDERER__STATE) {
175: if (msg.getNewIntValue() == IRenderer.RENDER_REQUEST) {
176: executor.setRenderBounds(executor.getRenderer()
177: .getRenderBounds());
178: }
179: stateChanged(msg);
180: }
181: }
182:
183: }
184:
185: protected void stateChanged(Notification msg) {
186: if (msg.getNewIntValue() == IRenderer.RENDER_REQUEST) {
187: try {
188: executor.render();
189: } catch (RenderException e) {
190: // won't happen
191: throw (RuntimeException) new RuntimeException()
192: .initCause(e);
193: }
194: }
195: executor.setState(msg.getNewIntValue());
196:
197: }
198: }
199:
200: /**
201: * <!-- begin-user-doc --> <!-- end-user-doc -->
202: *
203: * @generated
204: */
205: public static final String copyright = "uDig - User Friendly Desktop Internet GIS client http://udig.refractions.net (C) 2004, Refractions Research Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; version 2.1 of the License. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details."; //$NON-NLS-1$
206:
207: /**
208: * An eclipse job that renders a layer. Allows each renderer to run in a seperate thread.
209: *
210: * @author Jesse
211: * @since 1.0.0
212: */
213: protected static class RenderJob extends Job {
214: protected volatile IProgressMonitor monitor;
215:
216: protected RenderExecutor executor;
217:
218: Envelope bounds;
219:
220: /**
221: * Creates an new instance of AbstractRenderer.RenderThread
222: */
223: public RenderJob(RenderExecutor executor) {
224: super (Messages.RenderExecutorImpl_title);
225: this .executor = executor;
226: init();
227:
228: }
229:
230: protected void init() {
231: setRule(new RenderJobRule());
232: setSystem(true);
233: }
234:
235: /**
236: * A scheduling rule that serializes all rendering operations that hit the local filesystem, to
237: * avoid bogging down the PC, and lets other kind of georesources be accessed and rendered in a
238: * parallel fashion. <br/>
239: * The georesource id is used as a discriminator, a Georesource is supposed to be local if its
240: * id starts with "file:/"
241: */
242: private class RenderJobRule implements ISchedulingRule {
243:
244: public boolean isConflicting(ISchedulingRule rule) {
245: if (!(rule instanceof RenderJobRule))
246: return false;
247:
248: RenderJobRule other = (RenderJobRule) rule;
249: if (other == this )
250: return true;
251: else if (getRenderer() instanceof CompositeRendererImpl)
252: return false;
253: else
254: return other.getRenderer().getClass().equals(
255: getRenderer().getClass())
256: && !isCanceled()
257: && !other.isCanceled()
258: && isUsingLocalResources(getRenderer())
259: && isUsingLocalResources(other
260: .getRenderer());
261:
262: }
263:
264: private boolean isUsingLocalResources(Renderer renderer) {
265: try {
266: return renderer.getContext().getGeoResource()
267: .getIdentifier().toString().startsWith(
268: "file:/"); //$NON-NLS-1$
269: } catch (Exception e) {
270: return false;
271: }
272: }
273:
274: public boolean contains(ISchedulingRule rule) {
275: return isConflicting(rule);
276: }
277:
278: Renderer getRenderer() {
279: return executor.getRenderer();
280: }
281:
282: boolean isCanceled() {
283: if (getMonitor() != null)
284: return getMonitor().isCanceled();
285: else
286: return false;
287: }
288:
289: }
290:
291: /**
292: * @return Returns the executor.
293: */
294: public RenderExecutor getExecutor() {
295: return executor;
296: }
297:
298: /**
299: * Returns the progress monitor or null if not rendering.
300: *
301: * @return the progress monitor or null if not rendering.
302: * @uml.property name="monitor"
303: */
304: public IProgressMonitor getMonitor() {
305: return monitor;
306: }
307:
308: protected void startRendering(Envelope bounds2,
309: IProgressMonitor monitor) throws Throwable {
310: Envelope bounds = bounds2;
311: //validate bounds
312: IRenderContext context2 = getExecutor().getContext();
313: if (bounds == null
314: || bounds.contains(context2.getViewportModel()
315: .getBounds())) {
316: bounds = null;
317: }
318:
319: if (executor.getState() == IRenderer.RENDER_REQUEST
320: || executor.getState() == IRenderer.STARTING) {
321: //Must not be called while state has to be IRenderer.RENDERING at this point already
322: clearImage(bounds, getExecutor());
323: }
324:
325: // If the start of the renderer is a render request then
326: if (executor.getRenderer().getState() != IRenderer.RENDER_REQUEST)
327: executor.getRenderer().setRenderBounds(bounds);
328:
329: monitor.beginTask(Messages.RenderExecutorImpl_1,
330: IProgressMonitor.UNKNOWN);
331: if (context2.getLayer() != null) {
332: initializeLabelPainter(context2);
333: }
334:
335: executor.getRenderer().render(
336: new SubProgressMonitor(monitor, 0));
337: }
338:
339: protected void initializeLabelPainter(IRenderContext context2) {
340: String layerId = getLayerId(context2);
341:
342: context2.getLabelPainter().clear(layerId);
343: context2.getLabelPainter().startLayer(layerId);
344: }
345:
346: private String getLayerId(IRenderContext context2) {
347: String layerId = context2.getLayer().getID().toString();
348: if (context2.getLayer() instanceof SelectionLayer)
349: layerId = layerId + "-Selection";
350: return layerId;
351: }
352:
353: protected void finalizeLabelPainter(IRenderContext context2) {
354: String layerId = getLayerId(context2);
355:
356: Dimension displaySize = context2.getMapDisplay()
357: .getDisplaySize();
358: Graphics2D graphics = context2.getImage().createGraphics();
359: try {
360: context2.getLabelPainter().endLayer(
361: layerId,
362: graphics,
363: new Rectangle(0, 0, displaySize.width,
364: displaySize.height));
365: } finally {
366: graphics.dispose();
367: }
368: }
369:
370: protected void handleException(Throwable renderError) {
371: try {
372: ProjectPlugin.getPlugin().log(renderError);
373: if (renderError.getCause() instanceof NullPointerException)
374: handleNullPointerException(renderError);
375: else
376: handleUnknownError(renderError);
377: } catch (Exception e) {
378: ProjectPlugin.log(renderError.getLocalizedMessage(),
379: renderError);
380: }
381: }
382:
383: /**
384: *
385: * @param renderError
386: */
387: private void handleNullPointerException(Throwable renderError) {
388: executor.getContext().setStatus(ILayer.WARNING);
389: executor.getContext().setStatusMessage(
390: Messages.RenderExecutorImpl_2);
391: }
392:
393: /**
394: *
395: * @param renderError
396: */
397: private void handleUnknownError(Throwable renderError) {
398: executor.getContext().setStatus(ILayer.ERROR); // indicate to
399: // user
400: executor.getContext().setStatusMessage(
401: Messages.RenderExecutorImpl_1
402: + renderError.getLocalizedMessage());
403: }
404:
405: protected void postRendering() {
406: finalizeLabelPainter(executor.getContext());
407: // if monitor is cancelled change state to CANCELLED
408: if (monitor.isCanceled()) {
409: executor.getRenderer().setState(CANCELLED);
410: executor.setState(CANCELLED);
411: return;
412: }
413: executor.getRenderer().setState(IRenderer.DONE);
414: }
415:
416: /**
417: * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
418: */
419: protected IStatus run(IProgressMonitor monitor) {
420: setThread(Thread.currentThread());
421:
422: this .monitor = monitor;
423: try {
424: startRendering(bounds, monitor);
425: } catch (Throwable renderError) {
426: handleException(renderError);
427: renderError.printStackTrace();
428: getExecutor().getRenderer().setState(IRenderer.DONE);
429: return Status.OK_STATUS;
430: }
431:
432: postRendering();
433: return Status.OK_STATUS;
434: }
435:
436: @Override
437: public boolean belongsTo(Object family) {
438: if (executor.getContext() == null)
439: return false;
440: return family == executor.getContext().getRenderManager();
441: }
442:
443: /**
444: * @param object
445: */
446: public void setBounds(Envelope bounds) {
447: this .bounds = bounds;
448: }
449:
450: }
451:
452: protected static void clearImage(Envelope bounds2,
453: RenderExecutor executor) {
454: if (bounds2 != null
455: && !bounds2.contains(executor.getContext()
456: .getViewportModel().getBounds())) {
457: Point min = executor.getContext()
458: .worldToPixel(
459: new Coordinate(bounds2.getMinX(), bounds2
460: .getMinY()));
461: Point max = executor.getContext()
462: .worldToPixel(
463: new Coordinate(bounds2.getMaxX(), bounds2
464: .getMaxY()));
465: int width = Math.abs(max.x - min.x);
466: int height = Math.abs(max.y - min.y);
467: Rectangle paintArea = new Rectangle(Math.min(min.x, max.x),
468: Math.min(min.y, max.y), width, height);
469: executor.getContext().clearImage(paintArea);
470: } else {
471: executor.getContext().clearImage();
472: }
473: }
474:
475: /**
476: * The cached value of the '{@link #getRenderer() <em>Renderer</em>}' reference. <!--
477: * begin-user-doc --> <!-- end-user-doc -->
478: *
479: * @see #getRenderer()
480: * @generated
481: * @ordered
482: */
483: protected Renderer renderer = null;
484:
485: protected Adapter renderListener = getRendererListener();
486:
487: /**
488: * A listener that triggers an update when the style of its layer changes or the visibility
489: * changes.
490: */
491: protected Adapter layerListener = getLayerListener();
492:
493: protected RenderJob renderJob;
494:
495: volatile boolean dirty;
496:
497: /**
498: * <!-- begin-user-doc --> <!-- end-user-doc -->
499: *
500: * @generated NOT
501: */
502: public RenderExecutorImpl() {
503: super ();
504: renderJob = new RenderJob(this );
505: }
506:
507: /**
508: * <!-- begin-user-doc --> <!-- end-user-doc -->
509: *
510: * @generated
511: */
512: protected EClass eStaticClass() {
513: return RenderPackage.eINSTANCE.getRenderExecutor();
514: }
515:
516: /**
517: * <!-- begin-user-doc --> <!-- end-user-doc -->
518: *
519: * @generated NOT
520: */
521: public void dispose() {
522: while (getRenderer().eAdapters().remove(renderListener))
523: ;
524: eAdapters().clear();
525: removeLayerListener(getContext());
526: stopRendering();
527: getRenderer().dispose();
528:
529: try {
530: //Clear label cache for this layer.
531: ILayer renderingLayer = getContext().getLayer();
532: if (renderingLayer != null) {
533: //Only if it as a usual layer's renderer
534: ILabelPainter labelPainter = getContext()
535: .getLabelPainter();
536: String layerId = renderingLayer.getID().toString();
537: if (getContext().getLayer() instanceof SelectionLayer)
538: layerId = layerId + "-Selection";
539: labelPainter.clear(layerId);
540: }
541: } catch (Exception exc) {
542: exc.printStackTrace();
543: }
544:
545: if (getRenderer().getState() != DISPOSED)
546: getRenderer().setState(DISPOSED);
547: }
548:
549: /**
550: * @see net.refractions.udig.project.internal.render.impl.RendererImpl#setState(int)
551: */
552: public void setState(int newState) {
553: super .setState(newState);
554: }
555:
556: /**
557: * <!-- begin-user-doc --> <!-- end-user-doc -->
558: *
559: * @generated NOT
560: */
561: public void stopRendering() {
562: if (renderJob.cancel())
563: return;
564: final AtomicBoolean done = new AtomicBoolean(renderJob.cancel());
565: IJobChangeListener listener = new JobChangeAdapter() {
566: @Override
567: public void done(IJobChangeEvent event) {
568: done.set(true);
569: synchronized (done) {
570: done.notify();
571: }
572:
573: }
574: };
575: renderJob.addJobChangeListener(listener);
576: try {
577: long start = System.currentTimeMillis();
578: while (!done.get() && !renderJob.cancel()
579: && start + 2000 < System.currentTimeMillis())
580: synchronized (done) {
581: try {
582: done.wait(200);
583: } catch (InterruptedException e) {
584: throw (RuntimeException) new RuntimeException()
585: .initCause(e);
586: }
587: }
588: if (!done.get() && !renderJob.cancel()) {
589: ProjectPlugin
590: .log("After 2 seconds unable to cancel " + getRenderer().getName() + " Renderer"); //$NON-NLS-1$ //$NON-NLS-2$
591: }
592: } finally {
593: renderJob.removeJobChangeListener(listener);
594: }
595:
596: }
597:
598: /**
599: * <!-- begin-user-doc --> <!-- end-user-doc -->
600: *
601: * @throws RenderException
602: * @generated NOT
603: */
604: public void render(Graphics2D destination, IProgressMonitor monitor)
605: throws RenderException {
606:
607: if (getState() == DISPOSED)
608: return;
609: getRenderer().render(destination, validateMonitor(monitor));
610: }
611:
612: private IProgressMonitor validateMonitor(IProgressMonitor monitor) {
613: if (monitor != null)
614: return monitor;
615:
616: return new NullProgressMonitor();
617: }
618:
619: /**
620: * @see net.refractions.udig.project.internal.render.Renderer#getContext()
621: */
622: public RenderContext getContext() {
623: if (getRenderer() == null)
624: return null;
625: return (RenderContext) getRenderer().getContext();
626: }
627:
628: /**
629: * <!-- begin-user-doc --> <!-- end-user-doc -->
630: *
631: * @generated
632: */
633: public Renderer getRenderer() {
634: return renderer;
635: }
636:
637: protected String getRenderJobName() {
638: return MessageFormat.format(
639: Messages.RenderExecutorImpl_message,
640: new Object[] { getName() });
641: }
642:
643: /**
644: * @see net.refractions.udig.project.internal.render.RenderExecutor#setRenderer(net.refractions.udig.project.render.Renderer)
645: * @uml.property name="renderer"
646: */
647: @SuppressWarnings("unchecked")
648: public void setRenderer(Renderer newRenderer) {
649: if (getRenderer() != null) {
650: getRenderer().eAdapters().remove(renderListener);
651: removeLayerListener((RenderContext) getRenderer()
652: .getContext());
653: }
654: setRendererGen(newRenderer);
655: // registerFeatureListener();
656: if (newRenderer != null) {
657: newRenderer.eAdapters().add(renderListener);
658: addLayerListener((RenderContext) newRenderer.getContext());
659: }
660: }
661:
662: @SuppressWarnings("unchecked")
663: protected void removeLayerListener(IRenderContext context) {
664: if (context.getLayer() != null) {
665: List<Adapter> adapters = ((Layer) context.getLayer())
666: .eAdapters();
667: if (adapters instanceof SynchronizedEList) {
668: ((SynchronizedEList) adapters).lock();
669: }
670: try {
671: for (Iterator<Adapter> iter = adapters.iterator(); iter
672: .hasNext();) {
673: if (iter.next() instanceof RenderExecutorImpl.LayerListener)
674: iter.remove();
675: }
676: } finally {
677: if (adapters instanceof SynchronizedEList) {
678: ((SynchronizedEList) adapters).unlock();
679: }
680: }
681: }
682: }
683:
684: @SuppressWarnings("unchecked")
685: protected void addLayerListener(IRenderContext context) {
686:
687: if (context.getLayer() != null
688: && !(context.getLayer() instanceof SelectionLayer)) {
689: removeLayerListener(context);
690: ((Layer) context.getLayer()).eAdapters().add(layerListener);
691: }
692: }
693:
694: /**
695: * <!-- begin-user-doc --> <!-- end-user-doc -->
696: *
697: * @generated
698: */
699: public void setRendererGen(Renderer newRenderer) {
700: Renderer oldRenderer = renderer;
701: renderer = newRenderer;
702: if (eNotificationRequired())
703: eNotify(new ENotificationImpl(this , Notification.SET,
704: RenderPackage.RENDER_EXECUTOR__RENDERER,
705: oldRenderer, renderer));
706: }
707:
708: /**
709: * <!-- begin-user-doc --> <!-- end-user-doc -->
710: *
711: * @generated
712: */
713: public Object eGet(EStructuralFeature eFeature, boolean resolve) {
714: switch (eDerivedStructuralFeatureID(eFeature)) {
715: case RenderPackage.RENDER_EXECUTOR__STATE:
716: return new Integer(getState());
717: case RenderPackage.RENDER_EXECUTOR__NAME:
718: return getName();
719: case RenderPackage.RENDER_EXECUTOR__CONTEXT:
720: return getContext();
721: case RenderPackage.RENDER_EXECUTOR__RENDERER:
722: return getRenderer();
723: }
724: return eDynamicGet(eFeature, resolve);
725: }
726:
727: /**
728: * <!-- begin-user-doc --> <!-- end-user-doc -->
729: *
730: * @generated
731: */
732: public void eSet(EStructuralFeature eFeature, Object newValue) {
733: switch (eDerivedStructuralFeatureID(eFeature)) {
734: case RenderPackage.RENDER_EXECUTOR__STATE:
735: setState(((Integer) newValue).intValue());
736: return;
737: case RenderPackage.RENDER_EXECUTOR__NAME:
738: setName((String) newValue);
739: return;
740: case RenderPackage.RENDER_EXECUTOR__CONTEXT:
741: setContext((IRenderContext) newValue);
742: return;
743: case RenderPackage.RENDER_EXECUTOR__RENDERER:
744: setRenderer((Renderer) newValue);
745: return;
746: }
747: eDynamicSet(eFeature, newValue);
748: }
749:
750: /**
751: * <!-- begin-user-doc --> <!-- end-user-doc -->
752: *
753: * @generated
754: */
755:
756: public void eUnset(EStructuralFeature eFeature) {
757: switch (eDerivedStructuralFeatureID(eFeature)) {
758: case RenderPackage.RENDER_EXECUTOR__STATE:
759: setState(STATE_EDEFAULT);
760: return;
761: case RenderPackage.RENDER_EXECUTOR__NAME:
762: setName(NAME_EDEFAULT);
763: return;
764: case RenderPackage.RENDER_EXECUTOR__CONTEXT:
765: setContext((IRenderContext) null);
766: return;
767: case RenderPackage.RENDER_EXECUTOR__RENDERER:
768: setRenderer((Renderer) null);
769: return;
770: }
771: eDynamicUnset(eFeature);
772: }
773:
774: /**
775: * <!-- begin-user-doc --> <!-- end-user-doc -->
776: *
777: * @generated
778: */
779: public boolean eIsSet(EStructuralFeature eFeature) {
780: switch (eDerivedStructuralFeatureID(eFeature)) {
781: case RenderPackage.RENDER_EXECUTOR__STATE:
782: return state != STATE_EDEFAULT;
783: case RenderPackage.RENDER_EXECUTOR__NAME:
784: return NAME_EDEFAULT == null ? name != null
785: : !NAME_EDEFAULT.equals(name);
786: case RenderPackage.RENDER_EXECUTOR__CONTEXT:
787: return context != null;
788: case RenderPackage.RENDER_EXECUTOR__RENDERER:
789: return renderer != null;
790: }
791: return eDynamicIsSet(eFeature);
792: }
793:
794: /**
795: * @see net.refractions.udig.project.internal.render.impl.RendererImpl#getInfo(Point, Layer)
796: * public InfoList getInfo(Point screenLocation) throws IOException { if
797: * (!(getContext().getLayer() instanceof SelectionLayer)) return
798: * renderer.getInfo(screenLocation); return new InfoList(screenLocation.x,
799: * screenLocation.y, null); }
800: */
801:
802: /**
803: * @see net.refractions.udig.project.internal.render.RenderExecutor#visit(net.refractions.udig.project.render.ExecutorVisitor)
804: */
805: public void visit(ExecutorVisitor visitor) {
806: visitor.visit(this );
807: }
808:
809: /**
810: * @return Returns the layerListener.
811: * @uml.property name="layerListener"
812: */
813: protected LayerListener getLayerListener() {
814: return new LayerListener(this );
815: }
816:
817: protected RendererListener getRendererListener() {
818: return new RendererListener(this );
819: }
820:
821: /**
822: * @see net.refractions.udig.project.internal.render.Renderer#render(com.vividsolutions.jts.geom.Envelope)
823: */
824: public synchronized void render() {
825: // Check the visibility of all other layers...if none are visible then
826: // the
827: // last visible one was just turned off...fire off a render
828: List<IRenderer> renderers = getContext().getRenderManager()
829: .getRenderers();
830: boolean visible = false;
831: for (IRenderer renderer : renderers) {
832: if (renderer.getContext().isVisible()) {
833: visible = true;
834: break;
835: }
836: }
837: if (getState() == DISPOSED
838: || (!getRenderer().getContext().isVisible() && visible)) {
839: dirty = true;
840: getContext().getLayer().setStatus(ILayer.DONE);
841: if (getRenderer().getState() != IRenderer.DONE)
842: getRenderer().setState(IRenderer.DONE);
843: return;
844: }
845:
846: // new Exception().printStackTrace();
847:
848: dirty = false;
849: if (getRenderer().getState() != STARTING) {
850: getRenderer().setState(IRenderer.STARTING);
851: }
852: renderJob.setBounds(getRenderBounds());
853: clearImage(getRenderBounds(), this );
854: renderJob.schedule();
855: }
856:
857: /**
858: * @see net.refractions.udig.project.internal.render.impl.RendererImpl#render(com.vividsolutions.jts.geom.Envelope,
859: * org.eclipse.core.runtime.IProgressMonitor)
860: */
861: public void render(IProgressMonitor monitor) {
862: render();
863: }
864:
865: @Override
866: public String toString() {
867: String selection = ""; //$NON-NLS-1$
868: if (getContext().getLayer() instanceof SelectionLayer)
869: selection = "Selection "; //$NON-NLS-1$
870: return getContext().getMap().getName()
871: + ":" + selection + (getRenderer() != null ? getRenderer().getName() : "null"); //$NON-NLS-1$ //$NON-NLS-2$
872: }
873:
874: } // RenderExecutorImpl
|