2 /*///////////////////////////////////////////////////////////////////
\r
3 // This file was taken from java forum
\r
4 // Re: JFileChooser functioning like normal Windows Apps FileChooser
\r
6 // http://forum.java.sun.com/thread.jspa?forumID=57&threadID=327712
\r
7 *///////////////////////////////////////////////////////////////////
\r
12 import java.awt.event.*;
\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
22 public class JalviewFileChooser extends JFileChooser
\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
34 public JalviewFileChooser(String dir, String [] suffix, String [] desc, String selected)
\r
38 JalviewFileFilter chosen = null;
\r
39 for(int i=0; i<suffix.length; i++)
\r
41 JalviewFileFilter jvf = new JalviewFileFilter(suffix[i], desc[i]);
\r
42 addChoosableFileFilter(jvf);
\r
43 if(selected!=null && selected.equalsIgnoreCase(desc[i]))
\r
47 setFileFilter(chosen);
\r
51 public String getSelectedFormat()
\r
54 String format = getFileFilter().getDescription();
\r
56 if (format.toUpperCase().startsWith("JALVIEW"))
\r
58 else if (format.toUpperCase().startsWith("FASTA"))
\r
60 else if (format.toUpperCase().startsWith("MSF"))
\r
62 else if (format.toUpperCase().startsWith("CLUSTAL"))
\r
64 else if (format.toUpperCase().startsWith("BLC"))
\r
66 else if (format.toUpperCase().startsWith("PIR"))
\r
68 else if (format.toUpperCase().startsWith("PFAM"))
\r
73 public JalviewFileChooser(String dir)
\r
79 public int showSaveDialog(Component parent) throws HeadlessException {
\r
80 setDialogType(SAVE_DIALOG);
\r
81 int ret = showDialog(parent, null);
\r
83 JalviewFileFilter jvf = (JalviewFileFilter)getFileFilter();
\r
84 if( !jvf.accept( getSelectedFile() ) )
\r
86 String withExtension = getSelectedFile()+"."+jvf.getAcceptableExtension();
\r
87 setSelectedFile(new File(withExtension));
\r
90 if(ret == JalviewFileChooser.APPROVE_OPTION && getSelectedFile().exists() )
\r
92 int confirm = JOptionPane.showConfirmDialog(parent,
\r
93 "Overwrite existing file?",
\r
95 JOptionPane.YES_NO_OPTION);
\r
96 if(confirm!=JOptionPane.YES_OPTION)
\r
97 ret = this.CANCEL_OPTION;
\r
105 if (COLUMNS == null)
\r
107 Locale l = getLocale();
\r
108 COLUMNS = new String[]{
\r
109 UIManager.getString("FileChooser.fileNameHeaderText",l),
\r
110 UIManager.getString("FileChooser.fileSizeHeaderText",l),
\r
111 UIManager.getString("FileChooser.fileTypeHeaderText",l),
\r
112 UIManager.getString("FileChooser.fileDateHeaderText",l),
\r
113 UIManager.getString("FileChooser.fileAttrHeaderText",l)
\r
118 /**************************************************************************
\r
119 * Always create the local UI
\r
121 *************************************************************************/
\r
122 public final void setUI(ComponentUI comp)
\r
124 super.setUI(new UI(this));
\r
127 /**************************************************************************
\r
128 * Internal implementation of Metal LookAndFeel to create the table sorting
\r
130 *************************************************************************/
\r
131 private final static class UI extends MetalFileChooserUI
\r
133 private DirectoryModel model;
\r
135 /**************************************************************************
\r
136 * Must be overridden to extend
\r
138 *************************************************************************/
\r
139 public UI(JFileChooser e)
\r
144 /**************************************************************************
\r
145 * Overridden to create our own model
\r
146 *************************************************************************/
\r
147 protected final void createModel()
\r
149 model = new DirectoryModel(getFileChooser());
\r
152 /**************************************************************************
\r
153 * Overridden to get our own model
\r
155 *************************************************************************/
\r
156 public final BasicDirectoryModel getModel() { return model; }
\r
158 /**************************************************************************
\r
159 * Calls the default method then adds a MouseListener to the JTable
\r
162 *************************************************************************/
\r
163 protected final JPanel createDetailsView(JFileChooser chooser)
\r
165 final JPanel panel = super.createDetailsView(chooser);
\r
167 //Since we can't access MetalFileChooserUI's private member detailsTable
\r
168 //directly, we have to find it in the JPanel
\r
169 final JTable tbl = findJTable(panel.getComponents());
\r
172 //Fix the columns so they can't be rearranged, if we don't do this
\r
173 //we would need to keep track when each column is moved
\r
174 tbl.getTableHeader().setReorderingAllowed(false);
\r
176 //Add a mouselistener to listen for clicks on column headers
\r
177 tbl.getTableHeader().addMouseListener(new MouseAdapter(){
\r
178 public void mouseClicked(MouseEvent e)
\r
180 //Only process single clicks
\r
181 if (e.getClickCount() > 1) return;
\r
183 final int col = tbl.getTableHeader().columnAtPoint(e.getPoint());
\r
184 if (col == COLUMN_FILENAME || col == COLUMN_FILESIZE ||
\r
185 col == COLUMN_FILEDATE)
\r
186 model.sort(col,tbl);
\r
193 /**************************************************************************
\r
194 * Finds the JTable in the panel so we can add MouseListener
\r
197 *************************************************************************/
\r
198 private final static JTable findJTable(Component[] comp)
\r
200 for (int i=0;i<comp.length;i++)
\r
202 if (comp[i] instanceof JTable)
\r
204 return (JTable)comp[i];
\r
206 if (comp[i] instanceof Container)
\r
208 JTable tbl = findJTable(((Container)comp[i]).getComponents());
\r
209 if (tbl != null) return tbl;
\r
216 /***************************************************************************
\r
217 * Implementation of BasicDirectoryModel that sorts the Files by column
\r
218 **************************************************************************/
\r
219 private final static class DirectoryModel extends BasicDirectoryModel
\r
224 /**************************************************************************
\r
225 * Must be overridden to extend BasicDirectoryModel
\r
227 *************************************************************************/
\r
228 DirectoryModel(JFileChooser chooser)
\r
234 /**************************************************************************
\r
235 * Supposedly this is not used anymore, hopefully not. We implemented
\r
236 * some basic attempt at sorting just in case
\r
240 *************************************************************************/
\r
241 protected final boolean lt(File a, File b)
\r
243 System.out.println("LT called?");
\r
244 boolean less = false;
\r
247 case COLUMN_FILEDATE:
\r
248 less = a.lastModified() > b.lastModified();
\r
250 case COLUMN_FILESIZE:
\r
251 less = a.length() > b.length();
\r
254 less = a.getName().compareToIgnoreCase(b.getName()) > 0;
\r
257 if (ascending) return less = !less;
\r
261 /**************************************************************************
\r
262 * Resorts the JFileChooser table based on new column
\r
264 *************************************************************************/
\r
265 protected final void sort(int c, JTable tbl)
\r
267 //Set column and order
\r
269 ascending = !ascending;
\r
270 String indicator = " (^)";
\r
272 indicator = " (v)";
\r
274 final JTableHeader th = tbl.getTableHeader();
\r
275 final TableColumnModel tcm = th.getColumnModel();
\r
277 for (int i=0;i<JalviewFileChooser.COLUMN_COLCOUNT;i++)
\r
279 final TableColumn tc = tcm.getColumn( i ); // the column to change
\r
280 tc.setHeaderValue( COLUMNS[i] );
\r
283 final TableColumn tc = tcm.getColumn( col ); // the column to change
\r
284 tc.setHeaderValue( COLUMNS[col] + indicator );
\r
288 //Requery the file listing
\r
289 validateFileCache();
\r
292 /**************************************************************************
\r
293 * Sorts the data based on current column setting
\r
295 *************************************************************************/
\r
296 protected final void sort(Vector data)
\r
300 case COLUMN_FILEDATE:
\r
301 Collections.sort(data,new Comparator(){
\r
302 public int compare(Object o1,Object o2)
\r
305 final File a = (File)o1;
\r
306 final File b = (File)o2;
\r
307 if (a.lastModified() > b.lastModified())
\r
309 else if (a.lastModified() == b.lastModified())
\r
319 case COLUMN_FILESIZE:
\r
320 Collections.sort(data,new Comparator(){
\r
321 public int compare(Object o1,Object o2)
\r
324 final File a = (File)o1;
\r
325 final File b = (File)o2;
\r
326 if (a.length() > b.length())
\r
328 else if (a.length() == b.length())
\r
338 case COLUMN_FILENAME:
\r
339 Collections.sort(data,new Comparator(){
\r
340 public int compare(Object o1,Object o2)
\r
342 final File a = (File)o1;
\r
343 final File b = (File)o2;
\r
345 return a.getName().compareToIgnoreCase(b.getName());
\r
347 return -1 * a.getName().compareToIgnoreCase(b.getName());
\r