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)
\r
37 JalviewFileFilter filter = new JalviewFileFilter(suffix, desc);
\r
38 this.setFileFilter(filter);
\r
42 public JalviewFileChooser(String dir)
\r
48 public int showSaveDialog(Component parent) throws HeadlessException {
\r
49 setDialogType(SAVE_DIALOG);
\r
50 int ret = showDialog(parent, null);
\r
52 if(ret == JalviewFileChooser.APPROVE_OPTION && getSelectedFile().exists() )
\r
54 int confirm = JOptionPane.showConfirmDialog(parent,
\r
55 "Overwrite existing file?",
\r
57 JOptionPane.YES_NO_OPTION);
\r
58 if(confirm!=JOptionPane.YES_OPTION)
\r
59 ret = this.CANCEL_OPTION;
\r
67 if (COLUMNS == null)
\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
80 /**************************************************************************
\r
81 * Always create the local UI
\r
83 *************************************************************************/
\r
84 public final void setUI(ComponentUI comp)
\r
86 super.setUI(new UI(this));
\r
89 /**************************************************************************
\r
90 * Internal implementation of Metal LookAndFeel to create the table sorting
\r
92 *************************************************************************/
\r
93 private final static class UI extends MetalFileChooserUI
\r
95 private DirectoryModel model;
\r
97 /**************************************************************************
\r
98 * Must be overridden to extend
\r
100 *************************************************************************/
\r
101 public UI(JFileChooser e)
\r
106 /**************************************************************************
\r
107 * Overridden to create our own model
\r
108 *************************************************************************/
\r
109 protected final void createModel()
\r
111 model = new DirectoryModel(getFileChooser());
\r
114 /**************************************************************************
\r
115 * Overridden to get our own model
\r
117 *************************************************************************/
\r
118 public final BasicDirectoryModel getModel() { return model; }
\r
120 /**************************************************************************
\r
121 * Calls the default method then adds a MouseListener to the JTable
\r
124 *************************************************************************/
\r
125 protected final JPanel createDetailsView(JFileChooser chooser)
\r
127 final JPanel panel = super.createDetailsView(chooser);
\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
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
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
142 //Only process single clicks
\r
143 if (e.getClickCount() > 1) return;
\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
155 /**************************************************************************
\r
156 * Finds the JTable in the panel so we can add MouseListener
\r
159 *************************************************************************/
\r
160 private final static JTable findJTable(Component[] comp)
\r
162 for (int i=0;i<comp.length;i++)
\r
164 if (comp[i] instanceof JTable)
\r
166 return (JTable)comp[i];
\r
168 if (comp[i] instanceof Container)
\r
170 JTable tbl = findJTable(((Container)comp[i]).getComponents());
\r
171 if (tbl != null) return tbl;
\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
186 /**************************************************************************
\r
187 * Must be overridden to extend BasicDirectoryModel
\r
189 *************************************************************************/
\r
190 DirectoryModel(JFileChooser chooser)
\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
202 *************************************************************************/
\r
203 protected final boolean lt(File a, File b)
\r
205 System.out.println("LT called?");
\r
206 boolean less = false;
\r
209 case COLUMN_FILEDATE:
\r
210 less = a.lastModified() > b.lastModified();
\r
212 case COLUMN_FILESIZE:
\r
213 less = a.length() > b.length();
\r
216 less = a.getName().compareToIgnoreCase(b.getName()) > 0;
\r
219 if (ascending) return less = !less;
\r
223 /**************************************************************************
\r
224 * Resorts the JFileChooser table based on new column
\r
226 *************************************************************************/
\r
227 protected final void sort(int c, JTable tbl)
\r
229 //Set column and order
\r
231 ascending = !ascending;
\r
232 String indicator = " (^)";
\r
234 indicator = " (v)";
\r
236 final JTableHeader th = tbl.getTableHeader();
\r
237 final TableColumnModel tcm = th.getColumnModel();
\r
239 for (int i=0;i<JalviewFileChooser.COLUMN_COLCOUNT;i++)
\r
241 final TableColumn tc = tcm.getColumn( i ); // the column to change
\r
242 tc.setHeaderValue( COLUMNS[i] );
\r
245 final TableColumn tc = tcm.getColumn( col ); // the column to change
\r
246 tc.setHeaderValue( COLUMNS[col] + indicator );
\r
250 //Requery the file listing
\r
251 validateFileCache();
\r
254 /**************************************************************************
\r
255 * Sorts the data based on current column setting
\r
257 *************************************************************************/
\r
258 protected final void sort(Vector data)
\r
262 case COLUMN_FILEDATE:
\r
263 Collections.sort(data,new Comparator(){
\r
264 public int compare(Object o1,Object o2)
\r
267 final File a = (File)o1;
\r
268 final File b = (File)o2;
\r
269 if (a.lastModified() > b.lastModified())
\r
271 else if (a.lastModified() == b.lastModified())
\r
281 case COLUMN_FILESIZE:
\r
282 Collections.sort(data,new Comparator(){
\r
283 public int compare(Object o1,Object o2)
\r
286 final File a = (File)o1;
\r
287 final File b = (File)o2;
\r
288 if (a.length() > b.length())
\r
290 else if (a.length() == b.length())
\r
300 case COLUMN_FILENAME:
\r
301 Collections.sort(data,new Comparator(){
\r
302 public int compare(Object o1,Object o2)
\r
304 final File a = (File)o1;
\r
305 final File b = (File)o2;
\r
307 return a.getName().compareToIgnoreCase(b.getName());
\r
309 return -1 * a.getName().compareToIgnoreCase(b.getName());
\r