Formatting changes
[jalview.git] / src / jalview / io / JalviewFileChooser.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
4  *\r
5  * This program is free software; you can redistribute it and/or\r
6  * modify it under the terms of the GNU General Public License\r
7  * as published by the Free Software Foundation; either version 2\r
8  * of the License, or (at your option) any later version.\r
9  *\r
10  * This program is distributed in the hope that it will be useful,\r
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13  * GNU General Public License for more details.\r
14  *\r
15  * You should have received a copy of the GNU General Public License\r
16  * along with this program; if not, write to the Free Software\r
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
18  */\r
19 /*///////////////////////////////////////////////////////////////////\r
20 // This file was taken from java forum\r
21 // Re: JFileChooser functioning like normal Windows Apps FileChooser\r
22 // Author: ddanimal\r
23 // http://forum.java.sun.com/thread.jspa?forumID=57&threadID=327712\r
24 */\r
25 \r
26 //////////////////////////////////////////////////////////////////\r
27 package jalview.io;\r
28 \r
29 import java.io.*;\r
30 import java.util.*;\r
31 \r
32 import java.awt.*;\r
33 import java.awt.event.*;\r
34 import javax.swing.*;\r
35 import javax.swing.plaf.*;\r
36 import javax.swing.plaf.basic.*;\r
37 import javax.swing.plaf.metal.*;\r
38 import javax.swing.table.*;\r
39 \r
40 public class JalviewFileChooser\r
41     extends JFileChooser\r
42 {\r
43 \r
44 \r
45   public JalviewFileChooser(String dir, String[] suffix, String[] desc,\r
46                             String selected)\r
47   {\r
48     super(dir);\r
49 \r
50     JalviewFileFilter chosen = null;\r
51 \r
52     for (int i = 0; i < suffix.length; i++)\r
53     {\r
54       JalviewFileFilter jvf = new JalviewFileFilter(suffix[i], desc[i]);\r
55       addChoosableFileFilter(jvf);\r
56 \r
57       if ( (selected != null) && selected.equalsIgnoreCase(desc[i]))\r
58       {\r
59         chosen = jvf;\r
60       }\r
61     }\r
62 \r
63     if (chosen != null)\r
64     {\r
65       setFileFilter(chosen);\r
66     }\r
67 \r
68   }\r
69 \r
70 \r
71   public void setFileFilter(javax.swing.filechooser.FileFilter filter)\r
72  {\r
73    super.setFileFilter(filter);\r
74 \r
75    if (!(getUI() instanceof BasicFileChooserUI)) {\r
76            return;\r
77    }\r
78 \r
79    final BasicFileChooserUI ui = (BasicFileChooserUI) getUI();\r
80    final String name = ui.getFileName().trim();\r
81 \r
82    if ((name == null) || (name.length() == 0)) {\r
83            return;\r
84    }\r
85 \r
86    EventQueue.invokeLater(new Thread() {\r
87            public void run() {\r
88                    String currentName = ui.getFileName();\r
89                    if ((currentName == null) || (currentName.length() == 0)) {\r
90                            ui.setFileName(name);\r
91                    }\r
92            }\r
93         });\r
94  }\r
95 \r
96 \r
97   public JalviewFileChooser(String dir)\r
98   {\r
99     super(dir);\r
100   }\r
101 \r
102   public String getSelectedFormat()\r
103   {\r
104     String format = getFileFilter().getDescription();\r
105 \r
106     if (format.toUpperCase().startsWith("JALVIEW"))\r
107     {\r
108       format = "Jalview";\r
109     }\r
110     else if (format.toUpperCase().startsWith("FASTA"))\r
111     {\r
112       format = "FASTA";\r
113     }\r
114     else if (format.toUpperCase().startsWith("MSF"))\r
115     {\r
116       format = "MSF";\r
117     }\r
118     else if (format.toUpperCase().startsWith("CLUSTAL"))\r
119     {\r
120       format = "CLUSTAL";\r
121     }\r
122     else if (format.toUpperCase().startsWith("BLC"))\r
123     {\r
124       format = "BLC";\r
125     }\r
126     else if (format.toUpperCase().startsWith("PIR"))\r
127     {\r
128       format = "PIR";\r
129     }\r
130     else if (format.toUpperCase().startsWith("PFAM"))\r
131     {\r
132       format = "PFAM";\r
133     }\r
134 \r
135     return format;\r
136   }\r
137 \r
138   public int showSaveDialog(Component parent)\r
139       throws HeadlessException\r
140   {\r
141     setDialogType(SAVE_DIALOG);\r
142 \r
143     int ret = showDialog(parent, null);\r
144 \r
145     if (getFileFilter() instanceof JalviewFileFilter)\r
146     {\r
147       JalviewFileFilter jvf = (JalviewFileFilter) getFileFilter();\r
148 \r
149       if (!jvf.accept(getSelectedFile()))\r
150       {\r
151         String withExtension = getSelectedFile() + "." +\r
152             jvf.getAcceptableExtension();\r
153         setSelectedFile(new File(withExtension));\r
154       }\r
155     }\r
156 \r
157     if ( (ret == JalviewFileChooser.APPROVE_OPTION) &&\r
158         getSelectedFile().exists())\r
159     {\r
160       int confirm = JOptionPane.showConfirmDialog(parent,\r
161                                                   "Overwrite existing file?",\r
162                                                   "File exists",\r
163                                                   JOptionPane.YES_NO_OPTION);\r
164 \r
165       if (confirm != JOptionPane.YES_OPTION)\r
166       {\r
167         ret = this.CANCEL_OPTION;\r
168       }\r
169     }\r
170 \r
171     return ret;\r
172   }\r
173 \r
174   /**************************************************************************\r
175    * Always create the local UI\r
176    * @param comp\r
177    *************************************************************************/\r
178   public final void setUI(ComponentUI comp)\r
179   {\r
180     super.setUI(new UI(this));\r
181   }\r
182 \r
183   /**************************************************************************\r
184    * Internal implementation of Metal LookAndFeel to create the table sorting\r
185    * ability.\r
186    *************************************************************************/\r
187   private class UI\r
188       extends MetalFileChooserUI\r
189   {\r
190     private DirectoryModel model;\r
191 \r
192     /**************************************************************************\r
193      * Must be overridden to extend\r
194      * @param e\r
195      *************************************************************************/\r
196     public UI(JFileChooser e)\r
197     {\r
198       super(e);\r
199     }\r
200 \r
201     /**************************************************************************\r
202      * Overridden to create our own model\r
203      *************************************************************************/\r
204     protected final void createModel()\r
205     {\r
206       model = new DirectoryModel(getFileChooser());\r
207     }\r
208 \r
209     /**************************************************************************\r
210      * Overridden to get our own model\r
211      * @return\r
212      *************************************************************************/\r
213     public final BasicDirectoryModel getModel()\r
214     {\r
215       return model;\r
216     }\r
217 \r
218     /**************************************************************************\r
219      * Calls the default method then adds a MouseListener to the JTable\r
220      * @param chooser\r
221      * @return\r
222      *************************************************************************/\r
223     protected final JPanel createDetailsView(JFileChooser chooser)\r
224     {\r
225       final JPanel panel = super.createDetailsView(chooser);\r
226 \r
227       //Since we can't access MetalFileChooserUI's private member detailsTable\r
228       //directly, we have to find it in the JPanel\r
229       final JTable tbl = findJTable(panel.getComponents());\r
230 \r
231       if (tbl != null)\r
232       {\r
233         //Add a mouselistener to listen for presses on column headers\r
234         tbl.getTableHeader().addMouseListener(new MouseAdapter()\r
235         {\r
236           public void mousePressed(MouseEvent e)\r
237           {\r
238 \r
239             e.consume();\r
240 \r
241             final int col = tbl.getTableHeader().columnAtPoint(e.getPoint());\r
242             model.sort(col, tbl);\r
243 \r
244           }\r
245         });\r
246       }\r
247 \r
248       return panel;\r
249     }\r
250 \r
251     /**************************************************************************\r
252      * Finds the JTable in the panel so we can add MouseListener\r
253      * @param comp\r
254      * @return\r
255      *************************************************************************/\r
256     private JTable findJTable(Component[] comp)\r
257     {\r
258       for (int i = 0; i < comp.length; i++)\r
259       {\r
260         if (comp[i] instanceof JTable)\r
261         {\r
262           return (JTable) comp[i];\r
263         }\r
264 \r
265         if (comp[i] instanceof Container)\r
266         {\r
267           JTable tbl = findJTable( ( (Container) comp[i]).getComponents());\r
268 \r
269           if (tbl != null)\r
270           {\r
271             return tbl;\r
272           }\r
273         }\r
274       }\r
275 \r
276       return null;\r
277     }\r
278   }\r
279 \r
280   /***************************************************************************\r
281    * Implementation of BasicDirectoryModel that sorts the Files by column\r
282    **************************************************************************/\r
283   private final  class DirectoryModel\r
284       extends BasicDirectoryModel\r
285   {\r
286     String sortingColumnName=null;\r
287     int col = 0;\r
288     boolean ascending;\r
289 \r
290     /**************************************************************************\r
291      * Must be overridden to extend BasicDirectoryModel\r
292      * @param chooser\r
293      *************************************************************************/\r
294     DirectoryModel(JFileChooser chooser)\r
295     {\r
296       super(chooser);\r
297     }\r
298 \r
299 \r
300     /**************************************************************************\r
301      * Resorts the JFileChooser table based on new column\r
302      * @param c\r
303      *************************************************************************/\r
304     protected final void sort(int c, JTable tbl)\r
305     {\r
306 \r
307 \r
308       //Set column and order\r
309       col = c;\r
310       ascending = !ascending;\r
311 \r
312       String indicator = " (^)";\r
313 \r
314       if (ascending)\r
315       {\r
316         indicator = " (v)";\r
317       }\r
318 \r
319       final JTableHeader th = tbl.getTableHeader();\r
320       final TableColumnModel tcm = th.getColumnModel();\r
321       TableColumn tc = null;\r
322       String title = null;\r
323 \r
324 \r
325       //Remove indicator from old sort, and add to new\r
326       for(int i=0; i<tcm.getColumnCount(); i++)\r
327       {\r
328         tc = tcm.getColumn(i);\r
329         title = tc.getHeaderValue().toString();\r
330         if (title.endsWith(" (^)") || title.endsWith(" (v)"))\r
331         {\r
332           title = title.substring(0, title.length() - 4);\r
333         }\r
334 \r
335         if(i==col)\r
336         {\r
337           sortingColumnName = title;\r
338           title = title + indicator;\r
339         }\r
340 \r
341         tc.setHeaderValue(title);\r
342       }\r
343 \r
344       //Requery the file listing\r
345       validateFileCache();\r
346     }\r
347 \r
348     /**************************************************************************\r
349      * Sorts the data based on current column setting\r
350      * @param data\r
351      *************************************************************************/\r
352     protected final void sort(Vector data)\r
353     {\r
354         /*\r
355                         UIManager.getString("FileChooser.fileTypeHeaderText", l),\r
356                         UIManager.getString("FileChooser.fileAttrHeaderText", l)\r
357 */\r
358     if(sortingColumnName==null)\r
359       return;\r
360 \r
361 \r
362     if(sortingColumnName.equals(UIManager.getString("FileChooser.fileDateHeaderText")))\r
363     {\r
364       Collections.sort(data,\r
365                            new Comparator()\r
366           {\r
367 \r
368             public int compare(Object o1, Object o2)\r
369             {\r
370               int ret = 1;\r
371               final File a = (File) o1;\r
372               final File b = (File) o2;\r
373 \r
374               if (a.lastModified() > b.lastModified())\r
375               {\r
376                 ret = -1;\r
377               }\r
378               else if (a.lastModified() == b.lastModified())\r
379               {\r
380                 ret = 0;\r
381               }\r
382 \r
383               if (ascending)\r
384               {\r
385                 ret *= -1;\r
386               }\r
387 \r
388               return ret;\r
389             }\r
390           });\r
391     }\r
392     else if(sortingColumnName.equals(UIManager.getString("FileChooser.fileSizeHeaderText")))\r
393     {\r
394 \r
395          Collections.sort(data,\r
396                            new Comparator()\r
397           {\r
398 \r
399             public int compare(Object o1, Object o2)\r
400             {\r
401               int ret = 1;\r
402               final File a = (File) o1;\r
403               final File b = (File) o2;\r
404 \r
405               if (a.length() > b.length())\r
406               {\r
407                 ret = -1;\r
408               }\r
409               else if (a.length() == b.length())\r
410               {\r
411                 ret = 0;\r
412               }\r
413 \r
414               if (ascending)\r
415               {\r
416                 ret *= -1;\r
417               }\r
418 \r
419               return ret;\r
420             }\r
421           });\r
422     }\r
423     else if(sortingColumnName.equals(UIManager.getString("FileChooser.fileTypeHeaderText")))\r
424     {\r
425           Collections.sort(data,\r
426                            new Comparator()\r
427           {\r
428             public int compare(Object o1, Object o2)\r
429             {\r
430               final String a = getFileSystemView().getSystemTypeDescription( (File)o1 );\r
431               final String b = getFileSystemView().getSystemTypeDescription( (File)o2 );\r
432               if (ascending)\r
433               {\r
434                 return a.compareToIgnoreCase(b);\r
435               }\r
436               else\r
437               {\r
438                 return -1 * a.compareToIgnoreCase(b);\r
439               }\r
440             }\r
441           });\r
442       }\r
443       else if(sortingColumnName.equals(UIManager.getString("FileChooser.fileNameHeaderText")))\r
444 {\r
445       Collections.sort(data,\r
446                        new Comparator()\r
447       {\r
448         public int compare(Object o1, Object o2)\r
449         {\r
450           final String a = ((File) o1).getName();\r
451           final String b = ((File) o2).getName();\r
452 \r
453           if (ascending)\r
454           {\r
455             return a.compareToIgnoreCase(b);\r
456           }\r
457           else\r
458           {\r
459             return -1 * a.compareToIgnoreCase(b);\r
460           }\r
461         }\r
462       });\r
463   }\r
464 \r
465     }\r
466   }\r
467 }\r