Skip to content

Commit e881b34

Browse files
committed
adds test/async package and fixes
- JFileChooser missing constructors - JOptionPane missing options passing - JSFrameUI not waiting for focus zindex - Window missing (Frame) constructor
1 parent 9a6547a commit e881b34

File tree

7 files changed

+298
-69
lines changed

7 files changed

+298
-69
lines changed

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

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
Notes
22
=====
3+
4+
updated 11/03/19 -- adds information about File.exists() and points to src/test/async
35
updated 10/26/19 -- adds information about File.createTempFile()
46
updated 8/16/19 -- minor typos and added summary paragraph
57
updated 7/19/19 -- clarification that AWT and Swing classes are supported directly
@@ -147,7 +149,7 @@ Modal Dialogs
147149
Although true modal dialogs are not possible with only one thread, a functional equivalent --
148150
asynchronous modal dialogs -- is relatively easy to set up. All the JOptionPane dialogs will
149151
return PropertyChangeEvents to signal that they have been disposed of and containing the results.
150-
More on this later....
152+
See below.
151153

152154

153155
Native calls
@@ -234,12 +236,22 @@ a2s components, which in turn subclass JComponents. So no changes in code are ne
234236
successfully transpiled over 500 applets using this strategy. (Kind of surprising, actually, that
235237
the original Java developers did not see that option. But we have a hindsight advantage here.)
236238

237-
Temporary Files
238-
===============
239+
Working with Files
240+
==================
241+
242+
SwingJS will always return File.exists() == true. If this is being tested, provide a J2sNative
243+
block that gives an appropriate "OK" message, for example:
244+
245+
(/** @j2sNative 1 ? false : */ outputfile.exits())
246+
247+
or
248+
249+
(/** @j2sNative 1 ? true : */ inputfile.exits())
250+
251+
Temporary files can be created in SwingJS. SwingJS will maintain a pseudo-filesystem for files
252+
created with File.createTempFile(). This is useful in that closure of writing to a temporary file
253+
does not generate a pseudo-download to the user's machine.
239254

240-
SwingJS will maintain a pseudo-filesystem for files created with File.createTempFile(). This
241-
is useful in that closure of writing to the file does not generate a download to the user's
242-
machine (which typically requires user intervention).
243255

244256
UNIMPLEMENTED CLASSES BY DESIGN
245257
===============================
@@ -466,12 +478,20 @@ It's a simple modification:
466478
System.out.println("int value is " + value);
467479
}
468480

481+
482+
Developers are encouraged to create a separate class that handles general calls to JFileDialog.
483+
An example class can be found in the SwingJS distribution as
484+
485+
/sources/net.sf.j2s.java.core/src/test/async/AsyncFileChooser.java.
486+
487+
469488
javax.swing.JOptionPane dialogs
470489
-------------------------------
471490

472491
For this action to work, the parentComponent must implement
473492
propertyChangeListener, and any call to JOptionPanel should allow for
474-
asynchronous response.
493+
an asynchronous response, meaning that there is no actionable code following the
494+
call to the dialog opening.
475495

476496
In addition, for compatibility with the Java version, implementation should
477497
wrap the call to getConfirmDialog or getOptionDialog in a method call to
@@ -490,12 +510,12 @@ Note that there is an int and an Object version of onDialogReturn().
490510
In JavaScript:
491511

492512
The initial return from JOptionPane.showConfirmDialog and showMessageDialog
493-
will be NaN, testable as an impossible Java int value using ret !=
494-
Math.floor(ret) if the parent implements PropertyChangeListeneer, or -1
513+
will be (SwingJS) JDialog.ASYNCHRONOUS_INTEGER (NaN), testable as an impossible
514+
Java int value using ret != -(-ret) if the parent implements PropertyChangeListener, or -1
495515
(CLOSE_OPTION) if not.
496516

497517
For showOptionDialog (which returns Object) or showInputDialog (which returns
498-
String), the initial return will be JDialog.ASYNCHRONOUS_OBJECT, testable as
518+
String), the initial return will be (SwingJS) JDialog.ASYNCHRONOUS_OBJECT, testable as
499519
((Object) ret) instanceof javax.swing.plaf.UIResource if the parent implements
500520
PropertyChangeListeneer, or null if not.
501521

@@ -514,7 +534,7 @@ All of the standard Java events associated with Components are also
514534
available.
515535

516536
Certain fall back mechanisms are possible, where onReturn does not exist, but
517-
only for the falling cases:
537+
only for the following cases:
518538

