From 5969ead0fd401f4435a3435ede9e4e87cf9c1d0b Mon Sep 17 00:00:00 2001 From: hansonr Date: Wed, 27 Jun 2018 11:20:25 +0100 Subject: [PATCH] JAL-3032 part2 local file reading by JFileChooser This commit adds the ALignFrame changes for handling the JalviewFileChooser callback. --- src/jalview/gui/AlignFrame.java | 43 +++++++++++--- src/jalview/gui/Desktop.java | 96 +++++++++++++++++++------------ src/jalview/io/AppletFormatAdapter.java | 17 +++++- src/jalview/io/FileLoader.java | 21 ++++++- src/jalview/io/FileParse.java | 36 +++++++++++- src/jalview/io/FormatAdapter.java | 8 +++ src/jalview/io/IdentifyFile.java | 27 +++++++++ src/jalview/io/JalviewFileChooser.java | 38 ++++++++++-- 8 files changed, 232 insertions(+), 54 deletions(-) diff --git a/src/jalview/gui/AlignFrame.java b/src/jalview/gui/AlignFrame.java index a2b1e47..26c5548 100644 --- a/src/jalview/gui/AlignFrame.java +++ b/src/jalview/gui/AlignFrame.java @@ -122,6 +122,7 @@ import java.awt.event.MouseEvent; import java.awt.print.PageFormat; import java.awt.print.PrinterJob; import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; import java.io.File; import java.io.FileWriter; import java.io.PrintWriter; @@ -136,6 +137,7 @@ import java.util.Vector; import javax.swing.JCheckBoxMenuItem; import javax.swing.JEditorPane; +import javax.swing.JFileChooser; import javax.swing.JInternalFrame; import javax.swing.JLayeredPane; import javax.swing.JMenu; @@ -150,7 +152,8 @@ import javax.swing.SwingUtilities; * @version $Revision$ */ public class AlignFrame extends GAlignFrame implements DropTargetListener, - IProgressIndicator, AlignViewControllerGuiI, ColourChangeListener + IProgressIndicator, AlignViewControllerGuiI, ColourChangeListener, + PropertyChangeListener { public static final int DEFAULT_WIDTH = 700; @@ -324,6 +327,12 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, init(); } + @Override + public void propertyChange(PropertyChangeEvent evt) + { + Desktop.getDesktop().propertyChange(evt); + } + /** * initalise the alignframe from the underlying viewport data and the * configurations @@ -1121,6 +1130,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, int value = chooser.showSaveDialog(this); + if (value == JalviewFileChooser.APPROVE_OPTION) { currentFileFormat = chooser.getSelectedFormat(); @@ -1421,14 +1431,30 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, chooser.setToolTipText( MessageManager.getString("label.load_jalview_annotations")); - int value = chooser.showOpenDialog(null); + Desktop.getDesktop().dialogData = new Object[] { "SelectedFile", + new Runnable() + { + + @Override + public void run() + { + Object[] data = Desktop.getDesktop().dialogData; + int value = ((Integer) data[0]).intValue(); + + if (value == JFileChooser.APPROVE_OPTION) + { + JalviewFileChooser chooser = (JalviewFileChooser) data[2]; + String choice = chooser.getSelectedFile().getPath(); + jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice); + loadJalviewDataFile(choice, null, null, null); + } + } + + }, chooser }; + + chooser.showOpenDialog(null); + - if (value == JalviewFileChooser.APPROVE_OPTION) - { - String choice = chooser.getSelectedFile().getPath(); - jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice); - loadJalviewDataFile(choice, null, null, null); - } } @@ -5618,6 +5644,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } } + } class PrintThread extends Thread diff --git a/src/jalview/gui/Desktop.java b/src/jalview/gui/Desktop.java index bc5db70..e82bd9c 100644 --- a/src/jalview/gui/Desktop.java +++ b/src/jalview/gui/Desktop.java @@ -105,6 +105,7 @@ import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JDesktopPane; +import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JInternalFrame; import javax.swing.JLabel; @@ -193,6 +194,13 @@ public class Desktop extends jalview.jbgui.GDesktop public static MyDesktopPane desktop; + public static MyDesktopPane getDesktop() + { + // BH 2018 could use currentThread() here as a reference to a + // Hashtable in JavaScript + return desktop; + } + static int openFrameCount = 0; static final int xOffset = 30; @@ -1110,7 +1118,7 @@ public class Desktop extends jalview.jbgui.GDesktop public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport) { String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT"); - JalviewFileChooser chooser = JalviewFileChooser + final JalviewFileChooser chooser = JalviewFileChooser .forRead(Cache.getProperty("LAST_DIRECTORY"), fileFormat); chooser.setFileView(new JalviewFileView()); @@ -1118,42 +1126,45 @@ public class Desktop extends jalview.jbgui.GDesktop MessageManager.getString("label.open_local_file")); chooser.setToolTipText(MessageManager.getString("action.open")); - int value = chooser.showOpenDialog(this); - - if (value == JalviewFileChooser.APPROVE_OPTION) + chooser.setCallback(new Runnable() { - String choice = chooser.getSelectedFile().getPath(); - Cache.setProperty("LAST_DIRECTORY", - chooser.getSelectedFile().getParent()); - - FileFormatI format = chooser.getSelectedFormat(); - /* - * Call IdentifyFile to verify the file contains what its extension implies. - * Skip this step for dynamically added file formats, because - * IdentifyFile does not know how to recognise them. - */ - if (FileFormats.getInstance().isIdentifiable(format)) + @Override + public void run() { - try - { - format = new IdentifyFile().identify(choice, DataSourceType.FILE); - } catch (FileFormatException e) + File selectedFile = chooser.getSelectedFile(); + Cache.setProperty("LAST_DIRECTORY", selectedFile.getParent()); + + FileFormatI format = chooser.getSelectedFormat(); + + /* + * Call IdentifyFile to verify the file contains what its extension implies. + * Skip this step for dynamically added file formats, because + * IdentifyFile does not know how to recognise them. + */ + if (FileFormats.getInstance().isIdentifiable(format)) { - // format = null; //?? + try + { + format = new IdentifyFile().identify(selectedFile, + DataSourceType.FILE); + } catch (FileFormatException e) + { + // format = null; //?? + } } - } - if (viewport != null) - { - new FileLoader().LoadFile(viewport, choice, DataSourceType.FILE, - format); - } - else - { - new FileLoader().LoadFile(choice, DataSourceType.FILE, format); + new FileLoader().LoadFile(viewport, selectedFile, + DataSourceType.FILE, format); } + }); + + int value = chooser.showOpenDialog(this); + if (value == JFileChooser.APPROVE_OPTION) + { + chooser.getCallback().run(); } + } /** @@ -2480,12 +2491,9 @@ public class Desktop extends jalview.jbgui.GDesktop switch (name) { case "SelectedFile": - File file = (File) val; - byte[] array = (val == null ? null - : /** @j2sNative file._bytes || */ - null); - onDialogReturn("fileName is '" + file.getName() + "'\n\n" - + new String(array)); + // in JavaScript, this File object will have a _bytes property, + // because the file data has already been loaded + onDialogReturn(new Object[] { (File) val }); return; } break; @@ -2495,9 +2503,19 @@ public class Desktop extends jalview.jbgui.GDesktop } // JSCOmponent.DialogCaller interface - private void onDialogReturn(Object value) + void onDialogReturn(Object value) { - System.out.println("not implemented"); + switch ((String) dialogData[0]) + { + case "SelectedFile": + case "runnable": + dialogData[0] = value; + ((Runnable) dialogData[1]).run(); + break; + case "label.select_feature_colour": + ((FeatureRenderer) dialogData[1]).processColorDialog((Color) value); + break; + } } // JSCOmponent.DialogCaller interface @@ -2511,6 +2529,10 @@ public class Desktop extends jalview.jbgui.GDesktop switch ((String) dialogData[0]) { + case "runnable": + dialogData[0] = Integer.valueOf(value); + ((Runnable) dialogData[1]).run(); + break; case "label.input_alignment_from_url": // reconstruct the parameter data int reply = value; diff --git a/src/jalview/io/AppletFormatAdapter.java b/src/jalview/io/AppletFormatAdapter.java index 3f51ea8..bc2465a 100755 --- a/src/jalview/io/AppletFormatAdapter.java +++ b/src/jalview/io/AppletFormatAdapter.java @@ -75,6 +75,8 @@ public class AppletFormatAdapter private AlignExportSettingI exportSettings; + private File selectedFile; + public static String INVALID_CHARACTERS = "Contains invalid characters"; /** @@ -147,6 +149,16 @@ public class AppletFormatAdapter public AlignmentI readFile(String file, DataSourceType sourceType, FileFormatI fileFormat) throws IOException { + return readFile(null, file, sourceType, fileFormat); + } + + public AlignmentI readFile(File selectedFile, String file, DataSourceType sourceType, + FileFormatI fileFormat) throws IOException + { + + this.selectedFile = selectedFile; + if (selectedFile != null) + this.inFile = selectedFile.getPath(); this.inFile = file; try { @@ -161,6 +173,7 @@ public class AppletFormatAdapter localSecondaryStruct, serviceSecondaryStruct); if (isParseWithJMOL) { + // needs a File option alignFile = new JmolParser(inFile, sourceType); } else @@ -174,7 +187,9 @@ public class AppletFormatAdapter ((StructureFile) alignFile).setDbRefType( FileFormat.PDB.equals(fileFormat) ? Type.PDB : Type.MMCIF); } - else + else if (selectedFile != null) { + alignFile = fileFormat.getReader(new FileParse(selectedFile, sourceType)); + } else { // alignFile = fileFormat.getAlignmentFile(inFile, sourceType); alignFile = fileFormat.getReader(new FileParse(inFile, sourceType)); diff --git a/src/jalview/io/FileLoader.java b/src/jalview/io/FileLoader.java index 9dd740b..74c82eb 100755 --- a/src/jalview/io/FileLoader.java +++ b/src/jalview/io/FileLoader.java @@ -71,6 +71,8 @@ public class FileLoader implements Runnable boolean raiseGUI = true; + private File selectedFile; + /** * default constructor always raised errors in GUI dialog boxes */ @@ -97,6 +99,14 @@ public class FileLoader implements Runnable LoadFile(file, protocol, format); } + public void LoadFile(AlignViewport viewport, File selectedFile, + DataSourceType protocol, FileFormatI format) + { + this.viewport = viewport; + this.selectedFile = selectedFile; + LoadFile(selectedFile.getPath(), protocol, format); + } + public void LoadFile(String file, DataSourceType protocol, FileFormatI format) { @@ -260,6 +270,9 @@ public class FileLoader implements Runnable format = new IdentifyFile().identify(source, false); // identify stream and rewind rather than close } + else if (selectedFile != null) { + format = new IdentifyFile().identify(selectedFile, protocol); + } else { format = new IdentifyFile().identify(file, protocol); @@ -340,8 +353,14 @@ public class FileLoader implements Runnable } else { - al = fa.readFile(file, protocol, format); + if (selectedFile == null) { + al = fa.readFile(file, protocol, format); + + } else { + al = fa.readFile(selectedFile, protocol, format); + } source = fa.getAlignFile(); // keep reference for later if + // necessary. } } diff --git a/src/jalview/io/FileParse.java b/src/jalview/io/FileParse.java index bf0a844..7e1940f 100755 --- a/src/jalview/io/FileParse.java +++ b/src/jalview/io/FileParse.java @@ -58,6 +58,8 @@ public class FileParse public File inFile = null; + public byte[] bytes; // from JavaScript + /** * a viewport associated with the current file operation. May be null. May * move to different object. @@ -315,12 +317,41 @@ public class FileParse public FileParse(String fileStr, DataSourceType sourceType) throws MalformedURLException, IOException { + + this(null, fileStr, sourceType, false); + } + + public FileParse(File file, DataSourceType sourceType) + throws MalformedURLException, IOException + { + + this(file, file.getPath(), sourceType, true); + } + + private FileParse(File file, String fileStr, DataSourceType sourceType, + boolean isFileObject) throws MalformedURLException, IOException + { + + /** + * @j2sNative + * + * this.bytes = file && file._bytes; + * + */ this.dataSourceType = sourceType; error = false; if (sourceType == DataSourceType.FILE) { - if (checkFileSource(fileStr)) + + if (bytes != null) + { + // this will be from JavaScript + inFile = file; + dataIn = new BufferedReader(new StringReader(new String(bytes))); + dataName = fileStr; + } + else if (checkFileSource(fileStr)) { String suffixLess = extractSuffix(fileStr); if (suffixLess != null) @@ -434,7 +465,8 @@ public class FileParse { // pass up the reason why we have no source to read from throw new IOException(MessageManager.formatMessage( - "exception.failed_to_read_data_from_source", new String[] + "exception.failed_to_read_data_from_source", + new String[] { errormessage })); } error = false; diff --git a/src/jalview/io/FormatAdapter.java b/src/jalview/io/FormatAdapter.java index 6d3c18a..2264a6a 100755 --- a/src/jalview/io/FormatAdapter.java +++ b/src/jalview/io/FormatAdapter.java @@ -32,6 +32,7 @@ import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; import jalview.util.Comparison; +import java.io.File; import java.io.IOException; /** @@ -235,6 +236,13 @@ public class FormatAdapter extends AppletFormatAdapter return al; } + public AlignmentI readFile(File file, DataSourceType sourceType, + FileFormatI fileFormat) throws IOException + { + AlignmentI al = super.readFile(file, null, sourceType, fileFormat); + return al; + } + @Override public AlignmentI readFromFile(FileParse source, FileFormatI format) throws IOException diff --git a/src/jalview/io/IdentifyFile.java b/src/jalview/io/IdentifyFile.java index aafe934..e2786ae 100755 --- a/src/jalview/io/IdentifyFile.java +++ b/src/jalview/io/IdentifyFile.java @@ -20,6 +20,7 @@ */ package jalview.io; +import java.io.File; import java.io.IOException; /** @@ -30,6 +31,31 @@ import java.io.IOException; */ public class IdentifyFile { + public FileFormatI identify(File file, DataSourceType sourceType) + throws FileFormatException + { + String emessage = "UNIDENTIFIED FILE PARSING ERROR"; + FileParse parser = null; + try + { + parser = new FileParse(file, sourceType); + if (parser.isValid()) + { + return identify(parser); + } + } catch (Exception e) + { + System.err.println("Error whilst identifying " + file); + e.printStackTrace(System.err); + emessage = e.getMessage(); + } + if (parser != null) + { + throw new FileFormatException(parser.errormessage); + } + throw new FileFormatException(emessage); + } + /** * Identify a datasource's file content. * @@ -439,4 +465,5 @@ public class IdentifyFile System.err.println("Usage: [ ...]"); } } + } diff --git a/src/jalview/io/JalviewFileChooser.java b/src/jalview/io/JalviewFileChooser.java index c49e34f..ae6c9eb 100755 --- a/src/jalview/io/JalviewFileChooser.java +++ b/src/jalview/io/JalviewFileChooser.java @@ -32,6 +32,8 @@ import java.awt.EventQueue; import java.awt.HeadlessException; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; import java.io.File; import java.util.ArrayList; import java.util.List; @@ -56,6 +58,7 @@ import javax.swing.plaf.basic.BasicFileChooserUI; * */ public class JalviewFileChooser extends JFileChooser + implements PropertyChangeListener { /** * Factory method to return a file chooser that offers readable alignment file @@ -68,8 +71,8 @@ public class JalviewFileChooser extends JFileChooser public static JalviewFileChooser forRead(String directory, String selected) { - List extensions = new ArrayList(); - List descs = new ArrayList(); + List extensions = new ArrayList<>(); + List descs = new ArrayList<>(); for (FileFormatI format : FileFormats.getInstance().getFormats()) { if (format.isReadable()) @@ -96,8 +99,8 @@ public class JalviewFileChooser extends JFileChooser { // TODO in Java 8, forRead and forWrite can be a single method // with a lambda expression parameter for isReadable/isWritable - List extensions = new ArrayList(); - List descs = new ArrayList(); + List extensions = new ArrayList<>(); + List descs = new ArrayList<>(); for (FileFormatI format : FileFormats.getInstance().getFormats()) { if (format.isWritable()) @@ -142,7 +145,7 @@ public class JalviewFileChooser extends JFileChooser super(safePath(dir)); if (extensions.length == descs.length) { - List formats = new ArrayList(); + List formats = new ArrayList<>(); for (int i = 0; i < extensions.length; i++) { formats.add(new String[] { extensions[i], descs[i] }); @@ -156,6 +159,29 @@ public class JalviewFileChooser extends JFileChooser } } + private Runnable theCallback; + + public void setCallback(Runnable callback) + { + this.theCallback = callback; + } + + public Runnable getCallback() + { + return theCallback; + } + + @Override + public void propertyChange(PropertyChangeEvent evt) + { + switch (evt.getPropertyName()) + { + case "SelectedFile": + theCallback.run(); + break; + } + } + private static File safePath(String dir) { if (dir == null) @@ -287,6 +313,7 @@ public class JalviewFileChooser extends JFileChooser int ret = showDialog(parent, MessageManager.getString("action.save")); + if (getFileFilter() instanceof JalviewFileFilter) { JalviewFileFilter jvf = (JalviewFileFilter) getFileFilter(); @@ -408,4 +435,5 @@ public class JalviewFileChooser extends JFileChooser } } + } -- 1.7.10.2