JAL-3048 JalviewJS compliant use of LineartOptions dialog
[jalview.git] / src / jalview / gui / TreePanel.java
index 5e14fce..fefa77f 100755 (executable)
@@ -47,6 +47,7 @@ import jalview.io.NewickFile;
 import jalview.jbgui.GTreePanel;
 import jalview.util.ImageMaker;
 import jalview.util.MessageManager;
+import jalview.util.dialogrunner.RunResponse;
 import jalview.viewmodel.AlignmentViewport;
 
 import java.awt.Font;
@@ -55,14 +56,20 @@ import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.image.BufferedImage;
 import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.File;
 import java.io.FileOutputStream;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import javax.imageio.ImageIO;
 import javax.swing.ButtonGroup;
 import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
 import javax.swing.JRadioButtonMenuItem;
+import javax.swing.event.InternalFrameAdapter;
+import javax.swing.event.InternalFrameEvent;
 
 import org.jibble.epsgraphics.EpsGraphics2D;
 
@@ -141,7 +148,35 @@ public class TreePanel extends GTreePanel
 
     buildAssociatedViewMenu();
 
-    av.addPropertyChangeListener(new java.beans.PropertyChangeListener()
+    final PropertyChangeListener listener = addAlignmentListener();
+
+    /*
+     * remove listener when window is closed, so that this
+     * panel can be garbage collected
+     */
+    addInternalFrameListener(new InternalFrameAdapter()
+    {
+      @Override
+      public void internalFrameClosed(InternalFrameEvent evt)
+      {
+        if (av != null)
+        {
+          av.removePropertyChangeListener(listener);
+        }
+      }
+    });
+
+    TreeLoader tl = new TreeLoader(newTree, inputData);
+    tl.start();
+
+  }
+
+  /**
+   * @return
+   */
+  protected PropertyChangeListener addAlignmentListener()
+  {
+    final PropertyChangeListener listener = new PropertyChangeListener()
     {
       @Override
       public void propertyChange(PropertyChangeEvent evt)
@@ -168,11 +203,9 @@ public class TreePanel extends GTreePanel
           repaint();
         }
       }
-    });
-
-    TreeLoader tl = new TreeLoader(newTree, inputData);
-    tl.start();
-
+    };
+    av.addPropertyChangeListener(listener);
+    return listener;
   }
 
   @Override
