JAL-3032 part2 local file reading by JFileChooser
authorhansonr <hansonr@stolaf.edu>
Wed, 27 Jun 2018 10:20:25 +0000 (11:20 +0100)
committerhansonr <hansonr@stolaf.edu>
Wed, 27 Jun 2018 10:22:27 +0000 (11:22 +0100)
This commit adds the ALignFrame changes for handling the
JalviewFileChooser callback.

src/jalview/gui/AlignFrame.java
src/jalview/gui/Desktop.java
src/jalview/io/AppletFormatAdapter.java
src/jalview/io/FileLoader.java
src/jalview/io/FileParse.java
src/jalview/io/FormatAdapter.java
src/jalview/io/IdentifyFile.java
src/jalview/io/JalviewFileChooser.java

index a2b1e47..26c5548 100644 (file)
@@ -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
index bc5db70..e82bd9c 100644 (file)
@@ -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<Thread, MyDesktopPane> 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;
index 3f51ea8..bc2465a 100755 (executable)
@@ -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));
index 9dd740b..74c82eb 100755 (executable)
@@ -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.
             }
           }
index bf0a844..7e1940f 100755 (executable)
@@ -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;
index 6d3c18a..2264a6a 100755 (executable)
@@ -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
index aafe934..e2786ae 100755 (executable)
@@ -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: <Filename> [<Filename> ...]");
     }
   }
+
 }
index c49e34f..ae6c9eb 100755 (executable)
@@ -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<String> extensions = new ArrayList<String>();
-    List<String> descs = new ArrayList<String>();
+    List<String> extensions = new ArrayList<>();
+    List<String> 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<String> extensions = new ArrayList<String>();
-    List<String> descs = new ArrayList<String>();
+    List<String> extensions = new ArrayList<>();
+    List<String> 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<String[]> formats = new ArrayList<String[]>();
+      List<String[]> 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
     }
 
   }
+
 }