Skip to content

Commit fd1b1c3

Browse files
committed
javajs.async package
Async AsyncFileChooser AsyncDialog AsyncColorChooser better modal blocking for Chrome and AsyncFileChooser
1 parent f2dc5af commit fd1b1c3

File tree

14 files changed

+269
-100
lines changed

14 files changed

+269
-100
lines changed
5.27 KB
Binary file not shown.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
20191107021431
1+
20191107100616
5.27 KB
Binary file not shown.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
20191107021431
1+
20191107100616
5.27 KB
Binary file not shown.

sources/net.sf.j2s.java.core/doc/Differences.txt

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ be done in UTF-8. This means:
99
- making sure your Exclipse project is set up for UTF-8 (not the Eclipse default?)
1010
- making sure your server can serve up UTF-8 by default for any browser-loaded files
1111
- making sure you don't edit a Java2Script class file or one of the site .js files
12-
using a non-UTF-8 editor. It may replace non-Latin characters with "?" or garbage.
13-
- making sure that your web pages are delivered with
12+
using a non-UTF-8 editor. It may replace non-Latin characters with "?" or garbage.
13+
- making sure that your web pages are delivered with proper headings indicating HTML5 and UTF-8
1414

1515
<!DOCTYPE html>
1616
<html>
@@ -32,7 +32,7 @@ ever be overridden by subclasses. As in java.lang.Thread.java:
3232
----------------------------------
3333

3434

35-
updated 11/03/19 -- adds information about File.exists() and points to src/test/async
35+
updated 11/03/19 -- adds information about File.exists() and points to src/javajs/async
3636
updated 10/26/19 -- adds information about File.createTempFile()
3737
updated 8/16/19 -- minor typos and added summary paragraph
3838
updated 7/19/19 -- clarification that AWT and Swing classes are supported directly
@@ -173,14 +173,43 @@ myclass.xxx in Java (and JavaScript).
173173

174174
This was done extensively in the Jalview project. See jalview.bin.Instance.
175175

176+
Helper Packages -- swingjs/ and javajs/
177+
---------------------------------------
178+
179+
The SwingJS library is the swingjs/ package. There are interfaces that may be of assistance
180+
in swingjs/api, but other than that, it is not recommended that developers access classes in
181+
this package. The "public" nature of their methods is really an internal necessity.
182+
183+
In addition to swingjs/, though, there are several useful classes in the javajs/ package
184+
that could be very useful. This package is a stand-alone package that can be
185+
cloned in any Java project that also would be great to have in any JavaScript project
186+
-- SwingJS-related or not. Functionality ranges from reading and writing various file
187+
formats, including PDF, BMP, PNG, GIF, JPG, JSON, ZIP, and CompoundDocument formats.
188+
189+
A variety of highly efficient three- and four-dimensional point, vector, matrix, and
190+
quaternion classes are included, as they were developed for JSmol and inherited from that
191+
project.
192+
193+
Of particular interest should be javajs/async/, which includes
194+
195+
javajs.async.Async
196+
javajs.async.AsyncColorChooser
197+
javajs.async.AsyncDialog
198+
javajs.async.AsyncFileChooser
199+
200+
See javajs.async.Async JavaDoc comments for a full description of
201+
these useful classes.
202+
203+
204+
176205

177206
Modal Dialogs
178207
-------------
179208

180209
Although true modal dialogs are not possible with only one thread, a functional equivalent --
181210
asynchronous modal dialogs -- is relatively easy to set up. All the JOptionPane dialogs will
182211
return PropertyChangeEvents to signal that they have been disposed of and containing the results.
183-
See below.
212+
See below and classes in the javajs.async package.
184213

185214

186215
Native calls
@@ -555,7 +584,7 @@ It's a simple modification:
555584
Developers are encouraged to create a separate class that handles general calls to JFileDialog.
556585
An example class can be found in the SwingJS distribution as
557586

558-
/sources/net.sf.j2s.java.core/src/test/async/AsyncFileChooser.java.
587+
/sources/net.sf.j2s.java.core/src/javajs/async/AsyncFileChooser.java.
559588

560589

561590
javax.swing.JOptionPane dialogs
@@ -629,7 +658,7 @@ showConfirmDialog. For other dialogs, a null return indicates the dialog was
629658
closed, just as for Java.
630659

631660
Developers are encouraged to create a separate class that handles general calls.
632-
An example class can be found in the SwingJS distribution as src/test/async/AsyncDialog.java.
661+
An example class can be found in the SwingJS distribution as src/javajs/async/AsyncDialog.java.
633662
Very simple modifications to the Java allows asynchronous operation using AsyncDialog. Here
634663
is a simple "do you want to close this frame" example, where you can see that what we have
635664
done is to set the reply into an ActionListener that is defined in the constructor of

