Clover icon

Coverage Report

  1. Project Clover database Thu Dec 4 2025 16:11:35 GMT
  2. Package javajs.async

File AsyncFileChooser.java

 

Coverage histogram

../../img/srcFileCovDistChart0.png
60% of files have more coverage

Code metrics

22
59
19
1
217
136
35
0.59
3.11
19
1.84

Classes

Class Line # Actions
AsyncFileChooser 25 59 35
0.00%
 

Contributing tests

No tests hitting this source file were found.

Source view

1    package javajs.async;
2   
3   
4    import java.awt.Component;
5    import java.awt.event.ActionEvent;
6    import java.awt.event.ActionListener;
7    import java.beans.PropertyChangeEvent;
8    import java.beans.PropertyChangeListener;
9    import java.io.File;
10    import java.util.function.Function;
11   
12    import javax.swing.JFileChooser;
13    import javax.swing.JOptionPane;
14    import javax.swing.filechooser.FileSystemView;
15   
16    /**
17    * A simple Asynchronous file chooser for JavaScript and Java.
18    *
19    * Requires an OK runnable; JavaScript can return notification of cancel for
20    * file reading only, not saving.
21    *
22    * @author Bob Hanson
23    */
24   
 
25    public class AsyncFileChooser extends JFileChooser implements PropertyChangeListener {
26   
27    private int optionSelected;
28    private Runnable ok, cancel; // sorry, no CANCEL in JavaScript for file open
29    private boolean isAsyncSave = true;
30    private static boolean notified;
31   
 
32  0 toggle public AsyncFileChooser() {
33  0 super();
34    }
35   
 
36  0 toggle public AsyncFileChooser(File file) {
37  0 super(file);
38    }
39   
 
40  0 toggle public AsyncFileChooser(File file, FileSystemView view) {
41  0 super(file, view);
42    }
43   
 
44  0 toggle @Deprecated
45    @Override
46    public int showDialog(Component frame, String btnText) {
47    // This one can come from JFileChooser - default is OPEN
48  0 return super.showDialog(frame, btnText);
49    }
50   
 
51  0 toggle private int err() {
52  0 try {
53  0 throw new java.lang.IllegalAccessException("Warning! AsyncFileChooser interface bypassed!");
54    } catch (IllegalAccessException e) {
55  0 e.printStackTrace();
56    }
57  0 return JFileChooser.ERROR_OPTION;
58    }
59   
 
60  0 toggle @Deprecated
61    @Override
62    public int showOpenDialog(Component frame) {
63  0 return err();
64    }
65   
 
66  0 toggle @Override
67    public int showSaveDialog(Component frame) {
68  0 isAsyncSave = false;
69  0 return super.showSaveDialog(frame);
70    }
71   
72    /**
73    *
74    * @param frame
75    * @param btnLabel "open" or "save"
76    * @param ok
77    * @param cancel must be null; JavaScript cannot capture a cancel from a file dialog
78    */
 
79  0 toggle public void showDialog(Component frame, String btnLabel, Runnable ok, Runnable cancel) {
80  0 this.ok = ok;
81  0 if (getDialogType() != JFileChooser.SAVE_DIALOG && cancel != null)
82  0 notifyCancel();
83  0 process(super.showDialog(frame, btnLabel));
84    }
85   
86    /**
87    *
88    * @param frame
89    * @param ok
90    * @param cancel must be null; JavaScript cannot capture a cancel from a file dialog
91    */
 
92  0 toggle public void showOpenDialog(Component frame, Runnable ok, Runnable cancel) {
93  0 this.ok = ok;
94  0 if (cancel != null)
95  0 notifyCancel();
96  0 process(super.showOpenDialog(frame));
97    }
98   
99    /**
100    *
101    * This just completes the set. It is not necessary for JavaScript, because JavaScript
102    * will just throw up a simple modal OK/Cancel message anyway.
103    *
104    * @param frame
105    * @param ok
106    * @param cancel must be null
107    */
 
108  0 toggle public void showSaveDialog(Component frame, Runnable ok, Runnable cancel) {
109  0 this.ok = ok;
110  0 this.cancel = cancel;
111  0 process(super.showSaveDialog(frame));
112    }
113   
114   
115    /**
116    * Locate a file for input or output. Note that JavaScript will not return on cancel for OPEN_DIALOG.
117    *
118    * @param title The title for the dialog
119    * @param mode OPEN_DIALOG or SAVE_DIALOG
120    * @param processFile function to use when complete
121    */
 
122  0 toggle public static void getFileAsync(Component parent, String title, int mode, Function<File, Void> processFile) {
123    // BH no references to this method. So changing its signature for asynchonous use
124    // And it didn't do as advertised - ran System.exit(0) if canceled
125    // create and display a file dialog
126  0 AsyncFileChooser fc = new AsyncFileChooser();
127  0 fc.setDialogTitle(title);
128  0 Runnable after = new Runnable() {
129   
 
130  0 toggle @Override
131    public void run() {
132  0 processFile.apply(fc.getSelectedFile());
133    }
134   
135    };
136  0 if (mode == JFileChooser.OPEN_DIALOG) {
137  0 fc.showOpenDialog(parent, after, after);
138    } else {
139  0 fc.showSaveDialog(parent, after, after);
140    }
141   
142    }
143   
144    /**
145    * Run yes.run() if a file doesn't exist or if the user allows it, else run no.run()
146    * @param parent
147    * @param filename
148    * @param title
149    * @param yes (approved)
150    * @param no (optional)
151    */
 
152  0 toggle public static void checkReplaceFileAsync(Component parent, File outfile, String title, Runnable yes, Runnable no) {
153  0 if (outfile.exists()) {
154  0 AsyncDialog.showYesNoAsync(parent,
155    outfile + " exists. Replace it?", null, new ActionListener() {
156   
 
157  0 toggle @Override
158    public void actionPerformed(ActionEvent e) {
159  0 switch (e.getID()) {
160  0 case JOptionPane.YES_OPTION:
161  0 yes.run();
162  0 break;
163  0 default:
164  0 if (no != null)
165  0 no.run();
166  0 break;
167    }
168    }
169   
170    });
171   
172    } else {
173  0 yes.run();
174    }
175   
176    }
177   
 
178  0 toggle private void notifyCancel() {
179  0 if (!notified) {
180  0 System.err.println("developer note: JavaScript cannot fire a FileChooser CANCEL action");
181    }
182  0 notified = true;
183    }
184   
 
185  0 toggle @Override
186    public void propertyChange(PropertyChangeEvent evt) {
187  0 switch (evt.getPropertyName()) {
188  0 case "SelectedFile":
189  0 case "SelectedFiles":
190  0 process(optionSelected = (evt.getNewValue() == null ? CANCEL_OPTION : APPROVE_OPTION));
191  0 break;
192    }
193    }
194   
 
195  0 toggle private void process(int ret) {
196  0 if (ret != -(-ret))
197  0 return; // initial JavaScript return is NaN
198  0 optionSelected = ret;
199  0 File f = getSelectedFile();
200  0 if (f == null) {
201  0 if (cancel != null)
202  0 cancel.run();
203    } else {
204  0 if (ok != null)
205  0 ok.run();
206    }
207    }
208   
 
209  0 toggle public int getSelectedOption() {
210  0 return optionSelected;
211    }
212   
 
213  0 toggle public static byte[] getFileBytes(File f) {
214  0 return /** @j2sNative f.秘bytes || */null;
215    }
216   
217    }