@@ -361,6 +394,7 @@ public class TreePanel extends GTreePanel
   @Override
   public void saveAsNewick_actionPerformed(ActionEvent e)
   {
+    // TODO: JAL-3048 save newick file for Jalview-JS
     JalviewFileChooser chooser = new JalviewFileChooser(
             jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
     chooser.setFileView(new JalviewFileView());
@@ -493,7 +527,7 @@ public class TreePanel extends GTreePanel
 
     if (treeCanvas.applyToAllViews)
     {
-      final ArrayList<CommandI> commands = new ArrayList<CommandI>();
+      final ArrayList<CommandI> commands = new ArrayList<>();
       for (AlignmentPanel ap : PaintRefresher
               .getAssociatedPanels(av.getSequenceSetId()))
       {
@@ -550,13 +584,14 @@ public class TreePanel extends GTreePanel
 
   public CommandI sortAlignmentIn(AlignmentPanel ap)
   {
+    // TODO: move to alignment view controller
     AlignmentViewport viewport = ap.av;
     SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
     AlignmentSorter.sortByTree(viewport.getAlignment(), tree);
     CommandI undo;
     undo = new OrderCommand("Tree Sort", oldOrder, viewport.getAlignment());
 
-    ap.paintAlignment(true);
+    ap.paintAlignment(true, false);
     return undo;
   }
 
@@ -627,76 +662,65 @@ public class TreePanel extends GTreePanel
   }
 
   /**
-   * DOCUMENT ME!
-   * 
-   * @param e
-   *          DOCUMENT ME!
+   * Outputs the Tree in EPS format. The user is prompted for the file to save
+   * to, and (unless a preference is already set) for the choice of Text or
+   * Lineart for character rendering.
    */
   @Override
-  public void epsTree_actionPerformed(ActionEvent e)
+  public void epsTree_actionPerformed()
   {
-    boolean accurateText = true;
-
-    String renderStyle = jalview.bin.Cache.getDefault("EPS_RENDERING",
-            "Prompt each time");
-
-    // If we need to prompt, and if the GUI is visible then
-    // Prompt for EPS rendering style
-    if (renderStyle.equalsIgnoreCase("Prompt each time")
-            && !(System.getProperty("java.awt.headless") != null && System
-                    .getProperty("java.awt.headless").equals("true")))
-    {
-      EPSOptions eps = new EPSOptions();
-      renderStyle = eps.getValue();
-
-      if (renderStyle == null || eps.cancelled)
-      {
-        return;
-      }
+    JalviewFileChooser chooser = new JalviewFileChooser(
+            ImageMaker.EPS_EXTENSION, ImageMaker.EPS_EXTENSION);
+    chooser.setFileView(new JalviewFileView());
+    chooser.setDialogTitle(
+            MessageManager.getString("label.create_eps_from_tree"));
+    chooser.setToolTipText(MessageManager.getString("action.save"));
 
-    }
+    int value = chooser.showSaveDialog(this);
 
-    if (renderStyle.equalsIgnoreCase("text"))
+    if (value != JalviewFileChooser.APPROVE_OPTION)
     {
-      accurateText = false;
+      return;
     }
+    File outFile = chooser.getSelectedFile();
+    Cache.setProperty("LAST_DIRECTORY", outFile.getParent());
 
-    int width = treeCanvas.getWidth();
-    int height = treeCanvas.getHeight();
+    String renderStyle = Cache.getDefault("EPS_RENDERING",
+            "Prompt each time");
+    AtomicBoolean textOption = new AtomicBoolean(
+            !"Lineart".equals(renderStyle));
 
-    try
+    /*
+     * configure the export action to run on OK in the dialog
+     */
+    RunResponse okAction = new RunResponse(JOptionPane.OK_OPTION)
     {
-      JalviewFileChooser chooser = new JalviewFileChooser(
-              ImageMaker.EPS_EXTENSION, ImageMaker.EPS_EXTENSION);
-      chooser.setFileView(new JalviewFileView());
-      chooser.setDialogTitle(
-              MessageManager.getString("label.create_eps_from_tree"));
-      chooser.setToolTipText(MessageManager.getString("action.save"));
-
-      int value = chooser.showSaveDialog(this);
-
-      if (value != JalviewFileChooser.APPROVE_OPTION)
+      @Override
+      public void run()
       {
-        return;
+        writeEpsFile(outFile, textOption.get());
       }
+    };
 
-      Cache.setProperty("LAST_DIRECTORY",
-              chooser.getSelectedFile().getParent());
-
-      FileOutputStream out = new FileOutputStream(
-              chooser.getSelectedFile());
-      EpsGraphics2D pg = new EpsGraphics2D("Tree", out, 0, 0, width,
-              height);
-
-      pg.setAccurateTextMode(accurateText);
-
-      treeCanvas.draw(pg, width, height);
-
-      pg.flush();
-      pg.close();
-    } catch (Exception ex)
+    /*
+     * Prompt for character rendering style if preference is not set
+     */
+    if (renderStyle.equalsIgnoreCase("Prompt each time")
+            && !(System.getProperty("java.awt.headless") != null && System
+                    .getProperty("java.awt.headless").equals("true")))
     {
-      ex.printStackTrace();
+      LineartOptions eps = new LineartOptions("EPS_RENDERING", "EPS",
+              textOption);
+      eps.setResponseAction(okAction);
+      eps.showDialog();
+      /* no code here - JalviewJS won't execute it */
+    }
+    else
+    {
+      /*
+       * if preference set, just run the export action
+       */
+      writeEpsFile(outFile, textOption.get());
     }
   }
 
@@ -853,4 +877,34 @@ public class TreePanel extends GTreePanel
             treecalcnm, smn);
     return ttl;
   }
+
+  /**
+   * Builds an EPS image and writes it to the specified file.
+   * 
+   * @param outFile
+   * @param textOption
+   *          true for Text character rendering, false for Lineart
+   */
+  protected void writeEpsFile(File outFile, boolean textOption)
+  {
+    try
+    {
+      int width = treeCanvas.getWidth();
+      int height = treeCanvas.getHeight();
+
+      FileOutputStream out = new FileOutputStream(
+              outFile);
+      EpsGraphics2D pg = new EpsGraphics2D("Tree", out, 0, 0, width,
+              height);
+      pg.setAccurateTextMode(!textOption);
+      treeCanvas.draw(pg, width, height);
+
+      pg.flush();
+      pg.close();
+    } catch (Exception ex)
+    {
+      System.err.println("Error writing tree as EPS");
+      ex.printStackTrace();
+    }
+  }
 }