]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.g2d/src/org/simantics/g2d/gallery/GalleryViewer.java
Add isDisposed checking to avoid unexpected NPE
[simantics/platform.git] / bundles / org.simantics.g2d / src / org / simantics / g2d / gallery / GalleryViewer.java
index 08ccf1f8769104812bd28e42f2d3ae5fec9699ab..d09ecf4a6b6f753f7f0adbf57060b3a36ac987c1 100644 (file)
@@ -103,6 +103,9 @@ import org.simantics.utils.threads.SWTThread;
 import org.simantics.utils.threads.ThreadUtils;
 import org.simantics.utils.threads.logger.ITask;
 import org.simantics.utils.threads.logger.ThreadLogger;
 import org.simantics.utils.threads.ThreadUtils;
 import org.simantics.utils.threads.logger.ITask;
 import org.simantics.utils.threads.logger.ThreadLogger;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.simantics.utils.ui.SWTDPIUtil;
 
 /**
  * @author Toni Kalajainen <toni.kalajainen@vtt.fi>
 
 /**
  * @author Toni Kalajainen <toni.kalajainen@vtt.fi>
@@ -110,6 +113,7 @@ import org.simantics.utils.threads.logger.ThreadLogger;
  */
 public class GalleryViewer extends ContentViewer {
 
  */
 public class GalleryViewer extends ContentViewer {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(GalleryViewer.class);
     /**
      * A hint key for storing a GalleryViewer within the hint stack of
      * {@link GalleryViewer}'s {@link ICanvasContext}.
     /**
      * A hint key for storing a GalleryViewer within the hint stack of
      * {@link GalleryViewer}'s {@link ICanvasContext}.
@@ -162,22 +166,24 @@ public class GalleryViewer extends ContentViewer {
         chassis = new SWTChassis(composite, style) {
             @Override
             public Point computeSize(int wHint, int hHint, boolean changed) {
         chassis = new SWTChassis(composite, style) {
             @Override
             public Point computeSize(int wHint, int hHint, boolean changed) {
-//              System.out.println("chassis compute size: " + wHint + ", " + hHint + ", " + changed);
-
                 if (diagram == null)
                     return super.computeSize(wHint, hHint, changed);
 
                 if (diagram == null)
                     return super.computeSize(wHint, hHint, changed);
 
+                // Note: This code must take into account that FlowLayout expects to 
+                // receive pixel coordinates, not SWT API coordinates.
+
                 Rectangle2D rect;
 //                if (!changed) {
 //                    rect = ElementUtils.getSurroundingElementBoundsOnDiagram(diagram.getSnapshot());
 //                }
 //                else
                 {
                 Rectangle2D rect;
 //                if (!changed) {
 //                    rect = ElementUtils.getSurroundingElementBoundsOnDiagram(diagram.getSnapshot());
 //                }
 //                else
                 {
-                    Double wH = wHint==SWT.DEFAULT ? null : (double) wHint-vMargin-vMargin;
-                    Double hH = hHint==SWT.DEFAULT ? null : (double) hHint-hMargin-hMargin;
+                    Double wH = wHint==SWT.DEFAULT ? null : (double) SWTDPIUtil.upscaleSwt(wHint)-hMargin*2;
+                    Double hH = hHint==SWT.DEFAULT ? null : (double) SWTDPIUtil.upscaleSwt(hHint)-vMargin*2;
                     rect = fl.computeSize(diagram, wH, hH);
                     rect = fl.computeSize(diagram, wH, hH);
+                    SWTDPIUtil.downscaleSwt(rect, rect);
                 }
                 }
-                return new Point((int)rect.getMaxX()+hMargin*2, (int)rect.getMaxY()+vMargin*2);
+                return new Point((int)rect.getWidth()+hMargin*2, (int)rect.getHeight()+vMargin*2);
             }
         };
 
             }
         };
 
@@ -207,12 +213,7 @@ public class GalleryViewer extends ContentViewer {
             hintCtx.setHint(DiagramHints.KEY_DIAGRAM, diagram);
 
             // Force layout
             hintCtx.setHint(DiagramHints.KEY_DIAGRAM, diagram);
 
             // Force layout
-            ThreadUtils.asyncExec(swtThread, new Runnable() {
-                @Override
-                public void run() {
-                    resized(false);
-                }
-            });
+            ThreadUtils.asyncExec(swtThread, () -> resized(false));
         });
 
         chassis.addControlListener(new ControlListener() {
         });
 
         chassis.addControlListener(new ControlListener() {
@@ -252,12 +253,9 @@ public class GalleryViewer extends ContentViewer {
                     fontRegistry.removeListener(fontRegistryListener);
 
                 // Prevent memory leaks.
                     fontRegistry.removeListener(fontRegistryListener);
 
                 // Prevent memory leaks.
-                ThreadUtils.asyncExec(ctx.getThreadAccess(), new Runnable() {
-                    @Override
-                    public void run() {
-                        chassis.getAWTComponent().setCanvasContext(null);
-                        ctx.dispose();
-                    }
+                ThreadUtils.asyncExec(ctx.getThreadAccess(), () -> {
+                    chassis.getAWTComponent().setCanvasContext(null);
+                    ctx.dispose();
                 });
             }
         });
                 });
             }
         });
@@ -271,12 +269,7 @@ public class GalleryViewer extends ContentViewer {
             currentItemFont = FontHelper.toAwt(fdn);
             itemClass.getSingleItem(GalleryItemSGNode.class).setFont(currentItemFont);
             // FIXME: a bug exists in this case. The group size will not be refreshed even though the sizes of the gallery items are recalculated and changed.
             currentItemFont = FontHelper.toAwt(fdn);
             itemClass.getSingleItem(GalleryItemSGNode.class).setFont(currentItemFont);
             // FIXME: a bug exists in this case. The group size will not be refreshed even though the sizes of the gallery items are recalculated and changed.
-            ThreadUtils.asyncExec(swtThread, new Runnable() {
-                @Override
-                public void run() {
-                    resized(true);
-                }
-            });
+            ThreadUtils.asyncExec(swtThread, () -> resized(true));
         }
     };
 
         }
     };
 
@@ -321,26 +314,25 @@ public class GalleryViewer extends ContentViewer {
         //System.out.println(this + ".resized(" + refreshElementSizes + ")");
         if (chassis.isDisposed())
             return;
         //System.out.println(this + ".resized(" + refreshElementSizes + ")");
         if (chassis.isDisposed())
             return;
-        org.eclipse.swt.graphics.Rectangle b = chassis.getBounds();
+        org.eclipse.swt.graphics.Rectangle b = SWTDPIUtil.upscaleSwt(chassis.getBounds());
+        //System.out.println("chassis bounds: " + b);
         final Rectangle2D bounds = new Rectangle2D.Double(hMargin, vMargin, b.width-hMargin*2, b.height-vMargin*2);
         final Rectangle2D bounds = new Rectangle2D.Double(hMargin, vMargin, b.width-hMargin*2, b.height-vMargin*2);
-        ctx.getThreadAccess().asyncExec(new Runnable() {
-            @Override
-            public void run() {
-                if (ctx.isDisposed())
-                    return;
-                if (diagram == null)
-                    return;
-                //System.out.println(this + ".resized(" + refreshElementSizes + ") AWT update");
-                if (refreshElementSizes)
-                    refreshElementSizes();
-                fl.layout(diagram, bounds);
-
-                // Makes sure RTreeNode is marked dirty and everything is
-                // properly repainted.
-                if (itemPainter != null)
-                    itemPainter.updateAll();
-                ctx.getContentContext().setDirty();
-            }});
+        ctx.getThreadAccess().asyncExec(() -> {
+            if (ctx.isDisposed())
+                return;
+            if (diagram == null)
+                return;
+            //System.out.println(this + ".resized(" + refreshElementSizes + ") AWT update");
+            if (refreshElementSizes)
+                refreshElementSizes();
+            fl.layout(diagram, bounds);
+
+            // Makes sure RTreeNode is marked dirty and everything is
+            // properly repainted.
+            if (itemPainter != null)
+                itemPainter.updateAll();
+            ctx.getContentContext().setDirty();
+        });
     }
 
     /**
     }
 
     /**
@@ -389,12 +381,9 @@ public class GalleryViewer extends ContentViewer {
         // wrong thread (SWT) for AWTChassis.
         chassis.getAWTComponent().setCanvasContext(canvasContext);
 
         // wrong thread (SWT) for AWTChassis.
         chassis.getAWTComponent().setCanvasContext(canvasContext);
 
-        swtThread.asyncExec(new Runnable() {
-            @Override
-            public void run() {
-                if (!chassis.isDisposed())
-                    chassis.setCanvasContext(canvasContext);
-            }
+        swtThread.asyncExec(() -> {
+            if (!chassis.isDisposed())
+                chassis.setCanvasContext(canvasContext);
         });
 
         canvasContext.assertParticipantDependencies();
         });
 
         canvasContext.assertParticipantDependencies();
@@ -570,12 +559,7 @@ public class GalleryViewer extends ContentViewer {
                 // 3. Calculate maximum vertical space needed by current diagram element texts
                 refreshElementSizes();
 
                 // 3. Calculate maximum vertical space needed by current diagram element texts
                 refreshElementSizes();
 
-                ThreadUtils.asyncExec(swtThread, new Runnable() {
-                    @Override
-                    public void run() {
-                        resized(false);
-                    }
-                });
+                ThreadUtils.asyncExec(swtThread, () -> resized(false));
                 // $AWT-Thread-End$
             }
         });
                 // $AWT-Thread-End$
             }
         });
@@ -598,7 +582,7 @@ public class GalleryViewer extends ContentViewer {
      */
     void refreshElementSizes() {
         if (awtComponent == null) {
      */
     void refreshElementSizes() {
         if (awtComponent == null) {
-            System.err.println("GalleryViewer.refreshElementSizes: awtComponent is null");
+            LOGGER.error("GalleryViewer.refreshElementSizes: awtComponent is null");
             return;
         }
 
             return;
         }
 
@@ -606,9 +590,9 @@ public class GalleryViewer extends ContentViewer {
         // Calculate maximum vertical space needed by current diagram element texts
         FontMetrics metrics = awtComponent.getFontMetrics(currentItemFont);
         int fontHeight = metrics.getHeight();
         // Calculate maximum vertical space needed by current diagram element texts
         FontMetrics metrics = awtComponent.getFontMetrics(currentItemFont);
         int fontHeight = metrics.getHeight();
-        int maxWidth = (int) itemSize.getWidth();
-        Rectangle2D size = itemSize;
-        java.awt.Point targetSize = new java.awt.Point((int) itemSize.getWidth(), (int) itemSize.getHeight());
+        Rectangle2D size = SWTDPIUtil.upscaleSwt(itemSize);
+        int maxWidth = (int) size.getWidth();
+        java.awt.Point targetSize = new java.awt.Point((int) size.getWidth(), (int) size.getHeight());
         diagram.setHint(DiagramHints.KEY_ELEMENT_RASTER_TARGET_SIZE, targetSize);
         int maxLinesNeeded = 0;
         for (IElement el : diagram.getElements()) {
         diagram.setHint(DiagramHints.KEY_ELEMENT_RASTER_TARGET_SIZE, targetSize);
         int maxLinesNeeded = 0;
         for (IElement el : diagram.getElements()) {
@@ -616,7 +600,7 @@ public class GalleryViewer extends ContentViewer {
             // for caching rendered images in the correct size only.
             // NOTE: currently this is not used in GalleryItemPainter since the
             // target size is now propagated through the element class loading
             // for caching rendered images in the correct size only.
             // NOTE: currently this is not used in GalleryItemPainter since the
             // target size is now propagated through the element class loading
-            // process through the diagram hint KEY_ELEMENT_RASTER_REFERENCE_SIZE.
+            // process through the diagram hint KEY_ELEMENT_RASTER_TARGET_SIZE.
             el.setHint(GalleryItemSGNode.KEY_TARGET_IMAGE_SIZE, targetSize);
 
             String text = ElementUtils.getText(el);
             el.setHint(GalleryItemSGNode.KEY_TARGET_IMAGE_SIZE, targetSize);
 
             String text = ElementUtils.getText(el);
@@ -644,11 +628,10 @@ public class GalleryViewer extends ContentViewer {
                 if (image != i)
                     continue;
 
                 if (image != i)
                     continue;
 
-                ctx.getThreadAccess().asyncExec(new Runnable() {
-                    @Override
-                    public void run() {
-                        //System.out.println(Thread.currentThread() + ": update scene graph(" + el + ")");
-                        // Update scene graph and repaint.
+                ctx.getThreadAccess().asyncExec(() -> {
+                    //System.out.println(Thread.currentThread() + ": update scene graph(" + el + ")");
+                    // Update scene graph and repaint.
+                    if (!ctx.isDisposed()) {
                         el.getElementClass().getSingleItem(GalleryItemSGNode.class).update(el);
                         ctx.getContentContext().setDirty();
                     }
                         el.getElementClass().getSingleItem(GalleryItemSGNode.class).update(el);
                         ctx.getContentContext().setDirty();
                     }
@@ -662,12 +645,9 @@ public class GalleryViewer extends ContentViewer {
         if (ctx.getThreadAccess().currentThreadAccess()) {
             ctx.add(p);
         } else {
         if (ctx.getThreadAccess().currentThreadAccess()) {
             ctx.add(p);
         } else {
-            ctx.getThreadAccess().asyncExec(new Runnable() {
-                @Override
-                public void run() {
-                    if (!ctx.isDisposed())
-                        ctx.add(p);
-                }
+            ctx.getThreadAccess().asyncExec(() -> {
+                if (!ctx.isDisposed())
+                    ctx.add(p);
             });
         }
     }
             });
         }
     }
@@ -676,12 +656,9 @@ public class GalleryViewer extends ContentViewer {
         if (ctx.getThreadAccess().currentThreadAccess()) {
             ctx.add(p);
         } else {
         if (ctx.getThreadAccess().currentThreadAccess()) {
             ctx.add(p);
         } else {
-            ctx.getThreadAccess().asyncExec(new Runnable() {
-                @Override
-                public void run() {
-                    if (!ctx.isDisposed())
-                        ctx.add(p);
-                }
+            ctx.getThreadAccess().asyncExec(() -> {
+                if (!ctx.isDisposed())
+                    ctx.add(p);
             });
         }
     }
             });
         }
     }
@@ -698,7 +675,7 @@ public class GalleryViewer extends ContentViewer {
 
     static class GalleryItemPainter extends ElementPainter {
         @Override
 
     static class GalleryItemPainter extends ElementPainter {
         @Override
-        public void paintSelectionFrame(G2DParentNode elementNode, G2DParentNode selectionNode, IElement e, Color color) {
+        public void paintSelectionFrame(int selectionId, G2DParentNode elementNode, G2DParentNode selectionNode, IElement e, Color color) {
             final Shape outline = ElementUtils.getElementBoundsOnDiagram(e);
             Rectangle2D bounds = outline.getBounds2D();
             GeometryUtils.expandRectangle(bounds, 2, 2, 2, 2);
             final Shape outline = ElementUtils.getElementBoundsOnDiagram(e);
             Rectangle2D bounds = outline.getBounds2D();
             GeometryUtils.expandRectangle(bounds, 2, 2, 2, 2);