this.installIcons
[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 \r
176   /**************************************************************************\r
177    * Always create the local UI\r
178    * @param comp\r
179    *************************************************************************/\r
180   public final void setUI(ComponentUI comp)\r
181   {\r
182     UI ui = new UI(this);\r
183 \r
184     super.setUI(ui);\r
185   }\r
186 \r
187   /**************************************************************************\r
188    * Internal implementation of Metal LookAndFeel to create the table sorting\r
189    * ability.\r
190    *************************************************************************/\r
191   private class UI\r
192       extends MetalFileChooserUI\r
193   {\r
194     private DirectoryModel model;\r
195 \r
196     /**************************************************************************\r
197      * Must be overridden to extend\r
198      * @param e\r
199      *************************************************************************/\r
200     public UI(JFileChooser e)\r
201     {\r
202       super(e);\r
203       this.installIcons(e);\r
204     }\r
205 \r
206     /**************************************************************************\r
207      * Overridden to create our own model\r
208      *************************************************************************/\r
209     protected final void createModel()\r
210     {\r
211       model = new DirectoryModel(getFileChooser());\r
212     }\r
213 \r
214     /**************************************************************************\r
215      * Overridden to get our own model\r
216      * @return\r
217      *************************************************************************/\r
218     public final BasicDirectoryModel getModel()\r
219     {\r
220       return model;\r
221     }\r
222 \r
223     /**************************************************************************\r
224      * Calls the default method then adds a MouseListener to the JTable\r
225      * @param chooser\r
226      * @return\r
227      *************************************************************************/\r
228     protected final JPanel createDetailsView(JFileChooser chooser)\r
229     {\r
230       final JPanel panel = super.createDetailsView(chooser);\r
231 \r
232       //Since we can't access MetalFileChooserUI's private member detailsTable\r
233       //directly, we have to find it in the JPanel\r
234       final JTable tbl = findJTable(panel.getComponents());\r
235 \r
236       if (tbl != null)\r
237       {\r
238         //Add a mouselistener to listen for presses on column headers\r
239         tbl.getTableHeader().addMouseListener(new MouseAdapter()\r
240         {\r
241           public void mousePressed(MouseEvent e)\r
242           {\r
243 \r
244             e.consume();\r
245 \r
246             final int col = tbl.getTableHeader().columnAtPoint(e.getPoint());\r
247             model.sort(col, tbl);\r
248 \r
249           }\r
250         });\r
251       }\r
252 \r
253       return panel;\r
254     }\r
255 \r
256     /**************************************************************************\r
257      * Finds the JTable in the panel so we can add MouseListener\r
258      * @param comp\r
259      * @return\r
260      *************************************************************************/\r
261     private JTable findJTable(Component[] comp)\r
262     {\r
263       for (int i = 0; i < comp.length; i++)\r
264       {\r
265         if (comp[i] instanceof JTable)\r
266         {\r
267           return (JTable) comp[i];\r
268         }\r
269 \r
270         if (comp[i] instanceof Container)\r
271         {\r
272           JTable tbl = findJTable( ( (Container) comp[i]).getComponents());\r
273 \r
274           if (tbl != null)\r
275           {\r
276             return tbl;\r
277           }\r
278         }\r
279       }\r
280 \r
281       return null;\r
282     }\r
283   }\r
284 \r
285   /***************************************************************************\r
286    * Implementation of BasicDirectoryModel that sorts the Files by column\r
287    **************************************************************************/\r
288   private final  class DirectoryModel\r
289       extends BasicDirectoryModel\r
290   {\r
291     String sortingColumnName=null;\r
292     int col = 0;\r
293     boolean ascending;\r
294 \r
295     /**************************************************************************\r
296      * Must be overridden to extend BasicDirectoryModel\r
297      * @param chooser\r
298      *************************************************************************/\r
299     DirectoryModel(JFileChooser chooser)\r
300     {\r
301       super(chooser);\r
302     }\r
303 \r
304 \r
305     /**************************************************************************\r
306      * Resorts the JFileChooser table based on new column\r
307      * @param c\r
308      *************************************************************************/\r
309     protected final void sort(int c, JTable tbl)\r
310     {\r
311 \r
312 \r
313       //Set column and order\r
314       col = c;\r
315       ascending = !ascending;\r
316 \r
317       String indicator = " (^)";\r
318 \r
319       if (ascending)\r
320       {\r
321         indicator = " (v)";\r
322       }\r
323 \r
324       final JTableHeader th = tbl.getTableHeader();\r
325       final TableColumnModel tcm = th.getColumnModel();\r
326       TableColumn tc = null;\r
327       String title = null;\r
328 \r
329 \r
330       //Remove indicator from old sort, and add to new\r
331       for(int i=0; i<tcm.getColumnCount(); i++)\r
332       {\r
333         tc = tcm.getColumn(i);\r
334         title = tc.getHeaderValue().toString();\r
335         if (title.endsWith(" (^)") || title.endsWith(" (v)"))\r
336         {\r
337           title = title.substring(0, title.length() - 4);\r
338         }\r
339 \r
340         if(i==col)\r
341         {\r
342           sortingColumnName = title;\r
343           title = title + indicator;\r
344         }\r
345 \r
346         tc.setHeaderValue(title);\r
347       }\r
348 \r
349       //Requery the file listing\r
350       validateFileCache();\r
351     }\r
352 \r
353     /**************************************************************************\r
354      * Sorts the data based on current column setting\r
355      * @param data\r
356      *************************************************************************/\r
357     protected final void sort(Vector data)\r
358     {\r
359         /*\r
360                         UIManager.getString("FileChooser.fileTypeHeaderText", l),\r
361                         UIManager.getString("FileChooser.fileAttrHeaderText", l)\r
362 */\r
363     if(sortingColumnName==null)\r
364       return;\r
365 \r
366 \r
367     if(sortingColumnName.equals(UIManager.getString("FileChooser.fileDateHeaderText")))\r
368     {\r
369       Collections.sort(data,\r
370                            new Comparator()\r
371           {\r
372 \r
373             public int compare(Object o1, Object o2)\r
374             {\r
375               int ret = 1;\r
376               final File a = (File) o1;\r
377               final File b = (File) o2;\r
378 \r
379               if (a.lastModified() > b.lastModified())\r
380               {\r
381                 ret = -1;\r
382               }\r
383               else if (a.lastModified() == b.lastModified())\r
384               {\r
385                 ret = 0;\r
386               }\r
387 \r
388               if (ascending)\r
389               {\r
390                 ret *= -1;\r
391               }\r
392 \r
393               return ret;\r
394             }\r
395           });\r
396     }\r
397     else if(sortingColumnName.equals(UIManager.getString("FileChooser.fileSizeHeaderText")))\r
398     {\r
399 \r
400          Collections.sort(data,\r
401                            new Comparator()\r
402           {\r
403 \r
404             public int compare(Object o1, Object o2)\r
405             {\r
406               int ret = 1;\r
407               final File a = (File) o1;\r
408               final File b = (File) o2;\r
409 \r
410               if (a.length() > b.length())\r
411               {\r
412                 ret = -1;\r
413               }\r
414               else if (a.length() == b.length())\r
415               {\r
416                 ret = 0;\r
417               }\r
418 \r
419               if (ascending)\r
420               {\r
421                 ret *= -1;\r
422               }\r
423 \r
424               return ret;\r
425             }\r
426           });\r
427     }\r
428     else if(sortingColumnName.equals(UIManager.getString("FileChooser.fileTypeHeaderText")))\r
429     {\r
430           Collections.sort(data,\r
431                            new Comparator()\r
432           {\r
433             public int compare(Object o1, Object o2)\r
434             {\r
435               final String a = getFileSystemView().getSystemTypeDescription( (File)o1 );\r
436               final String b = getFileSystemView().getSystemTypeDescription( (File)o2 );\r
437               if (ascending)\r
438               {\r
439                 return a.compareToIgnoreCase(b);\r
440               }\r
441               else\r
442               {\r
443                 return -1 * a.compareToIgnoreCase(b);\r
444               }\r
445             }\r
446           });\r
447       }\r
448       else if(sortingColumnName.equals(UIManager.getString("FileChooser.fileNameHeaderText")))\r
449 {\r
450       Collections.sort(data,\r
451                        new Comparator()\r
452       {\r
453         public int compare(Object o1, Object o2)\r
454         {\r
455           final String a = ((File) o1).getName();\r
456           final String b = ((File) o2).getName();\r
457 \r
458           if (ascending)\r
459           {\r
460             return a.compareToIgnoreCase(b);\r
461           }\r
462           else\r
463           {\r
464             return -1 * a.compareToIgnoreCase(b);\r
465           }\r
466         }\r
467       });\r
468   }\r
469 \r
470     }\r
471   }\r
472 }\r