From fe8a4b9cb2b7242c902259aab79ecc0637c6c370 Mon Sep 17 00:00:00 2001 From: gmungoc Date: Fri, 20 Jul 2018 11:04:19 +0100 Subject: [PATCH] JAL-3048 JalviewJS compliant use of LineartOptions dialog --- src/jalview/gui/AlignmentPanel.java | 84 ++++++------- src/jalview/gui/LineartOptions.java | 168 ++++++++++++++------------ src/jalview/gui/TreePanel.java | 137 ++++++++++++--------- src/jalview/io/HTMLOutput.java | 109 +++++------------ src/jalview/io/HtmlSvgOutput.java | 109 ++++++++++++----- src/jalview/jbgui/GTreePanel.java | 4 +- src/jalview/util/ImageMaker.java | 223 +++++++++++++++++++++++------------ 7 files changed, 465 insertions(+), 369 deletions(-) diff --git a/src/jalview/gui/AlignmentPanel.java b/src/jalview/gui/AlignmentPanel.java index e1d4800..6e46781 100644 --- a/src/jalview/gui/AlignmentPanel.java +++ b/src/jalview/gui/AlignmentPanel.java @@ -1279,9 +1279,16 @@ public class AlignmentPanel extends GAlignmentPanel implements return idwidth.intValue() + 4; } - void makeAlignmentImage(jalview.util.ImageMaker.TYPE type, File file) + /** + * Builds an image of the alignment of the specified type (EPS/PNG/SVG) and + * writes it to the specified file + * + * @param type + * @param file + */ + void makeAlignmentImage(ImageMaker.TYPE type, File file) { - int boarderBottomOffset = 5; + int borderBottomOffset = 5; long pSessionId = System.currentTimeMillis(); headless = (System.getProperty("java.awt.headless") != null && System.getProperty("java.awt.headless").equals("true")); @@ -1297,64 +1304,39 @@ public class AlignmentPanel extends GAlignmentPanel implements try { AlignmentDimension aDimension = getAlignmentDimension(); - try + String imageAction = "Create " + type.getName() + + " image from alignment"; + String imageTitle = alignFrame.getTitle(); + + ImageMaker im = new ImageMaker(this, type, imageAction, + aDimension.getWidth(), + aDimension.getHeight() + borderBottomOffset, file, imageTitle, + alignFrame, pSessionId, headless); + Graphics graphics = im.getGraphics(); + if (graphics != null) { - ImageMaker im; - final String imageAction, imageTitle; - if (type == ImageMaker.TYPE.PNG) - { - imageAction = "Create PNG image from alignment"; - imageTitle = null; - } - else if (type == ImageMaker.TYPE.EPS) - { - imageAction = "Create EPS file from alignment"; - imageTitle = alignFrame.getTitle(); - } - else - { - imageAction = "Create SVG file from alignment"; - imageTitle = alignFrame.getTitle(); - } - - im = new ImageMaker(this, type, imageAction, aDimension.getWidth(), - aDimension.getHeight() + boarderBottomOffset, file, - imageTitle, alignFrame, pSessionId, headless); - Graphics graphics = im.getGraphics(); if (av.getWrapAlignment()) { - if (graphics != null) - { - printWrappedAlignment(aDimension.getWidth(), - aDimension.getHeight() + boarderBottomOffset, 0, - graphics); - im.writeImage(); - } + printWrappedAlignment(aDimension.getWidth(), + aDimension.getHeight() + borderBottomOffset, 0, graphics); } else { - if (graphics != null) - { - printUnwrapped(aDimension.getWidth(), aDimension.getHeight(), 0, - graphics, graphics); - im.writeImage(); - } + printUnwrapped(aDimension.getWidth(), aDimension.getHeight(), 0, + graphics, graphics); } - - } catch (OutOfMemoryError err) - { - // Be noisy here. - System.out.println("########################\n" + "OUT OF MEMORY " - + file + "\n" + "########################"); - new OOMWarning("Creating Image for " + file, err); - // System.out.println("Create IMAGE: " + err); - } catch (Exception ex) - { - ex.printStackTrace(); + im.writeImage(); } - } finally + } catch (OutOfMemoryError err) { - + // Be noisy here. + System.out.println("########################\n" + "OUT OF MEMORY " + + file + "\n" + "########################"); + new OOMWarning("Creating Image for " + file, err); + // System.out.println("Create IMAGE: " + err); + } catch (Exception ex) + { + ex.printStackTrace(); } } diff --git a/src/jalview/gui/LineartOptions.java b/src/jalview/gui/LineartOptions.java index 1fded80..1dd030b 100644 --- a/src/jalview/gui/LineartOptions.java +++ b/src/jalview/gui/LineartOptions.java @@ -22,18 +22,17 @@ package jalview.gui; import jalview.bin.Cache; import jalview.util.MessageManager; +import jalview.util.dialogrunner.RunResponse; -import java.awt.BorderLayout; +import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.util.concurrent.atomic.AtomicBoolean; import javax.swing.BorderFactory; import javax.swing.ButtonGroup; -import javax.swing.JButton; import javax.swing.JCheckBox; -import javax.swing.JDialog; import javax.swing.JLabel; -import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JRadioButton; @@ -43,7 +42,7 @@ import javax.swing.JRadioButton; */ public class LineartOptions extends JPanel { - JDialog dialog; + JvOptionPane dialog; public boolean cancelled = false; @@ -53,16 +52,31 @@ public class LineartOptions extends JPanel JCheckBox askAgainCB = new JCheckBox(); + AtomicBoolean asText; + + private String dialogTitle; + /** - * Constructor + * Constructor that passes in an initial choice of Text or Lineart, as a + * mutable boolean object. User action in the dialog should update this + * object, and the same object should be used in any action handler + * set by calling setResponseAction. * * @param preferencesKey * the key under which the choice is saved as a user preference, if * 'Don't ask me again' is selected * @param formatType + * image type e.g. EPS, SVG + * @param textOption + * true to select Text, false for Lineart */ - public LineartOptions(String preferencesKey, String formatType) + public LineartOptions(String preferencesKey, String formatType, + AtomicBoolean textOption) { + this.asText = textOption; + dialogTitle = MessageManager.formatMessage( + "label.select_character_style_title", formatType); + try { jbInit(preferencesKey, formatType); @@ -71,109 +85,110 @@ public class LineartOptions extends JPanel ex.printStackTrace(); } - JOptionPane pane = new JOptionPane(null, JvOptionPane.DEFAULT_OPTION, - JvOptionPane.DEFAULT_OPTION, null, new Object[] - { this }); + dialog = JvOptionPane.newOptionDialog(Desktop.desktop); + } - String theTitle = MessageManager.formatMessage( - "label.select_character_style_title", formatType); - dialog = pane.createDialog(Desktop.desktop, theTitle); - dialog.setVisible(true); + /** + * Registers a Runnable action to be performed for a particular user response + * in the dialog + * + * @param action + */ + public void setResponseAction(RunResponse action) + { + dialog.response(action); + } + + /** + * Shows the dialog, and performs any registered actions depending on the user + * choices + */ + public void showDialog() + { + Object[] options = new Object[] { MessageManager.getString("action.ok"), + MessageManager.getString("action.cancel") }; + dialog.showInternalDialog(this, dialogTitle, + JvOptionPane.OK_CANCEL_OPTION, JvOptionPane.PLAIN_MESSAGE, null, + options, MessageManager.getString("action.ok")); } + /** + * Initialises the panel layout + * + * @param preferencesKey + * @param formatType + * @throws Exception + */ private void jbInit(String preferencesKey, String formatType) throws Exception { + /* + * radio buttons for Text or Lineart - selection updates the value + * of field 'asText' so it is correct when used in the confirm action + */ lineartRB = new JRadioButton(MessageManager.getString("label.lineart")); lineartRB.setFont(JvSwingUtils.getLabelFont()); - JRadioButton text = new JRadioButton( - MessageManager.getString("action.text")); - text.setFont(JvSwingUtils.getLabelFont()); - text.setSelected(true); - - ButtonGroup bg = new ButtonGroup(); - bg.add(lineartRB); - bg.add(text); - - askAgainCB.setFont(JvSwingUtils.getLabelFont()); - askAgainCB.setText(MessageManager.getString("label.dont_ask_me_again")); - JButton ok = new JButton(MessageManager.getString("action.ok")); - ok.addActionListener(new ActionListener() + lineartRB.setSelected(!asText.get()); + lineartRB.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - ok_actionPerformed(preferencesKey); + asText.set(!lineartRB.isSelected()); } }); - JButton cancel = new JButton(MessageManager.getString("action.cancel")); - cancel.addActionListener(new ActionListener() + + JRadioButton textRB = new JRadioButton( + MessageManager.getString("action.text")); + textRB.setFont(JvSwingUtils.getLabelFont()); + textRB.setSelected(asText.get()); + textRB.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - cancel_actionPerformed(e); + asText.set(textRB.isSelected()); } }); - JLabel jLabel1 = new JLabel(MessageManager.formatMessage( + + ButtonGroup bg = new ButtonGroup(); + bg.add(lineartRB); + bg.add(textRB); + + askAgainCB.setFont(JvSwingUtils.getLabelFont()); + askAgainCB.setText(MessageManager.getString("label.dont_ask_me_again")); + + JLabel prompt = new JLabel(MessageManager.formatMessage( "label.select_character_rendering_style", formatType)); - jLabel1.setFont(JvSwingUtils.getLabelFont()); - - this.setLayout(new BorderLayout()); - JPanel jPanel3 = new JPanel(); - jPanel3.setBorder(BorderFactory.createEtchedBorder()); - JPanel optionsPanel = new JPanel(); - optionsPanel.add(text); - optionsPanel.add(lineartRB); - optionsPanel.add(askAgainCB); - JPanel okCancelPanel = new JPanel(); - okCancelPanel.add(ok); - okCancelPanel.add(cancel); - jPanel3.add(jLabel1); - jPanel3.add(optionsPanel); - this.add(jPanel3, BorderLayout.CENTER); - this.add(okCancelPanel, BorderLayout.SOUTH); + prompt.setFont(JvSwingUtils.getLabelFont()); + + this.setLayout(new FlowLayout(FlowLayout.LEFT)); + setBorder(BorderFactory.createEtchedBorder()); + add(prompt); + add(textRB); + add(lineartRB); + add(askAgainCB); } /** - * Action on OK is to save the selected option as the value field - * and close the dialog. If "Don't ask me again" is selected, it is also saved - * as user preference, otherwise the existing user preference (if any) is - * removed. + * If "Don't ask me again" is selected, saves the selected option as the user + * preference, otherwise removes the existing user preference (if any) is + * removed * * @param preferencesKey */ - protected void ok_actionPerformed(String preferencesKey) + protected void updatePreference(String preferencesKey) { - if (lineartRB.isSelected()) - { - value = "Lineart"; - } - else - { - value = "Text"; - } + value = lineartRB.isSelected() ? "Lineart" : "Text"; - if (!askAgainCB.isSelected()) + if (askAgainCB.isSelected()) { - Cache.applicationProperties.remove(preferencesKey); + Cache.setProperty(preferencesKey, value); } else { - Cache.setProperty(preferencesKey, value); + Cache.applicationProperties.remove(preferencesKey); } - dialog.setVisible(false); - } - - /** - * Action on Cancel is to hide the dialog - * - * @param e - */ - protected void cancel_actionPerformed(ActionEvent e) - { - cancelled = true; - dialog.setVisible(false); } /** @@ -183,6 +198,7 @@ public class LineartOptions extends JPanel */ public String getValue() { + // todo remove return value; } } diff --git a/src/jalview/gui/TreePanel.java b/src/jalview/gui/TreePanel.java index eb2397c..fefa77f 100755 --- a/src/jalview/gui/TreePanel.java +++ b/src/jalview/gui/TreePanel.java @@ -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; @@ -56,13 +57,16 @@ 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; @@ -658,77 +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"))) - { - LineartOptions eps = new LineartOptions("EPS_RENDERING", "EPS"); - 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) { - // TODO: JAL-3048 not needed for Jalview-JS - Requires EpsGraphics2D dependency - 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()); } } @@ -741,7 +733,6 @@ public class TreePanel extends GTreePanel @Override public void pngTree_actionPerformed(ActionEvent e) { - // TODO: JAL-3048 image export supported in JalviewJS ? int width = treeCanvas.getWidth(); int height = treeCanvas.getHeight(); @@ -886,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(); + } + } } diff --git a/src/jalview/io/HTMLOutput.java b/src/jalview/io/HTMLOutput.java index 3a7b441..86da67a 100644 --- a/src/jalview/io/HTMLOutput.java +++ b/src/jalview/io/HTMLOutput.java @@ -20,16 +20,14 @@ */ package jalview.io; -import jalview.api.AlignExportSettingI; -import jalview.datamodel.AlignExportSettingBeanI; +import jalview.api.AlignExportSettingsI; +import jalview.datamodel.AlignExportSettingsAdapter; import jalview.datamodel.AlignmentExportData; import jalview.exceptions.NoFileSelectedException; import jalview.gui.AlignmentPanel; import jalview.gui.IProgressIndicator; import jalview.util.MessageManager; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.File; import java.io.IOException; @@ -47,93 +45,44 @@ public abstract class HTMLOutput implements Runnable protected File generatedFile; + String _bioJson = null; + + /** + * Constructor given an alignment panel (which should not be null) + * + * @param ap + */ public HTMLOutput(AlignmentPanel ap) { - if (ap != null) - { - this.ap = ap; - this.pIndicator = ap.alignFrame; - } + this.ap = ap; + this.pIndicator = ap.alignFrame; } - String _bioJson=null; + /** + * Gets the BioJSON data as a string, with lazy evaluation (first time called + * only). If the output format is configured not to embed BioJSON, returns + * null. + * + * @return + */ public String getBioJSONData() { - if (_bioJson==null) { - getBioJSONData(null); - } - return _bioJson; - } - - public void getBioJSONData(AlignExportSettingBeanI exportSettings) - { if (!isEmbedData()) { - return; + return null; } - if (exportSettings == null) + if (_bioJson == null) { - exportSettings = new AlignExportSettingBeanI() - { - @Override - public boolean isExportHiddenSequences() - { - return true; - } - - @Override - public boolean isExportHiddenColumns() - { - return true; - } - - @Override - public boolean isExportAnnotations() - { - return true; - } - - @Override - public boolean isExportFeatures() - { - return true; - } - - @Override - public boolean isExportGroups() - { - return true; - } - - @Override - public boolean isCancelled() - { - return false; - } - - }; + AlignExportSettingsI options = new AlignExportSettingsAdapter(true); + AlignmentExportData exportData = ap.getAlignViewport() + .getAlignExportData(options); + _bioJson = new FormatAdapter(ap, options).formatSequences( + FileFormat.Json, exportData.getAlignment(), + exportData.getOmitHidden(), exportData.getStartEndPostions(), + ap.getAlignViewport().getAlignment().getHiddenColumns()); } - AlignExportSettingI exportDataSettings = jalview.gui.AlignFrame - .getAlignmentForExport(FileFormat.Json, ap, - exportSettings); - exportDataSettings.addActionListener(new ActionListener() - { - - @Override - public void actionPerformed(ActionEvent e) - { - AlignmentExportData exportData = exportDataSettings.getAlignExportData(); - _bioJson = new FormatAdapter(ap, exportData.getSettings()) - .formatSequences(FileFormat.Json, exportData.getAlignment(), - exportData.getOmitHidden(), - exportData.getStartEndPostions(), ap.getAlignViewport() - .getAlignment().getHiddenColumns()); - - } - - - }); - exportDataSettings.doShowSettings(); + + return _bioJson; } /** diff --git a/src/jalview/io/HtmlSvgOutput.java b/src/jalview/io/HtmlSvgOutput.java index a184185..30c40a9 100644 --- a/src/jalview/io/HtmlSvgOutput.java +++ b/src/jalview/io/HtmlSvgOutput.java @@ -20,18 +20,23 @@ */ package jalview.io; +import jalview.bin.Cache; import jalview.exceptions.NoFileSelectedException; import jalview.gui.AlignmentPanel; import jalview.gui.LineartOptions; import jalview.gui.OOMWarning; import jalview.math.AlignmentDimension; import jalview.util.MessageManager; +import jalview.util.dialogrunner.RunResponse; import java.awt.Graphics; import java.awt.print.PrinterException; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import java.util.concurrent.atomic.AtomicBoolean; + +import javax.swing.JOptionPane; import org.jfree.graphics2d.svg.SVGGraphics2D; import org.jfree.graphics2d.svg.SVGHints; @@ -84,7 +89,7 @@ public class HtmlSvgOutput extends HTMLOutput return ap.printWrappedAlignment(pwidth, pheight, pi, pg[0]); } - private String getHtml(String titleSvg, String alignmentSvg, + String getHtml(String titleSvg, String alignmentSvg, String jsonData, boolean wrapped) { StringBuilder htmlSvg = new StringBuilder(); @@ -238,36 +243,87 @@ public class HtmlSvgOutput extends HTMLOutput setProgressMessage(null); setProgressMessage(MessageManager.formatMessage( "status.exporting_alignment_as_x_file", "HTML")); - AlignmentDimension aDimension = ap.getAlignmentDimension(); - SVGGraphics2D idPanelGraphics = new SVGGraphics2D( - aDimension.getWidth(), aDimension.getHeight()); - SVGGraphics2D alignPanelGraphics = new SVGGraphics2D( - aDimension.getWidth(), aDimension.getHeight()); - String renderStyle = jalview.bin.Cache.getDefault("HTML_RENDERING", + String renderStyle = Cache.getDefault("HTML_RENDERING", "Prompt each time"); + AtomicBoolean textOption = new AtomicBoolean( + !"Lineart".equals(renderStyle)); + + /* + * configure the action to run on OK in the dialog + */ + RunResponse okAction = new RunResponse(JOptionPane.OK_OPTION) + { + @Override + public void run() + { + doOutput(textOption.get()); + } + }; - // If we need to prompt, and if the GUI is visible then - // Prompt for rendering style + /* + * Prompt for character rendering style if preference is not set + */ if (renderStyle.equalsIgnoreCase("Prompt each time") && !isHeadless()) { LineartOptions svgOption = new LineartOptions("HTML_RENDERING", - "HTML"); - renderStyle = svgOption.getValue(); - - if (renderStyle == null || svgOption.cancelled) + "HTML", textOption); + svgOption.setResponseAction(new RunResponse(JOptionPane.NO_OPTION) { - setProgressMessage(MessageManager.formatMessage( - "status.cancelled_image_export_operation", "HTML")); - return; - } + @Override + public void run() + { + setProgressMessage(MessageManager.formatMessage( + "status.cancelled_image_export_operation", "HTML")); + } + }); + svgOption.setResponseAction(okAction); + svgOption.showDialog(); + /* no code here - JalviewJS cannot execute it */ + } + else + { + /* + * else (if preference set) just do the export action + */ + doOutput(textOption.get()); } + } catch (OutOfMemoryError err) + { + System.out.println("########################\n" + "OUT OF MEMORY " + + generatedFile + "\n" + "########################"); + new OOMWarning("Creating Image for " + generatedFile, err); + } catch (Exception e) + { + e.printStackTrace(); + setProgressMessage(MessageManager + .formatMessage("info.error_creating_file", "HTML")); + } + } - if (renderStyle.equalsIgnoreCase("Lineart")) + /** + * Builds and writes the image to the file specified by field + * generatedFile + * + * @param textCharacters + * true for Text character rendering, false for Lineart + */ + protected void doOutput(boolean textCharacters) + { + try + { + AlignmentDimension aDimension = ap.getAlignmentDimension(); + SVGGraphics2D idPanelGraphics = new SVGGraphics2D( + aDimension.getWidth(), aDimension.getHeight()); + SVGGraphics2D alignPanelGraphics = new SVGGraphics2D( + aDimension.getWidth(), aDimension.getHeight()); + if (!textCharacters) // Lineart selected { - idPanelGraphics.setRenderingHint(SVGHints.KEY_DRAW_STRING_TYPE, + idPanelGraphics.setRenderingHint( + SVGHints.KEY_DRAW_STRING_TYPE, SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR); - alignPanelGraphics.setRenderingHint(SVGHints.KEY_DRAW_STRING_TYPE, + alignPanelGraphics.setRenderingHint( + SVGHints.KEY_DRAW_STRING_TYPE, SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR); } if (ap.av.getWrapAlignment()) @@ -277,15 +333,15 @@ public class HtmlSvgOutput extends HTMLOutput } else { - printUnwrapped(aDimension.getWidth(), aDimension.getHeight(), 0, - idPanelGraphics, alignPanelGraphics); + printUnwrapped(aDimension.getWidth(), aDimension.getHeight(), + 0, idPanelGraphics, alignPanelGraphics); } String idPanelSvgData = idPanelGraphics.getSVGDocument(); String alignPanelSvgData = alignPanelGraphics.getSVGDocument(); String jsonData = getBioJSONData(); - String htmlData = getHtml(idPanelSvgData, alignPanelSvgData, jsonData, - ap.av.getWrapAlignment()); + String htmlData = getHtml(idPanelSvgData, alignPanelSvgData, + jsonData, ap.av.getWrapAlignment()); FileOutputStream out = new FileOutputStream(generatedFile); out.write(htmlData.getBytes()); out.flush(); @@ -293,11 +349,6 @@ public class HtmlSvgOutput extends HTMLOutput setProgressMessage(MessageManager .formatMessage("status.export_complete", "HTML")); exportCompleted(); - } catch (OutOfMemoryError err) - { - System.out.println("########################\n" + "OUT OF MEMORY " - + generatedFile + "\n" + "########################"); - new OOMWarning("Creating Image for " + generatedFile, err); } catch (Exception e) { e.printStackTrace(); diff --git a/src/jalview/jbgui/GTreePanel.java b/src/jalview/jbgui/GTreePanel.java index c506fc6..916a98f 100755 --- a/src/jalview/jbgui/GTreePanel.java +++ b/src/jalview/jbgui/GTreePanel.java @@ -175,7 +175,7 @@ public class GTreePanel extends JInternalFrame { public void actionPerformed(ActionEvent e) { - epsTree_actionPerformed(e); + epsTree_actionPerformed(); } }); pngTree.setText("PNG"); @@ -259,7 +259,7 @@ public class GTreePanel extends JInternalFrame { } - public void epsTree_actionPerformed(ActionEvent e) + public void epsTree_actionPerformed() { } diff --git a/src/jalview/util/ImageMaker.java b/src/jalview/util/ImageMaker.java index 493e210..64771c4 100755 --- a/src/jalview/util/ImageMaker.java +++ b/src/jalview/util/ImageMaker.java @@ -25,6 +25,7 @@ import jalview.bin.Jalview; import jalview.gui.IProgressIndicator; import jalview.gui.LineartOptions; import jalview.io.JalviewFileChooser; +import jalview.util.dialogrunner.RunResponse; import java.awt.Component; import java.awt.Graphics; @@ -33,8 +34,10 @@ import java.awt.RenderingHints; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileOutputStream; +import java.util.concurrent.atomic.AtomicBoolean; import javax.imageio.ImageIO; +import javax.swing.JOptionPane; import org.jfree.graphics2d.svg.SVGGraphics2D; import org.jfree.graphics2d.svg.SVGHints; @@ -60,8 +63,6 @@ public class ImageMaker EpsGraphics2D pg; - SVGGraphics2D g2; - Graphics graphics; FileOutputStream out; @@ -105,7 +106,7 @@ public class ImageMaker return name; } - public JalviewFileChooser getChooser() + public JalviewFileChooser getFileChooser() { return new JalviewFileChooser(extension, description); } @@ -144,8 +145,7 @@ public class ImageMaker { setProgressMessage(MessageManager.formatMessage( "status.waiting_for_user_to_select_output_file", type.name)); - JalviewFileChooser chooser; - chooser = type.getChooser(); + JalviewFileChooser chooser = type.getFileChooser(); chooser.setFileView(new jalview.io.JalviewFileView()); chooser.setDialogTitle(title); chooser.setToolTipText(MessageManager.getString("action.save")); @@ -163,7 +163,7 @@ public class ImageMaker "status.cancelled_image_export_operation", type.name)); } } - // TODO JAL-3048 refactor to method called by constructor or callback + if (file != null) { try @@ -200,6 +200,11 @@ public class ImageMaker return graphics; } + /** + * For SVG or PNG, writes the generated graphics data to the file output + * stream. For EPS, flushes the output graphics (which is written to file as + * it is generated). + */ public void writeImage() { try @@ -228,53 +233,71 @@ public class ImageMaker } } + /** + * Generates an EPS image and writes it to the (previously set) output buffer. + * The user is first prompted for choice of Text or Lineart rendering, unless + * a preference for this has been set. + * + * @param width + * @param height + * @param title + */ void setupEPS(int width, int height, String title) { - boolean accurateText = true; - String renderStyle = Cache.getDefault("EPS_RENDERING", "Prompt each time"); + AtomicBoolean textOption = new AtomicBoolean( + !"Lineart".equals(renderStyle)); - // 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"))) + /* + * configure the action to run on OK in the dialog + */ + RunResponse okAction = new RunResponse(JOptionPane.OK_OPTION) { - LineartOptions eps = new LineartOptions("EPS_RENDERING", "EPS"); - renderStyle = eps.getValue(); - - if (renderStyle == null || eps.cancelled) + @Override + public void run() { - setProgressMessage(MessageManager.formatMessage( - "status.cancelled_image_export_operation", "EPS")); - return; + writeEPS(width, height, title, textOption.get()); } - } + }; - if (renderStyle.equalsIgnoreCase("text")) + /* + * 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"))) { - accurateText = false; + LineartOptions epsOption = new LineartOptions("EPS_RENDERING", + TYPE.EPS.getName(), textOption); + epsOption.setResponseAction(new RunResponse(JOptionPane.NO_OPTION) + { + @Override + public void run() + { + setProgressMessage(MessageManager.formatMessage( + "status.cancelled_image_export_operation", "EPS")); + } + }); + epsOption.setResponseAction(okAction); + epsOption.showDialog(); + /* no code here - JalviewJS cannot execute it */ } - - try + else { - pg = new EpsGraphics2D(title, out, 0, 0, width, height); - Graphics2D ig2 = pg; - ig2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, - RenderingHints.VALUE_ANTIALIAS_ON); - - pg.setAccurateTextMode(accurateText); - - graphics = pg; - setProgressMessage(MessageManager - .formatMessage("status.export_complete", type.getName())); - } catch (Exception ex) - { - System.err.println("Error writing PNG: " + ex.toString()); + /* + * else (if preference set) just do the export action + */ + writeEPS(width, height, title, textOption.get()); } } + /** + * Sets up a graphics object for the PNG image to be written on + * + * @param width + * @param height + */ void setupPNG(int width, int height) { bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); @@ -284,69 +307,123 @@ public class ImageMaker RenderingHints.VALUE_ANTIALIAS_ON); setProgressMessage(MessageManager .formatMessage("status.export_complete", type.getName())); - } + /** + * Sets up a graphics object for the SVG image to be written on. The user is + * first prompted for choice of Text or Lineart rendering, unless a preference + * for this has been set. + * + * @param width + * @param height + * @param title + */ void setupSVG(int width, int height, String title) { - - g2 = new SVGGraphics2D(width, height); - Graphics2D ig2 = g2; - - String renderStyle = jalview.bin.Cache.getDefault("SVG_RENDERING", + String renderStyle = Cache.getDefault("SVG_RENDERING", "Prompt each time"); + AtomicBoolean textOption = new AtomicBoolean( + !"Lineart".equals(renderStyle)); - // If we need to prompt, and if the GUI is visible then - // Prompt for EPS rendering style + /* + * configure the action to run on OK in the dialog + */ + RunResponse okAction = new RunResponse(JOptionPane.OK_OPTION) + { + @Override + public void run() + { + setupSVG(width, height, textOption.get()); + } + }; + + /* + * 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"))) { - LineartOptions svgOption = new LineartOptions("SVG_RENDERING", "SVG"); - renderStyle = svgOption.getValue(); - - if (renderStyle == null || svgOption.cancelled) + LineartOptions svgOption = new LineartOptions("SVG_RENDERING", + TYPE.SVG.getName(), textOption); + svgOption.setResponseAction(new RunResponse(JOptionPane.NO_OPTION) { - setProgressMessage(MessageManager.formatMessage( - "status.cancelled_image_export_operation", "SVG")); - return; - } + @Override + public void run() + { + setProgressMessage(MessageManager.formatMessage( + "status.cancelled_image_export_operation", "SVG")); + } + }); + svgOption.setResponseAction(okAction); + svgOption.showDialog(); + /* no code here - JalviewJS cannot execute it */ } - - if (renderStyle.equalsIgnoreCase("Lineart")) + else { - ig2.setRenderingHint(SVGHints.KEY_DRAW_STRING_TYPE, - SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR); + /* + * else (if preference set) just do the export action + */ + setupSVG(width, height, textOption.get()); } - - setProgressMessage(MessageManager - .formatMessage("status.export_complete", type.getName())); - graphics = g2; } - static JalviewFileChooser getPNGChooser() + void setProgressMessage(String message) { - if (Jalview.isHeadlessMode()) + if (pIndicator != null && !headless) { - return null; + pIndicator.setProgressBar(message, pSessionId); } - return new JalviewFileChooser(PNG_EXTENSION, PNG_DESCRIPTION); } - static JalviewFileChooser getEPSChooser() + /** + * A helper method to configure the SVG output graphics, with choice of Text + * or Lineart character rendering + * + * @param width + * @param height + * @param textOption + * true for Text, false for Lineart + */ + protected void setupSVG(int width, int height, boolean textOption) { - if (Jalview.isHeadlessMode()) + SVGGraphics2D g2 = new SVGGraphics2D(width, height); + if (!textOption) // Lineart selected { - return null; + g2.setRenderingHint(SVGHints.KEY_DRAW_STRING_TYPE, + SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR); } - return new JalviewFileChooser(EPS_EXTENSION, EPS_DESCRIPTION); + setProgressMessage(MessageManager + .formatMessage("status.export_complete", type.getName())); + graphics = g2; } - private void setProgressMessage(String message) + /** + * A helper method that sets up the EPS graphics output with user choice of + * Text or Lineart character rendering + * + * @param width + * @param height + * @param title + * @param textOption + * true for Text, false for Lineart + */ + protected void writeEPS(int width, int height, String title, + boolean textOption) { - if (pIndicator != null && !headless) + try { - pIndicator.setProgressBar(message, pSessionId); + pg = new EpsGraphics2D(title, out, 0, 0, width, height); + Graphics2D ig2 = pg; + ig2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + pg.setAccurateTextMode(!textOption); // true = Lineart + graphics = pg; + setProgressMessage(MessageManager + .formatMessage("status.export_complete", type.getName())); + } catch (Exception ex) + { + System.err.println("Error writing PNG: " + ex.toString()); } } -- 1.7.10.2