Merge branch 'develop' into spike/JAL-4047/JAL-4048_columns_in_sequenceID
[jalview.git] / src / jalview / gui / AppJmol.java
index 2447a2f..950f129 100644 (file)
  */
 package jalview.gui;
 
-import java.util.Locale;
-
 import java.awt.BorderLayout;
 import java.awt.Color;
 import java.awt.Dimension;
 import java.awt.Font;
 import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
 import java.io.File;
+import java.lang.reflect.InvocationTargetException;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
 
 import javax.swing.JPanel;
 import javax.swing.JSplitPane;
@@ -43,15 +51,17 @@ import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceI;
 import jalview.datamodel.StructureViewerModel;
 import jalview.datamodel.StructureViewerModel.StructureData;
-import jalview.fts.service.alphafold.AlphafoldRestClient;
 import jalview.gui.ImageExporter.ImageWriterI;
 import jalview.gui.StructureViewer.ViewerType;
+import jalview.io.exceptions.ImageOutputException;
 import jalview.structure.StructureCommand;
 import jalview.structures.models.AAStructureBindingModel;
 import jalview.util.BrowserLauncher;
 import jalview.util.ImageMaker;
+import jalview.util.ImageMaker.TYPE;
 import jalview.util.MessageManager;
 import jalview.util.Platform;
+import jalview.util.imagemaker.BitmapImageSizing;
 
 public class AppJmol extends StructureViewerBase
 {
@@ -361,9 +371,9 @@ public class AppJmol extends StructureViewerBase
       }
       if (waitTotal > waitMax)
       {
-        System.err.println("Timed out waiting for Jmol to load files after "
+        jalview.bin.Console.errPrintln("Timed out waiting for Jmol to load files after "
                 + waitTotal + "ms");
-        // System.err.println("finished: " + jmb.isFinishedInit()
+        // jalview.bin.Console.errPrintln("finished: " + jmb.isFinishedInit()
         // + "; loaded: " + Arrays.toString(jmb.getPdbFile())
         // + "; files: " + files.toString());
         jmb.getStructureFiles();
@@ -424,21 +434,93 @@ public class AppJmol extends StructureViewerBase
   @Override
   public void makePDBImage(ImageMaker.TYPE type)
   {
+    try {
+    makePDBImage(null, type, null,
+            BitmapImageSizing.nullBitmapImageSizing());
+    } catch (ImageOutputException ioex) {
+      Console.error("Unexpected error whilst writing "+type.toString(),ioex);
+    }
+  }
+
+  public void makePDBImage(File file, ImageMaker.TYPE type, String renderer,
+          BitmapImageSizing userBis) throws ImageOutputException
+  {
     int width = getWidth();
     int height = getHeight();
+
+    BitmapImageSizing bis = ImageMaker.getScaleWidthHeight(width, height,
+            userBis);
+    float usescale = bis.scale;
+    int usewidth = bis.width;
+    int useheight = bis.height;
+
     ImageWriterI writer = new ImageWriterI()
     {
       @Override
       public void exportImage(Graphics g) throws Exception
       {
-        jmb.jmolViewer.renderScreenImage(g, width, height);
+        Graphics2D ig2 = (Graphics2D) g;
+        ig2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+                RenderingHints.VALUE_ANTIALIAS_ON);
+        if (type == TYPE.PNG && usescale > 0.0f)
+        {
+          // for a scaled image, this scales down a bigger image to give the
+          // right resolution
+          if (usescale > 0.0f)
+          {
+            ig2.scale(1 / usescale, 1 / usescale);
+          }
+        }
+
+        jmb.jmolViewer.antialiased = true;
+        jmb.jmolViewer.requestRepaintAndWait("image export");
+        jmb.jmolViewer.renderScreenImage(ig2, usewidth, useheight);
       }
     };
     String view = MessageManager.getString("action.view")
             .toLowerCase(Locale.ROOT);
-    ImageExporter exporter = new ImageExporter(writer,
+    final ImageExporter exporter = new ImageExporter(writer,
             getProgressIndicator(), type, getTitle());
-    exporter.doExport(null, this, width, height, view);
+    
+    final Throwable[] exceptions = new Throwable[1];
+    exceptions[0] = null;
+    final AppJmol us = this;
+    try
+    {
+      Thread runner = Executors.defaultThreadFactory().newThread(new Runnable()
+      {
+        @Override
+        public void run()
+        {
+          try
+          {
+            exporter.doExport(file, us, width, height, view, renderer,
+                    userBis);
+          } catch (Throwable t)
+          {
+            exceptions[0] = t;
+          }
+        }
+      });
+      runner.start();
+      do { Thread.sleep(25); } while (runner.isAlive());
+    } catch (Throwable e)
+    {
+      throw new ImageOutputException(
+              "Unexpected error when generating image", e);
+    }
+    if (exceptions[0] != null)
+    {
+      if (exceptions[0] instanceof ImageOutputException)
+      {
+        throw ((ImageOutputException) exceptions[0]);
+      }
+      else
+      {
+        throw new ImageOutputException(
+                "Unexpected error when generating image", exceptions[0]);
+      }
+    }
   }
 
   @Override
@@ -450,7 +532,7 @@ public class AppJmol extends StructureViewerBase
               .openURL("http://wiki.jmol.org");// http://jmol.sourceforge.net/docs/JmolUserGuide/");
     } catch (Exception ex)
     {
-      System.err.println("Show Jmol help failed with: " + ex.getMessage());
+      jalview.bin.Console.errPrintln("Show Jmol help failed with: " + ex.getMessage());
     }
   }