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;
10 import java.util.function.Function;
12 import javax.swing.JFileChooser;
13 import javax.swing.JOptionPane;
14 import javax.swing.filechooser.FileSystemView;
17 * A simple Asynchronous file chooser for JavaScript and Java.
19 * Requires an OK runnable; JavaScript can return notification of cancel for
20 * file reading only, not saving.
25 public class AsyncFileChooser extends JFileChooser implements PropertyChangeListener {
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;
32 public AsyncFileChooser() {
36 public AsyncFileChooser(File file) {
40 public AsyncFileChooser(File file, FileSystemView view) {
46 public int showDialog(Component frame, String btnText) {
47 // This one can come from JFileChooser - default is OPEN
48 return super.showDialog(frame, btnText);
53 throw new java.lang.IllegalAccessException("Warning! AsyncFileChooser interface bypassed!");
54 } catch (IllegalAccessException e) {
57 return JFileChooser.ERROR_OPTION;
62 public int showOpenDialog(Component frame) {
67 public int showSaveDialog(Component frame) {
69 return super.showSaveDialog(frame);
75 * @param btnLabel "open" or "save"
77 * @param cancel must be null; JavaScript cannot capture a cancel from a file dialog
79 public void showDialog(Component frame, String btnLabel, Runnable ok, Runnable cancel) {
81 if (getDialogType() != JFileChooser.SAVE_DIALOG && cancel != null)
83 process(super.showDialog(frame, btnLabel));
90 * @param cancel must be null; JavaScript cannot capture a cancel from a file dialog
92 public void showOpenDialog(Component frame, Runnable ok, Runnable cancel) {
96 process(super.showOpenDialog(frame));
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.
106 * @param cancel must be null
108 public void showSaveDialog(Component frame, Runnable ok, Runnable cancel) {
110 this.cancel = cancel;
111 process(super.showSaveDialog(frame));
116 * Locate a file for input or output. Note that JavaScript will not return on cancel for OPEN_DIALOG.
118 * @param title The title for the dialog
119 * @param mode OPEN_DIALOG or SAVE_DIALOG
120 * @param processFile function to use when complete
122 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 AsyncFileChooser fc = new AsyncFileChooser();
127 fc.setDialogTitle(title);
128 Runnable after = new Runnable() {
132 processFile.apply(fc.getSelectedFile());
136 if (mode == JFileChooser.OPEN_DIALOG) {
137 fc.showOpenDialog(parent, after, after);
139 fc.showSaveDialog(parent, after, after);
145 * Run yes.run() if a file doesn't exist or if the user allows it, else run no.run()
149 * @param yes (approved)
150 * @param no (optional)
152 public static void checkReplaceFileAsync(Component parent, File outfile, String title, Runnable yes, Runnable no) {
153 if (outfile.exists()) {
154 AsyncDialog.showYesNoAsync(parent,
155 outfile + " exists. Replace it?", null, new ActionListener() {
158 public void actionPerformed(ActionEvent e) {
160 case JOptionPane.YES_OPTION:
178 private void notifyCancel() {
180 System.err.println("developer note: JavaScript cannot fire a FileChooser CANCEL action");
186 public void propertyChange(PropertyChangeEvent evt) {
187 switch (evt.getPropertyName()) {
189 case "SelectedFiles":
190 process(optionSelected = (evt.getNewValue() == null ? CANCEL_OPTION : APPROVE_OPTION));
195 private void process(int ret) {
197 return; // initial JavaScript return is NaN
198 optionSelected = ret;
199 File f = getSelectedFile();
209 public int getSelectedOption() {
210 return optionSelected;
213 public static byte[] getFileBytes(File f) {
214 return /** @j2sNative f.秘bytes || */null;