519539

520540
For showMessageDialog, for WARNING_MESSAGE and ERROR_MESSAGE, a simple
@@ -535,8 +555,8 @@ Note that you should implement a response for CLOSED_OPTION for
535555
showConfirmDialog. For other dialogs, a null return indicates the dialog was
536556
closed, just as for Java.
537557

538-
539-
558+
Developers are encouraged to create a separate class that handles general calls.
559+
An example class can be found in the SwingJS distribution as src/test/async/AsyncDialog.java.
540560

541561
native methods
542562
--------------

sources/net.sf.j2s.java.core/src/java/awt/Window.java

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -448,36 +448,35 @@ public void setTrayIconWindow(boolean isTrayIconWindow) {
448448
}
449449

450450

451-
// /**
452-
// * This was never ever any use, since Frame subclasses Window
453-
// *
454-
// * Constructs a new, initially invisible window with the specified
455-
// * <code>Frame</code> as its owner. The window will not be focusable unless
456-
// * its owner is showing on the screen.
457-
// * <p>
458-
// * If there is a security manager, this method first calls the security
459-
// * manager's <code>checkTopLevelWindow</code> method with <code>this</code> as
460-
// * its argument to determine whether or not the window must be displayed with
461-
// * a warning banner.
462-
// *
463-
// * @param owner
464-
// * the <code>Frame</code> to act as owner or <code>null</code> if
465-
// * this window has no owner
466-
// * @exception IllegalArgumentException
467-
// * if the <code>owner</code>'s <code>GraphicsConfiguration</code>
468-
// * is not from a screen device
469-
// * @exception HeadlessException
470-
// * when <code>GraphicsEnvironment.isHeadless</code> returns
471-
// * <code>true</code>
472-
// *
473-
// * @see java.awt.GraphicsEnvironment#isHeadless
474-
// * @see java.lang.SecurityManager#checkTopLevelWindow
475-
// * @see #isShowing
476-
// *
477-
// */
478-
// public Window(Frame owner) {
479-
// this(owner, null);
480-
// }
451+
/**
452+
*
453+
* Constructs a new, initially invisible window with the specified
454+
* <code>Frame</code> as its owner. The window will not be focusable unless
455+
* its owner is showing on the screen.
456+
* <p>
457+
* If there is a security manager, this method first calls the security
458+
* manager's <code>checkTopLevelWindow</code> method with <code>this</code> as
459+
* its argument to determine whether or not the window must be displayed with
460+
* a warning banner.
461+
*
462+
* @param owner
463+
* the <code>Frame</code> to act as owner or <code>null</code> if
464+
* this window has no owner
465+
* @exception IllegalArgumentException
466+
* if the <code>owner</code>'s <code>GraphicsConfiguration</code>
467+
* is not from a screen device
468+
* @exception HeadlessException
469+
* when <code>GraphicsEnvironment.isHeadless</code> returns
470+
* <code>true</code>
471+
*
472+
* @see java.awt.GraphicsEnvironment#isHeadless
473+
* @see java.lang.SecurityManager#checkTopLevelWindow
474+
* @see #isShowing
475+
*
476+
*/
477+
public Window(Frame owner) {
478+
this(owner, null);
479+
}
481480

482481
/**
483482
* Constructs a new, initially invisible window with the specified

sources/net.sf.j2s.java.core/src/javax/swing/JFileChooser.java

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@
2929
import java.awt.BorderLayout;
3030
import java.awt.Component;
3131
import java.awt.Container;
32-
import java.awt.JSDialog;
3332
import java.awt.EventQueue;
34-
import java.awt.JSFrame;
3533
import java.awt.HeadlessException;
34+
import java.awt.JSDialog;
35+
import java.awt.JSFrame;
3636
import java.awt.Toolkit;
3737
import java.awt.Window;
3838
import java.awt.event.ActionEvent;
@@ -44,15 +44,13 @@
4444
import java.io.File;
4545
//import java.lang.ref.WeakReference;
4646
import java.util.ArrayList;
47-
import java.util.Map;
4847

4948
import javax.swing.event.EventListenerList;
5049
import javax.swing.filechooser.FileFilter;
50+
import javax.swing.filechooser.FileSystemView;
5151
//import javax.swing.filechooser.FileSystemView;
5252
import javax.swing.filechooser.FileView;
5353

54-
import javajs.api.JSFunction;
55-
import swingjs.JSToolkit;
5654
import swingjs.JSUtil;
5755

5856

@@ -368,23 +366,23 @@ public String getUIClassID() {
368366
}
369367

370368

371-
// /**
372-
// * Constructs a <code>JFileChooser</code> using the given
373-
// * <code>FileSystemView</code>.
374-
// */
375-
// public JFileChooser(FileSystemView fsv) {
376-
// this((File) null, fsv);
377-
// }
378-
//
369+
/**
370+
* Constructs a <code>JFileChooser</code> using the given
371+
* <code>FileSystemView</code>.
372+
*/
373+
public JFileChooser(FileSystemView fsv) {
374+
this((File) null, fsv);
375+
}
379376

