tidied up system.out messages and moved many to stderr.
[jalview.git] / src / jalview / io / JalviewFileChooser.java
1 \r
2 /*///////////////////////////////////////////////////////////////////\r
3 // This file was taken from java forum\r
4 // Re: JFileChooser functioning like normal Windows Apps FileChooser\r
5 // Author: ddanimal\r
6 // http://forum.java.sun.com/thread.jspa?forumID=57&threadID=327712\r
7 *///////////////////////////////////////////////////////////////////\r
8 \r
9 package jalview.io;\r
10 \r
11 import java.awt.*;\r
12 import java.awt.event.*;\r
13 import java.io.*;\r
14 import java.util.*;\r
15 \r
16 import javax.swing.*;\r
17 import javax.swing.plaf.*;\r
18 import javax.swing.plaf.basic.*;\r
19 import javax.swing.plaf.metal.*;\r
20 import javax.swing.table.*;\r
21 \r
22 public class JalviewFileChooser extends JFileChooser\r
23 {\r
24 \r
25   private static final int COLUMN_FILENAME = 0;\r
26   private static final int COLUMN_FILESIZE = 1;\r
27   private static final int COLUMN_FILETYPE = 2;\r
28   private static final int COLUMN_FILEDATE = 3;\r
29   private static final int COLUMN_FILEATTR = 4;\r
30   private static final int COLUMN_COLCOUNT = 5;\r
31   private static String[] COLUMNS = null;\r
32 \r
33 \r
34   public JalviewFileChooser(String dir, String [] suffix, String [] desc, String selected)\r
35   {\r
36     super(dir);\r
37 \r
38     JalviewFileFilter chosen = null;\r
39     for(int i=0; i<suffix.length; i++)\r
40     {\r
41       JalviewFileFilter jvf = new JalviewFileFilter(suffix[i], desc[i]);\r
42       addChoosableFileFilter(jvf);\r
43       if(selected!=null && selected.equalsIgnoreCase(desc[i]))\r
44         chosen = jvf;\r
45     }\r
46     if(chosen!=null)\r
47       setFileFilter(chosen);\r
48     initColumns();\r
49   }\r
50 \r
51   public String getSelectedFormat()\r
52   {\r
53 \r
54     String format = getFileFilter().getDescription();\r
55 \r
56     if (format.toUpperCase().startsWith("JALVIEW"))\r
57       format = "Jalview";\r
58     else if (format.toUpperCase().startsWith("FASTA"))\r
59       format = "FASTA";\r
60     else if (format.toUpperCase().startsWith("MSF"))\r
61       format = "MSF";\r
62     else if (format.toUpperCase().startsWith("CLUSTAL"))\r
63       format = "CLUSTAL";\r
64     else if (format.toUpperCase().startsWith("BLC"))\r
65       format = "BLC";\r
66     else if (format.toUpperCase().startsWith("PIR"))\r
67       format = "PIR";\r
68     else if (format.toUpperCase().startsWith("PFAM"))\r
69       format = "PFAM";\r
70 \r
71     return format;\r
72   }\r
73   public JalviewFileChooser(String dir)\r
74   {\r
75     super(dir);\r
76     initColumns();\r
77   }\r
78 \r
79   public int showSaveDialog(Component parent) throws HeadlessException {\r
80       setDialogType(SAVE_DIALOG);\r
81       int ret = showDialog(parent, null);\r
82 \r
83       if(getFileFilter() instanceof JalviewFileFilter)\r
84       {\r
85         JalviewFileFilter jvf = (JalviewFileFilter) getFileFilter();\r
86         if (!jvf.accept(getSelectedFile()))\r
87         {\r
88           String withExtension = getSelectedFile() + "." + jvf.getAcceptableExtension();\r
89           setSelectedFile(new File(withExtension));\r
90         }\r
91       }\r
92 \r
93       if(ret == JalviewFileChooser.APPROVE_OPTION  &&  getSelectedFile().exists() )\r
94       {\r
95        int confirm =  JOptionPane.showConfirmDialog(parent,\r
96                                       "Overwrite existing file?",\r
97                                       "File exists",\r
98                                       JOptionPane.YES_NO_OPTION);\r
99        if(confirm!=JOptionPane.YES_OPTION)\r
100          ret = this.CANCEL_OPTION;\r
101       }\r
102       return ret;\r
103   }\r
104 \r
105 \r
106   void initColumns()\r
107   {\r
108     if (COLUMNS == null)\r
109     {\r
110         Locale l = getLocale();\r
111         COLUMNS = new String[]{\r
112         UIManager.getString("FileChooser.fileNameHeaderText",l),\r
113         UIManager.getString("FileChooser.fileSizeHeaderText",l),\r
114         UIManager.getString("FileChooser.fileTypeHeaderText",l),\r
115         UIManager.getString("FileChooser.fileDateHeaderText",l),\r
116         UIManager.getString("FileChooser.fileAttrHeaderText",l)\r
117       };\r
118     }\r
119   }\r
120 \r
121   /**************************************************************************\r
122    * Always create the local UI\r
123    * @param comp\r
124    *************************************************************************/\r
125   public final void setUI(ComponentUI comp)\r
126   {\r
127     super.setUI(new UI(this));\r
128   }\r
129 \r
130    /**************************************************************************\r
131     * Internal implementation of Metal LookAndFeel to create the table sorting\r
132     * ability.\r
133     *************************************************************************/\r
134    private final static class UI extends MetalFileChooserUI\r
135    {\r
136      private DirectoryModel model;\r
137 \r
138      /**************************************************************************\r
139       * Must be overridden to extend\r
140       * @param e\r
141       *************************************************************************/\r
142      public UI(JFileChooser e)\r
143      {\r
144        super(e);\r
145      }\r
146 \r
147      /**************************************************************************\r
148       * Overridden to create our own model\r
149       *************************************************************************/\r
150      protected final void createModel()\r
151      {\r
152        model = new DirectoryModel(getFileChooser());\r
153      }\r
154 \r
155      /**************************************************************************\r
156       * Overridden to get our own model\r
157       * @return\r
158       *************************************************************************/\r
159      public final BasicDirectoryModel getModel() {       return model;     }\r
160 \r
161      /**************************************************************************\r
162       * Calls the default method then adds a MouseListener to the JTable\r
163       * @param chooser\r
164       * @return\r
165       *************************************************************************/\r
166      protected final JPanel createDetailsView(JFileChooser chooser)\r
167      {\r
168        final JPanel panel = super.createDetailsView(chooser);\r
169 \r
170        //Since we can't access MetalFileChooserUI's private member detailsTable\r
171        //directly, we have to find it in the JPanel\r
172        final JTable tbl = findJTable(panel.getComponents());\r
173        if (tbl != null)\r
174        {\r
175          //Fix the columns so they can't be rearranged, if we don't do this\r
176          //we would need to keep track when each column is moved\r
177          tbl.getTableHeader().setReorderingAllowed(false);\r
178 \r
179          //Add a mouselistener to listen for clicks on column headers\r
180          tbl.getTableHeader().addMouseListener(new MouseAdapter(){\r
181            public void mouseClicked(MouseEvent e)\r
182            {\r
183              //Only process single clicks\r
184              if (e.getClickCount() > 1) return;\r
185              e.consume();\r
186              final int col = tbl.getTableHeader().columnAtPoint(e.getPoint());\r
187              if (col == COLUMN_FILENAME || col == COLUMN_FILESIZE ||\r
188                  col == COLUMN_FILEDATE)\r
189                model.sort(col,tbl);\r
190            }\r
191          });\r
192        }\r
193        return panel;\r
194      }\r
195 \r
196      /**************************************************************************\r
197       * Finds the JTable in the panel so we can add MouseListener\r
198       * @param comp\r
199       * @return\r
200       *************************************************************************/\r
201      private final static JTable findJTable(Component[] comp)\r
202      {\r
203        for (int i=0;i<comp.length;i++)\r
204        {\r
205          if (comp[i] instanceof JTable)\r
206          {\r
207            return (JTable)comp[i];\r
208          }\r
209          if (comp[i] instanceof Container)\r
210          {\r
211            JTable tbl = findJTable(((Container)comp[i]).getComponents());\r
212            if (tbl != null) return tbl;\r
213          }\r
214        }\r
215        return null;\r
216      }\r
217    }\r
218 \r
219   /***************************************************************************\r
220    * Implementation of BasicDirectoryModel that sorts the Files by column\r
221    **************************************************************************/\r
222   private final static class DirectoryModel extends BasicDirectoryModel\r
223    {\r
224      int col = 0;\r
225      boolean ascending;\r
226 \r
227      /**************************************************************************\r
228       * Must be overridden to extend BasicDirectoryModel\r
229       * @param chooser\r
230       *************************************************************************/\r
231      DirectoryModel(JFileChooser chooser)\r
232      {\r
233        super(chooser);\r
234      }\r
235 \r
236 \r
237      /**************************************************************************\r
238       * Supposedly this is not used anymore, hopefully not.  We implemented\r
239       * some basic attempt at sorting just in case\r
240       * @param a\r
241       * @param b\r
242       * @return\r
243       *************************************************************************/\r
244      protected final boolean lt(File a, File b)\r
245      {\r
246        System.out.println("DEBUG:LT called?");\r
247        boolean less = false;\r
248        switch (col)\r
249        {\r
250          case COLUMN_FILEDATE:\r
251            less = a.lastModified() > b.lastModified();\r
252            break;\r
253          case COLUMN_FILESIZE:\r
254            less = a.length() > b.length();\r
255            break;\r
256          default:\r
257            less = a.getName().compareToIgnoreCase(b.getName()) > 0;\r
258          break;\r
259        }\r
260        if (ascending) return less = !less;\r
261        return less;\r
262      }\r
263 \r
264      /**************************************************************************\r
265       * Resorts the JFileChooser table based on new column\r
266       * @param c\r
267       *************************************************************************/\r
268      protected final void sort(int c, JTable tbl)\r
269      {\r
270        //Set column and order\r
271        col = c;\r
272        ascending = !ascending;\r
273        String indicator = " (^)";\r
274        if (ascending)\r
275          indicator = " (v)";\r
276 \r
277        final JTableHeader th = tbl.getTableHeader();\r
278        final TableColumnModel tcm = th.getColumnModel();\r
279 \r
280        for (int i=0;i<JalviewFileChooser.COLUMN_COLCOUNT;i++)\r
281        {\r
282          final TableColumn tc = tcm.getColumn( i ); // the column to change\r
283          tc.setHeaderValue( COLUMNS[i] );\r
284        }\r
285 \r
286        final TableColumn tc = tcm.getColumn( col ); // the column to change\r
287        tc.setHeaderValue( COLUMNS[col] + indicator );\r
288 \r
289        th.repaint();\r
290 \r
291        //Requery the file listing\r
292        validateFileCache();\r
293      }\r
294 \r
295      /**************************************************************************\r
296       * Sorts the data based on current column setting\r
297       * @param data\r
298       *************************************************************************/\r
299      protected final void sort(Vector data)\r
300      {\r
301        switch (col)\r
302        {\r
303          case COLUMN_FILEDATE:\r
304            Collections.sort(data,new Comparator(){\r
305              public int compare(Object o1,Object o2)\r
306              {\r
307                int ret = 1;\r
308                final File a = (File)o1;\r
309                final File b = (File)o2;\r
310                if (a.lastModified() > b.lastModified())\r
311                  ret = -1;\r
312                else if (a.lastModified() == b.lastModified())\r
313                  ret = 0;\r
314 \r
315                if (ascending)\r
316                  ret *= -1;\r
317                return ret;\r
318              }\r
319 \r
320            });\r
321            break;\r
322          case COLUMN_FILESIZE:\r
323            Collections.sort(data,new Comparator(){\r
324              public int compare(Object o1,Object o2)\r
325              {\r
326                int ret = 1;\r
327                final File a = (File)o1;\r
328                final File b = (File)o2;\r
329                if (a.length() > b.length())\r
330                  ret = -1;\r
331                else if (a.length() == b.length())\r
332                  ret = 0;\r
333 \r
334                if (ascending)\r
335                  ret *= -1;\r
336                return ret;\r
337              }\r
338 \r
339            });\r
340            break;\r
341          case COLUMN_FILENAME:\r
342            Collections.sort(data,new Comparator(){\r
343              public int compare(Object o1,Object o2)\r
344              {\r
345                final File a = (File)o1;\r
346                final File b = (File)o2;\r
347                if (ascending)\r
348                  return a.getName().compareToIgnoreCase(b.getName());\r
349                else\r
350                  return -1 * a.getName().compareToIgnoreCase(b.getName());\r
351              }\r
352 \r
353            });\r
354            break;\r
355        }\r
356      }\r
357   }\r
358 }\r
359 \r