override showSaveDialog to prompt user if file exists
[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)\r
35   {\r
36     super(dir);\r
37     JalviewFileFilter filter = new JalviewFileFilter(suffix, desc);\r
38     this.setFileFilter(filter);\r
39     initColumns();\r
40   }\r
41 \r
42   public JalviewFileChooser(String dir)\r
43   {\r
44     super(dir);\r
45     initColumns();\r
46   }\r
47 \r
48   public int showSaveDialog(Component parent) throws HeadlessException {\r
49       setDialogType(SAVE_DIALOG);\r
50       int ret = showDialog(parent, null);\r
51 \r
52       if(ret == JalviewFileChooser.APPROVE_OPTION  &&  getSelectedFile().exists() )\r
53       {\r
54        int confirm =  JOptionPane.showConfirmDialog(parent,\r
55                                       "Overwrite existing file?",\r
56                                       "File exists",\r
57                                       JOptionPane.YES_NO_OPTION);\r
58        if(confirm!=JOptionPane.YES_OPTION)\r
59          ret = this.CANCEL_OPTION;\r
60       }\r
61       return ret;\r
62   }\r
63 \r
64 \r
65   void initColumns()\r
66   {\r
67     if (COLUMNS == null)\r
68     {\r
69         Locale l = getLocale();\r
70         COLUMNS = new String[]{\r
71         UIManager.getString("FileChooser.fileNameHeaderText",l),\r
72         UIManager.getString("FileChooser.fileSizeHeaderText",l),\r
73         UIManager.getString("FileChooser.fileTypeHeaderText",l),\r
74         UIManager.getString("FileChooser.fileDateHeaderText",l),\r
75         UIManager.getString("FileChooser.fileAttrHeaderText",l)\r
76       };\r
77     }\r
78   }\r
79 \r
80   /**************************************************************************\r
81    * Always create the local UI\r
82    * @param comp\r
83    *************************************************************************/\r
84   public final void setUI(ComponentUI comp)\r
85   {\r
86     super.setUI(new UI(this));\r
87   }\r
88 \r
89    /**************************************************************************\r
90     * Internal implementation of Metal LookAndFeel to create the table sorting\r
91     * ability.\r
92     *************************************************************************/\r
93    private final static class UI extends MetalFileChooserUI\r
94    {\r
95      private DirectoryModel model;\r
96 \r
97      /**************************************************************************\r
98       * Must be overridden to extend\r
99       * @param e\r
100       *************************************************************************/\r
101      public UI(JFileChooser e)\r
102      {\r
103        super(e);\r
104      }\r
105 \r
106      /**************************************************************************\r
107       * Overridden to create our own model\r
108       *************************************************************************/\r
109      protected final void createModel()\r
110      {\r
111        model = new DirectoryModel(getFileChooser());\r
112      }\r
113 \r
114      /**************************************************************************\r
115       * Overridden to get our own model\r
116       * @return\r
117       *************************************************************************/\r
118      public final BasicDirectoryModel getModel() {       return model;     }\r
119 \r
120      /**************************************************************************\r
121       * Calls the default method then adds a MouseListener to the JTable\r
122       * @param chooser\r
123       * @return\r
124       *************************************************************************/\r
125      protected final JPanel createDetailsView(JFileChooser chooser)\r
126      {\r
127        final JPanel panel = super.createDetailsView(chooser);\r
128 \r
129        //Since we can't access MetalFileChooserUI's private member detailsTable\r
130        //directly, we have to find it in the JPanel\r
131        final JTable tbl = findJTable(panel.getComponents());\r
132        if (tbl != null)\r
133        {\r
134          //Fix the columns so they can't be rearranged, if we don't do this\r
135          //we would need to keep track when each column is moved\r
136          tbl.getTableHeader().setReorderingAllowed(false);\r
137 \r
138          //Add a mouselistener to listen for clicks on column headers\r
139          tbl.getTableHeader().addMouseListener(new MouseAdapter(){\r
140            public void mouseClicked(MouseEvent e)\r
141            {\r
142              //Only process single clicks\r
143              if (e.getClickCount() > 1) return;\r
144              e.consume();\r
145              final int col = tbl.getTableHeader().columnAtPoint(e.getPoint());\r
146              if (col == COLUMN_FILENAME || col == COLUMN_FILESIZE ||\r
147                  col == COLUMN_FILEDATE)\r
148                model.sort(col,tbl);\r
149            }\r
150          });\r
151        }\r
152        return panel;\r
153      }\r
154 \r
155      /**************************************************************************\r
156       * Finds the JTable in the panel so we can add MouseListener\r
157       * @param comp\r
158       * @return\r
159       *************************************************************************/\r
160      private final static JTable findJTable(Component[] comp)\r
161      {\r
162        for (int i=0;i<comp.length;i++)\r
163        {\r
164          if (comp[i] instanceof JTable)\r
165          {\r
166            return (JTable)comp[i];\r
167          }\r
168          if (comp[i] instanceof Container)\r
169          {\r
170            JTable tbl = findJTable(((Container)comp[i]).getComponents());\r
171            if (tbl != null) return tbl;\r
172          }\r
173        }\r
174        return null;\r
175      }\r
176    }\r
177 \r
178   /***************************************************************************\r
179    * Implementation of BasicDirectoryModel that sorts the Files by column\r
180    **************************************************************************/\r
181   private final static class DirectoryModel extends BasicDirectoryModel\r
182    {\r
183      int col = 0;\r
184      boolean ascending;\r
185 \r
186      /**************************************************************************\r
187       * Must be overridden to extend BasicDirectoryModel\r
188       * @param chooser\r
189       *************************************************************************/\r
190      DirectoryModel(JFileChooser chooser)\r
191      {\r
192        super(chooser);\r
193      }\r
194 \r
195 \r
196      /**************************************************************************\r
197       * Supposedly this is not used anymore, hopefully not.  We implemented\r
198       * some basic attempt at sorting just in case\r
199       * @param a\r
200       * @param b\r
201       * @return\r
202       *************************************************************************/\r
203      protected final boolean lt(File a, File b)\r
204      {\r
205        System.out.println("LT called?");\r
206        boolean less = false;\r
207        switch (col)\r
208        {\r
209          case COLUMN_FILEDATE:\r
210            less = a.lastModified() > b.lastModified();\r
211            break;\r
212          case COLUMN_FILESIZE:\r
213            less = a.length() > b.length();\r
214            break;\r
215          default:\r
216            less = a.getName().compareToIgnoreCase(b.getName()) > 0;\r
217          break;\r
218        }\r
219        if (ascending) return less = !less;\r
220        return less;\r
221      }\r
222 \r
223      /**************************************************************************\r
224       * Resorts the JFileChooser table based on new column\r
225       * @param c\r
226       *************************************************************************/\r
227      protected final void sort(int c, JTable tbl)\r
228      {\r
229        //Set column and order\r
230        col = c;\r
231        ascending = !ascending;\r
232        String indicator = " (^)";\r
233        if (ascending)\r
234          indicator = " (v)";\r
235 \r
236        final JTableHeader th = tbl.getTableHeader();\r
237        final TableColumnModel tcm = th.getColumnModel();\r
238 \r
239        for (int i=0;i<JalviewFileChooser.COLUMN_COLCOUNT;i++)\r
240        {\r
241          final TableColumn tc = tcm.getColumn( i ); // the column to change\r
242          tc.setHeaderValue( COLUMNS[i] );\r
243        }\r
244 \r
245        final TableColumn tc = tcm.getColumn( col ); // the column to change\r
246        tc.setHeaderValue( COLUMNS[col] + indicator );\r
247 \r
248        th.repaint();\r
249 \r
250        //Requery the file listing\r
251        validateFileCache();\r
252      }\r
253 \r
254      /**************************************************************************\r
255       * Sorts the data based on current column setting\r
256       * @param data\r
257       *************************************************************************/\r
258      protected final void sort(Vector data)\r
259      {\r
260        switch (col)\r
261        {\r
262          case COLUMN_FILEDATE:\r
263            Collections.sort(data,new Comparator(){\r
264              public int compare(Object o1,Object o2)\r
265              {\r
266                int ret = 1;\r
267                final File a = (File)o1;\r
268                final File b = (File)o2;\r
269                if (a.lastModified() > b.lastModified())\r
270                  ret = -1;\r
271                else if (a.lastModified() == b.lastModified())\r
272                  ret = 0;\r
273 \r
274                if (ascending)\r
275                  ret *= -1;\r
276                return ret;\r
277              }\r
278 \r
279            });\r
280            break;\r
281          case COLUMN_FILESIZE:\r
282            Collections.sort(data,new Comparator(){\r
283              public int compare(Object o1,Object o2)\r
284              {\r
285                int ret = 1;\r
286                final File a = (File)o1;\r
287                final File b = (File)o2;\r
288                if (a.length() > b.length())\r
289                  ret = -1;\r
290                else if (a.length() == b.length())\r
291                  ret = 0;\r
292 \r
293                if (ascending)\r
294                  ret *= -1;\r
295                return ret;\r
296              }\r
297 \r
298            });\r
299            break;\r
300          case COLUMN_FILENAME:\r
301            Collections.sort(data,new Comparator(){\r
302              public int compare(Object o1,Object o2)\r
303              {\r
304                final File a = (File)o1;\r
305                final File b = (File)o2;\r
306                if (ascending)\r
307                  return a.getName().compareToIgnoreCase(b.getName());\r
308                else\r
309                  return -1 * a.getName().compareToIgnoreCase(b.getName());\r
310              }\r
311 \r
312            });\r
313            break;\r
314        }\r
315      }\r
316   }\r
317 }\r
318 \r