380-
// /**
381-
// * Constructs a <code>JFileChooser</code> using the given current directory
382-
// * and <code>FileSystemView</code>.
383-
// */
384-
// public JFileChooser(File currentDirectory, FileSystemView fsv) {
385-
// setup(fsv);
386-
// setCurrentDirectory(currentDirectory);
387-
// }
377+
378+
/**
379+
* Constructs a <code>JFileChooser</code> using the given current directory
380+
* and <code>FileSystemView</code>.
381+
*/
382+
public JFileChooser(File currentDirectory, FileSystemView fsv) {
383+
//setup(fsv);
384+
setCurrentDirectory(currentDirectory);
385+
}
388386

389387
// /**
390388
// * Constructs a <code>JFileChooser</code> using the given current directory
@@ -782,7 +780,7 @@ public int showDialog(Component parent, String approveButtonText) {
782780
removePropertyChangeListener((PropertyChangeListener) parent);
783781
addPropertyChangeListener((PropertyChangeListener) parent);
784782
}
785-
Runnable r = new Runnable() {
783+
@SuppressWarnings("unused") Runnable r = new Runnable() {
786784

787785
@Override
788786
public void run() {

sources/net.sf.j2s.java.core/src/javax/swing/JOptionPane.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -927,7 +927,7 @@ public static int showConfirmDialog(Component parentComponent, Object message, S
927927
}
928928
}
929929

930-
return showOptionDialog(parentComponent, message, title, optionType, messageType, icon, null, null);
930+
return showOptionDialog(parentComponent, message, title, optionType, messageType, icon, options, null);
931931
}
932932

933933
/**

sources/net.sf.j2s.java.core/src/swingjs/plaf/JSFrameUI.java

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import java.awt.Insets;
66
import java.awt.Rectangle;
77
import java.awt.Toolkit;
8+
import java.awt.event.ActionEvent;
9+
import java.awt.event.ActionListener;
810
import java.awt.event.ComponentEvent;
911
import java.awt.event.WindowEvent;
1012
import java.awt.peer.FramePeer;
@@ -13,6 +15,8 @@
1315
import javax.swing.JComponent;
1416
import javax.swing.JFrame;
1517
import javax.swing.LookAndFeel;
18+
import javax.swing.SwingUtilities;
19+
import javax.swing.Timer;
1620

1721
import javajs.api.JSFunction;
1822
import swingjs.api.js.DOMNode;
@@ -276,8 +280,6 @@ public boolean handleJSEvent(Object target, int eventType, Object jQueryEvent) {
276280
switch (/** @j2sNative jQueryEvent.type || */
277281
"") {
278282
case "click":
279-
DOMNode tbar = titleBarNode;
280-
J2S.setDraggable(tbar, false);
281283
frameCloserAction();
282284
return HANDLED;
283285
case "mouseout":
@@ -292,10 +294,31 @@ public boolean handleJSEvent(Object target, int eventType, Object jQueryEvent) {
292294
}
293295

294296
protected void frameCloserAction() {
295-
frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
297+
// We use a timer so that all the focus-related window zindex business is done first,
298+
// in case a custom close-option dialog is thrown up.
299+
Timer t = new Timer(100, new ActionListener() {
300+
301+
@Override
302+
public void actionPerformed(ActionEvent e) {
303+
frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
304+
}
305+
306+
});
307+
t.setRepeats(false);
308+
t.start();
296309
}
297310

298311
protected void closeFrame() {
312+
DOMNode tbar = titleBarNode;
313+
/**
314+
* @j2sNative
315+
*
316+
* J2S.setDraggable(tbar, false);
317+
*/
318+
{
319+
// but "false" here will become Boolean.FALSE
320+
J2S.setDraggable(tbar, false);
321+
}
299322
J2S.unsetMouse(frameNode);
300323
$(frameNode).remove();
301324
$(outerNode).remove();

0 commit comments

Comments
 (0)