sources/net.sf.j2s.java.core/src/java/lang/ThreadGroup.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class ThreadGroup implements Thread.UncaughtExceptionHandler {
7777

7878
private int ngroups;
7979
private ThreadGroup groups[];
80-
protected HTML5Applet 秘html5Applet;
80+
public HTML5Applet 秘html5Applet;
8181
public boolean 秘systemExited;
8282
public JSAppletViewer 秘appletViewer;
8383

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
package javajs.async;
2+
3+
import java.awt.Color;
4+
import java.awt.Component;
5+
import java.awt.event.ActionListener;
6+
7+
/**
8+
* A class to manage asynchronous aspects of SwingJS
9+
*
10+
* The javajs.async package simplifies the production of methods that can be
11+
* used equally well in Java and in JavaScript for handling "pseudo-modal"
12+
* blocking in JavaScript, meaning the user is locked out of other interactions,
13+
* as in Java, but the code is not actually blocking the thread.
14+
*
15+
* Included in this package are
16+
*
17+
* Async
18+
*
19+
* Provides few simple generic static methods.
20+
*
21+
* Async.isJS() -- true if we are running this in JavaScript
22+
*
23+
* Async.javaSleep() -- bypassing Thread.sleep() for JavaScript; allowing it for
24+
* Java
25+
*
26+
*
27+
* AsyncDialog
28+
*
29+
* Provides several very useful methods that act as a replacement for direct
30+
* JOptionPane or JDialog calls, including both a synchronous callback
31+
* (manifested in Java) and an asynchronous callback (JavaScript), both
32+
* resulting in the same effect, except for the fact that the JavaScript code
33+
* has returned immediately from the call with an "ignore me" reference, while
34+
* Java is waiting at that call to return a value from JOptionPane (which is
35+
* saved by AsyncDialog and not delivered as a return value).
36+
*
37+
* AsyncDialog does not extend JOptionPane, but it mirrors that classes public
38+
* methods. There are a LOT of public methods in JOPtionPane. I suppose we
39+
* should implement them all. In practice, AsyncDialog calls standard
40+
* JOptionPane static classes for the dialogs.
41+
*
42+
* Initially, the following methods are implemented:
43+
*
44+
* public void showConfirmDialog(Component frame, Object message, String title,
45+
* ActionListener a)
46+
*
47+
* public void showConfirmDialog(Component frame, Object message, String title,
48+
* int optionType, ActionListener a)
49+
*
50+
* public void showConfirmDialog(Component frame, Object message, String title,
51+
* int optionType, int messageType, ActionListener a)
52+
*
53+
* public void showInputDialog(Component frame, Object message, ActionListener
54+
* a)
55+
*
56+
* public void showInputDialog(Component frame, Object message, String title,
57+
* int messageType, Icon icon, Object[] selectionValues, Object
58+
* initialSelectionValue, ActionListener a)
59+
*
60+
* public void showMessageDialog(Component frame, Object message, ActionListener
61+
* a)
62+
*
63+
* public void showOptionDialog(Component frame, Object message, String title,
64+
* int optionType, int messageType, Icon icon, Object[] options, Object
65+
* initialValue, ActionListener a)
66+
*
67+
*
68+
* All nonstatic methods, requiring new AsyncDialog(), also require an
69+
* ActionListener. This listener will get a call to actionPerformed(ActionEvent)
70+
* where:
71+
*
72+
* event.getSource() is a reference to the originating AsyncDialog (super
73+
* JOptionPane) for all information that a standard JOptionPane can provide,
74+
* along with the two methods int getOption() and Object getChoice().
75+
*
76+
* event.getID() is a reference to the standard JOptionPane int return code.
77+
*
78+
* event.getActionCommand() also holds a value, but it may or may not be of
79+
* value.
80+
*
81+
*
82+
* A few especially useful methods are static, allowing just one or two expected
83+
* callbacks of interest:
84+
*
85+
* AsyncDialog.showOKAsync(Component parent, Object message, String title,
86+
* Runnable ok)
87+
*
88+
* AsyncDialog.showYesAsync (Component parent, Object message, String title,
89+
* Runnable yes)
90+
*
91+
* AsyncDialog.showYesNoAsync (Component parent, Object message, String title,
92+
* Runnable yes, Runnable no)
93+
*
94+
* These methods provide a fast way to adjust JOptionPane calls to be
95+
* asynchronous.
96+
*
97+
*
98+
*
99+
* AsyncFileChooser extends javax.swing.JFileChooser
100+
*
101+
* Accepted constructors include:
102+
*
103+
* public AsyncFileChooser()
104+
*
105+
* public AsyncFileChooser(File file)
106+
*
107+
* public AsyncFileChooser(File file, FileSystemView view)
108+
*
109+
* (Note, however, that FileSystemView has no equivalent in JavaScript.)
110+
*
111+
* It's three public methods include:
112+
*
113+
* public void showDialog(Component frame, String btnLabel, Runnable ok,
114+
* Runnable cancel)
115+
*
116+
* public void showOpenDialog(Component frame, Runnable ok, Runnable cancel)
117+
*
118+
* public void showSaveDialog(Component frame, Runnable ok, Runnable cancel)
119+
*
120+
*
121+
* ActionListener is not needed here, as the instance of new AsyncFileChooser()
122+
* already has direct access to all the JFileChooser public methods such as
123+
* getSelectedFile() and getSelectedFiles().
124+
*
125+
* As a subclass of JFileChooser, it accepts all three public showXXXX methods
126+
* of JFileChooser, namely:
127+
*
128+
* public void showDialog(Component frame, String btnLabel)
129+
*
130+
* public void showOpenDialog(Component frame)
131+
*
132+
* public void showSaveDialog(Component frame)
133+
*
134+
*
135+
* None of these are recommended. AsyncFileChooser will indicate errors if the
136+
* first of these two are called. (showSaveDialog is fine, as it is modal even
137+
* in JavaScript. However it is not recommended that showSaveDialog(Component
138+
* frame) be used, as in the future browsers may implement some sort of file
139+
* saver in HTML5.
140+
*
141+
*
142+
*
143+
* AsyncColorChooser
144+
*
145+
*
146+
* AsyncColorChooser accesses JColorChooser asynchronously, using a private
147+
* SwingJS setting that tells JColorChooser to report back to it with property
148+
* changes. It is constructed using new AsyncColorChooser() and implements just
149+
* two methods:
150+
*
151+
* public void showDialog(Component component, String title, Color initialColor,
152+
* ActionListener listener)
153+
*
154+
* public Color getSelectedColor()
155+
*
156+
*
157+
* The listener will get an actionPerformed(ActionEvent) callback with
158+
* event.getID() equal to the color value or 0 if canceled. The
159+
* getSelectedColor() method may also be called from this callback to retrieve
160+
* the associated java.awt.Color object, using
161+
*
162+
* ((AsyncColorChooser)e.getSource()).getSelectedColor()
163+
*
164+
* As in Java, a null value for the selected color indicates that the
165+
* JColorChooser was closed.
166+
*
167+
* Bob Hanson 2019.11.07
168+
*
169+
*
170+
* @author Bob Hanson hansonr_at_stolaf.edu
171+
*
172+
*/
173+
public class Async {
174+
175+
public static boolean isJS() {
176+
return (/** @j2sNative 1 ? true : */false);
177+
}
178+
179+
/**
180+
* No sleep in JavaScript
181+
* @param ms
182+
*/
183+
public static void javaSleep(int ms) {
184+
if (!isJS()) {
185+
try {
186+
Thread.sleep(ms);
187+
} catch (InterruptedException e) {
188+
}
189+
}
190+
191+
}
192+
193+
}

sources/net.sf.j2s.java.core/src/test/async/AsyncColorChooser.java renamed to sources/net.sf.j2s.java.core/src/javajs/async/AsyncColorChooser.java

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,13 @@
1-
package test.async;
1+
package javajs.async;
22

33
import java.awt.Color;
44
import java.awt.Component;
55
import java.awt.event.ActionEvent;
66
import java.awt.event.ActionListener;
7-
import java.awt.event.WindowEvent;
8-
import java.awt.event.WindowListener;
97
import java.beans.PropertyChangeEvent;
108
import java.beans.PropertyChangeListener;
11-
import java.io.File;
129

1310
import javax.swing.JColorChooser;
14-
import javax.swing.JFileChooser;
15-
import javax.swing.colorchooser.ColorSelectionModel;
16-
import javax.swing.event.ChangeEvent;
17-
import javax.swing.event.ChangeListener;
18-
import javax.swing.filechooser.FileSystemView;
1911
import javax.swing.plaf.UIResource;
2012

2113
/**
@@ -37,16 +29,11 @@ public void showDialog(Component component, String title, Color initialColor, Ac
3729
unsetListener();
3830
}
3931

40-
private void setListener(ActionListener a) {
41-
listener = a;
42-
/** @j2sNative Clazz.loadClass("javax.swing.JColorChooser");javax.swing.JColorChooser.listener = this */
32+
public Color getSelectedColor() {
33+
return selectedColor;
4334
}
4435

45-
private void unsetListener() {
46-
/** @j2sNative javax.swing.JColorChooser.listener = null */
47-
}
4836

49-
5037
@Override
5138
public void propertyChange(PropertyChangeEvent evt) {
5239
// JavaScript only
@@ -59,6 +46,16 @@ public void propertyChange(PropertyChangeEvent evt) {
5946
}
6047
}
6148

49+
private void setListener(ActionListener a) {
50+
listener = a;
51+
/** @j2sNative Clazz.loadClass("javax.swing.JColorChooser");javax.swing.JColorChooser.listener = this */
52+
}
53+
54+
private void unsetListener() {
55+
/** @j2sNative javax.swing.JColorChooser.listener = null */
56+
}
57+
58+
6259

6360
private void process(Color c) {
6461
if (c instanceof UIResource)
@@ -67,9 +64,4 @@ private void process(Color c) {
6764
listener.actionPerformed(new ActionEvent(this, c == null ? 0 : c.getRGB(), c == null ? null : c.toString()));
6865
}
6966

70-
public Color getSelectedColor() {
71-
return selectedColor;
72-
}
73-
74-
7567
}

0 commit comments

Comments
 (0)