Index: swingjs/README.txt
===================================================================
diff -u -N
--- swingjs/README.txt (revision 9fc58cdcb5f7c768aabc2c73b754cf3c444bd7d7)
+++ swingjs/README.txt (revision 0)
@@ -1,8 +0,0 @@
-The swingjs directory contains the current transpiler (net.sf.j2s.core.jar)
-and the run-time core site files (SwingJS-site.zip)
-
-In addition are version directories -- for example, ver/3.1.1 and ver/3.2.1
-
-The second of these, ver/3.2.1, adds Java 8 functionality.
-
-
Index: swingjs/SwingJS-site.zip
===================================================================
diff -u -N -rc2e6e8b7abeaae445d08d6106ef0d16f79a41318 -r6c27b7864ec61c420326a75e7cce476cf8d60395
Binary files differ
Index: swingjs/differences.txt
===================================================================
diff -u -N
--- swingjs/differences.txt (revision 0)
+++ swingjs/differences.txt (revision 6c27b7864ec61c420326a75e7cce476cf8d60395)
@@ -0,0 +1,1541 @@
+Notes
+=====
+
+---IMPORTANT CHARACTER SET NOTE---
+
+It is critical that all development work in Java2Script
+be done in UTF-8. This means:
+
+- making sure your Eclipse project is set up for UTF-8 (not the Eclipse default?)
+- making sure your server can serve up UTF-8 by default for any browser-loaded files
+- making sure you don't edit a Java2Script class file or one of the site .js files
+ using a non-UTF-8 editor. It may replace non-Latin characters with "?" or garbage.
+- making sure that your web pages are delivered with proper headings indicating HTML5 and UTF-8
+
+
+
+
+
+
+Note that the DOCTYPE tag is critical for some browsers to switch into HTML5 mode. (MSIE?)
+
+
+
+
+In particular, the Mandarin character 秘 (mi; "secret") is used extensively throughout
+the SwingJS class files to distinguish j2s-specific fields and methods that must not
+ever be shadowed or overridden by subclasses. For example, we see in java.lang.Thread.java:
+
+ public static JSThread 秘thisThread;
+
+----------------------------------
+
+
+updated 12/6/2020 -- note about restrictions on long, including BitSet and Scanner
+updated 3/21/2020 -- adds note about HashMap, Hashtable, and HashSet iterator ordering
+updated 3/20/2020 -- adds note about interning, new String("xxx"), and "xxx"
+updated 2/26/2020 -- adds Graphics.setClip issue
+updated 12/22/19 -- additional issues
+updated 11/03/19 -- adds information about File.exists() and points to src/javajs/async
+updated 10/26/19 -- adds information about File.createTempFile()
+updated 8/16/19 -- minor typos and added summary paragraph
+updated 7/19/19 -- clarification that AWT and Swing classes are supported directly
+updated 5/13/19 -- Mandarin U+79D8 reserved character; Missing Math methods; int and long
+updated 5/10/19 -- adds a section on static issues in multi-(duplicate)-applet pages
+updated 1/4/19 -- nio
+updated 9/15/18 -- adds integer 1/0 == Infinity
+updated 7/24/18 -- most classes replaced with https://github.com/frohoff/jdk8u-jdk
+updated 6/5/17 -- reserved package name "window"
+updated 3/11/17 -- myClass.getField
+updated 3/7/17 -- overloading of JSplitPane.setDividerLocation
+updated 3/2/17 -- more indication of classes not implemented (KeyListener)
+
+=============================================================================
+SwingJS and OpenJDK 8+
+=============================================================================
+
+SwingJS implements a wide range of the Java language in JavaScript. The base
+version for this implementation is OpenJDK8. some classes are implemented using
+older source code, and there are some missing methods. For the most part, this is
+no real problem. You can add or modify any java class just be adding it as source
+in your project. Or (preferably) you can contact me, and I can get it into the
+distribution. Or (even more preferably) you can do that via a patch submission.
+
+=================
+DESIGN PHILOSOPHY
+=================
+
+The java2script/SwingJS design goal is to recreate a recognizable, easily debuggable
+equivalent in JavaScript for as much of Java as practical. This means, for example,
+that one can call in JavaScript
+
+ new java.util.Hashtable()
+
+and for all practical purposes it will appear that Java is running.
+
+
+Method and Field Disambiguation
+-------------------------------
+
+SwingJS has no problem with the overloading of methods, for example:
+
+ public void print(int b);
+ public void print(float b);
+
+JavaScript does not allow overloading of methods, and the common practice in
+Java of naming a field the same as a method -- isAllowed and isAllowed() -- is
+not possible in JavaScript. As a result, SwingJS implements "fully-qualified"
+method names using "$" parameter type separation. Thus, these methods in SwingJS
+will be referred to as print$I and print$F. The rules for this encoding are
+relatively simple:
+
+1. The seven primitive types in Java are encoded $I (int), $L (long), $F (float),
+$D (double), $B (byte) $Z (boolean), and $H (short).
+
+2. String and Object are encoded as $S and $O, respectively.
+
+3. "java_lang_" is dropped for all other classes in the java.lang package (as in Java).
+ For example: $StringBuffer, not $java_lang_StringBuffer
+
+4. All other classes are encoded as
+
+ "$" + Class.getName().replace(".","_")
+
+For example, in Java we see:
+
+ public void equals(Object o) {...}
+
+Whereas in SwingJS we have:
+
+ Clazz.newMeth(C$, 'equals$O', function (o) {...}
+
+And
+
+ this.getContentPane().add(bar, "North");
+
+becomes
+
+ this.getContentPane$().add$java_awt_Component$O(bar, "North");
+
+5. Arrays are indicated with appended "A" for each level. So
+
+ setDataVector(Object[][] dataVector, Object[] columnIdentifiers)
+
+becomes
+
+ setDataVector$OAA$OA(dataVector, columnIdentifiers)
+
+(It is recognized that this design does introduce a bit of ambiguity, in that
+ in principal there could be user class named XA and X in the same package,
+ and methods a(X[]) and a(XA) in the same class that cannot be distinguished.
+ The benefit of this simple system, however, triumphed over the unlikelyhood
+ of that scenario.) The transpiler could be set to flag this possibility.
+
+6. Constructors are prepended with "c$". So
+
+ public JLabel(String text) {...}
+
+becomes:
+
+ Clazz.newMeth(C$, 'c$$S', function (text) {...});
+
+Field disambiguation involves prepending. In Java, a class and its subclass
+can both have the same field name, such as
+
+ boolean visible;
+
+When this happens, it is called "shadowing", and though not recommended, Java allows
+it. The Java2Script transpiler will prepend such shadowing fields with "$" so that the
+subclass instance has both "visible" (for use in its methods inherited from its
+superclass) and "$visible" (for its own methods). Thus, we might see in Java:
+
+ this.visible = super.visible;
+
+while in SwingJS we will see:
+
+ this.$visible=this.visible;
+
+since JavaScript does not have the "super" keyword.
+
+
+
+Parameterless methods such as toString() are appended with "$" to become toString$().
+The one exception to this rule is private methods, which are saved in (truly) private
+array in the class (and are not accessible by reflection). Private parameterless
+methods retain their simple Java name, since they cannot conflict with field names.
+
+This renaming of methods has a few consequences, which are discussed more fully below.
+See particularly the section on "qualified field and method names", where it is described
+how you can use packages or classes or interfaces with ".api.js" in them to represent JavaScript
+objects for which all method names are to be left unqualified. Note that it is not
+possible to cherry-pick methods to be unqualified; only full packages, classes or
+interfaces can hold this status.
+
+The swingjs.api.js package in particular contains a number of useful interfaces that
+you can import into your project for JavaScript-specific capabilities.
+
+
+Applet vs. Application
+----------------------
+
+One of the very cool aspects of SwingJS is that it doesn't particularly matter if a browser-based
+Java app is an "applet" or an "application". We don't need JNLP (Java Network Launch Protocol)
+because now we can just start up any Java application in a browser just as easily as any applet.
+The associative array that passes information to the SwingJS applet (information that formerly
+might have been part of the APPLET tag, such as width, height, and codebase, always referred to
+in our writing as "the Info array") allows the option to specify the JApplet/Applet "code"
+class or the application "main" class. Either one will run just fine.
+
+
+Performance
+-----------
+
+Obviously, there are limitations. One is performance, but we have seen reproducible
+performance at 1/6 - 1/3 the speed of Java. Achieving this performance may require
+some refactoring of the Java to make it more efficient in both Java and JavaScript.
+"for" loops need to be more carefully crafted; use of "new" and "instanceof" need to be
+minimized in critical areas. Note that method overloading -- that is, the same method name
+with different parameters, such as read(int) and read(byte) -- is no longer any problem.
+
+
+Threads
+-------
+
+Although there is only a single thread in JavaScript, meaning Thread.wait(), Thread.sleep(int) and
+Thread.notify() cannot be reproduced, we have found that this is not a serious limitation.
+For example, javax.swing.Timer() works perfectly in JavaScript. All it means is that threads
+that use sleep(int) or notify() must be refactored to allow Timer-like callbacks. That is,
+they must allow full exit and re-entry of Thread.run(), not the typical while/sleep motif.
+
+The key is to create a state-based run() that can be exited and re-entered in JavaScript.
+
+
+Static fields
+-------------
+
+Final static primitive "constant" fields (String, boolean, int, etc.) such as
+
+static final int TEST = 3;
+static final String MY_STRING = "my " + "string";
+
+are converted to their primitive form automatically by the Eclipse Java compiler
+and do not appear in the JavaScript by their names.
+
+Other static fields are properties of their class and can be used as expected.
+
+Note, however, that SwingJS runs all "Java" code on a page in a common "jvm"
+(like older versions of Java). So, like the older Java schema, the JavaScript
+equivalents of both applets and applications will share all of their static
+fields and methods. This includes java.lang.System.
+
+Basically, SwingJS implementations of Java run in a browser page-based sandbox
+instead of an applet-specific one.
+
+In general, this is no problem. But if we are to implement pages with
+multiple applets present, we must be sure to only have static references
+that are "final" or specifically meant to be shared in a JavaScript
+environment only (since they will not be shared in Java).
+
+A simple solution, if static non-constant references are needed, is to attach the
+field to Thread.currentThread.threadGroup(), which is an applet-specific reference.
+Be sure, if you do this, that you use explicit setters and getters:
+
+For example,
+
+private static String myvar;
+
+...
+
+public void setMyVar(String x) {
+ ThreadGroup g = Thread.currentThread().threadGroup();
+ /**
+ * @j2sNative g._myvar = x;
+ *
+ */
+ {
+ myvar = x;
+ }
+}
+
+public String getMyVar() {
+ ThreadGroup g = Thread.currentThread().threadGroup();
+ /**
+ * @j2sNative return g._myvar || null;
+ *
+ */
+ {
+ return myvar;
+ }
+}
+
+ in Java will get and set x the same in JavaScript and in Java.
+
+
+A convenient way to do this in general is to supply a singleton class with
+explicitly private-only constructors and then refer to it in Java and in JavaScript
+instead of using static field, referring to myclass.getIntance().xxx instead of
+myclass.xxx in Java (and JavaScript).
+
+This was done extensively in the Jalview project. See jalview.bin.Instance.
+
+
+Helper Packages -- swingjs/ and javajs/
+---------------------------------------
+
+The SwingJS library is the swingjs/ package. There are interfaces that may be of assistance
+in swingjs/api, but other than that, it is not recommended that developers access classes in
+this package. The "public" nature of their methods is really an internal necessity.
+
+In addition to swingjs/, though, there are several useful classes in the javajs/ package
+that could be very useful. This package is a stand-alone package that can be
+cloned in any Java project that also would be great to have in any JavaScript project
+-- SwingJS-related or not. Functionality ranges from reading and writing various file
+formats, including PDF, BMP, PNG, GIF, JPG, JSON, ZIP, and CompoundDocument formats.
+
+A variety of highly efficient three- and four-dimensional point, vector, matrix, and
+quaternion classes are included, as they were developed for JSmol and inherited from that
+project.
+
+Of particular interest should be javajs/async/, which includes
+
+javajs.async.Async
+javajs.async.AsyncColorChooser
+javajs.async.AsyncDialog
+javajs.async.AsyncFileChooser
+
+See javajs.async.Async JavaDoc comments for a full description of
+these useful classes.
+
+
+Modal Dialogs
+-------------
+
+Although true modal dialogs are not possible with only one thread, a functional equivalent --
+asynchronous modal dialogs -- is relatively easy to set up. All the JOptionPane dialogs will
+return PropertyChangeEvents to signal that they have been disposed of and containing the results.
+See below and classes in the javajs.async package.
+
+
+Native calls
+------------
+
+Native calls in Java are calls to operating system methods that are not in Java. JavaScript
+has no access to these, of course, and they must all be replaced by JavaScript equivalents.
+Fortunately, they are not common, and those that are present in Java (for example, in calculating
+checksums in ZIP file creation) are at a low enough level that most developers do not utilize them
+or do not even have access to them. All native calls in Java classes have been replaced by
+Java equivalents.
+
+
+Swing GUI Peers and UIClasses
+-----------------------------
+
+One of the biggest adaptations introduced in SwingJS is in the area of the graphical
+user interface. The issue here is complex but workable. In Java there are two background
+concepts -- the Component "peer" (one per "heavy-weight" component, such as a Frame) and the
+component "uiClass" (one per component, such as JButton or JTextField).
+
+Peers are native objects of the operating system. These are the virtual buttons and text areas
+that the user is interacting with at a very base level. Their events are being passed on to
+Java or the browser by the operating system. UI classes provide a consistent "look and feel"
+for these native objects, rendering them onto the native window canvas and handling all
+user-generated events. They paint the borders, the backgrounds, the highlights, of every
+control you see in Java. There is one-to-one correspondence of Swing classes and UI classes.
+Setting the Look and Feel for a project amounts to selecting the directory from which to draw
+these UI classes. The UI classes can be found in the javax.swing.plaf ("platform look and feel")
+package.
+
+Early on in the development of SwingJS, we decided not to fully reproduce the painfully detailed
+bit-by-bit painting of controls as is done in Java. Instead, we felt it was wiser to utilize the standard
+HTML5 UI capabilities as much as possible, using DIV, and INPUT especially, with extensive use
+of CSS and sometimes jQuery (menus, and sliders, for example). Thus, we have created a new
+set of UIs -- the "HTML5 Look and Feel". These classes can be found in swingjs.plaf. Besides being
+more adaptable, this approach allows far more versatility to SwingJS developers, allowing them
+to modify the GUI to suit their needs if desired.
+
+In SwingJS, since we have no access to native peers except through the browser DOM,
+it seemed logical to merge the peer and UI idea. So instead of having one peer per heavy-weight control and
+one UI class instance for each control type, we just have one UI class instance per control, and
+that UI class instance is what is being referred to when a "peer" is notified.
+
+In some ways this is a throw back to when all of Swing's components were subclasses of
+specific AWT components such as Button and List. These "heavy-weight components" all had their
+own individual native peers and thus automatically took on the look and feel provided by the OS.
+Later Swing versions implemented full look and feel for all peers, leaving only JDialog, JFrame,
+and a few other classes to have native peers. But in SwingJS we have again a 1:1 map of component
+and UI class/peer instance.
+
+The origin of most issues (read "bugs") in relation to the GUI will probably be found in the
+swingjs.plaf JSxxxxUI.java code.
+
+
+Swing-only Components -- no longer an issue
+-------------------------------------------
+
+Swing was introduced into Java well after the Java Abstract Window Toolkit (AWT) was well
+established. As such, its designers chose to allow AWT controls such as Button and List to be used
+alongside their Swing counterparts JButton and JList. Reading the code, it is clear that this
+design choice posed a huge headache for Swing class developers.
+
+For SwingJS, we decided from the beginning NOT to allow this mixed-mode programming and
+instead to require that all components be Swing components.
+
+However, this is no longer an issue. All AWT components in SwingJS are now subclasses of
+javax.swing.JComponent. So far, we have found no problem with this.
+
+
+The a2s Adapter Package
+-----------------------
+
+Originally, we thought that we would restrict ourselves to JApplets only. That is, only
+Swing-based applets. But as we worked, we discovered that there are a lot of great
+applets out there that are pre-Swing pure-AWT java.applet.Applet applets. Our problem was
+that we also wanted it to be possible to quickly adapt these applets to JavaScript as well.
+
+The solution turned out to be simple: Write a package (a2s) that recreates the interface for
+non-Swing components as subclasses of Swing components. Thus, a2s.Button subclasses javax.swing.JButton
+but also accepts all of the methods of java.awt.Button. This works amazingly well, with a few
+special adaptations to the core javax.swing to be "AWT-aware." All AWT components now subclass
+a2s components, which in turn subclass JComponents. So no changes in code are necessary. We have
+successfully transpiled over 500 applets using this strategy. (Kind of surprising, actually, that
+the original Java developers did not see that option. But we have a hindsight advantage here.)
+
+
+Working with Files
+==================
+
+Simple String file names are not optimal for passing information about
+read files within SwingJS applications.
+
+All work with files should either use Path or File objects exclusively.
+These objects, after a file is read or checked for existence, will already
+contain the file byte[] data. Doing something like this:
+
+File f = File("./test.dat");
+boolean isOK = f.exists();
+
+will load f with its byte[] data, if the file exists.
+
+But if after that, we use:
+
+File f2 = new File(f.getAbsolutePath());
+
+f2 will not contain that data. Such copying should be done as:
+
+File f2 = new File(f);
+
+in which case, the byte[] data will be transferred.
+
+
+SwingJS uses the following criteria to determine if File.exists() returns true:
+
+(1) if this File object has been used directly to read data, or
+(2) if reading data using this File object is successful.
+
+Note that you cannot check to see if a file exists before input or if it
+was actually written or if it already exists prior to writing in SwingJS.
+
+Thus, you should check each use of file.exists() carefully, and if necessary, provide a J2sNative
+block that gives an appropriate "OK" message, for example:
+
+(/** @j2sNative 1 ? false : */ outputfile.exits())
+
+or
+
+(/** @j2sNative 1 ? true : */ inputfile.exits())
+
+Temporary files can be created in SwingJS. SwingJS will maintain a pseudo-filesystem for files
+created with File.createTempFile(). This is useful in that closure of writing to a temporary file
+does not generate a pseudo-download to the user's machine.
+
+
+UNIMPLEMENTED CLASSES BY DESIGN
+===============================
+
+The SwingJS implementation of the following classes are present
+in a way that gracefully bypasses their functionality:
+
+accessibility
+security
+serialization
+
+
+
+TODO LIST FOR UNIMPLEMENTED CLASSES
+===================================
+
+JEditorPane (minimal implementation) - DONE 12/2018; some issues still
+JSplitPane - DONE 8/2018
+JTabbedPane - DONE 10/2018
+JTree - done 12/2019
+
+
+MINOR ISSUES--required some rewriting/refactoring by Bob and Udo
+================================================================
+
+Thread.currentThread() == dispatchThread
+
+
+MINOR ISSUES--requiring some rewriting/refactoring outside of SwingJS
+=====================================================================
+
+See below for a full discussion.
+
+Restrictions on long
+Restriction on BitSet and Scanner
+HashMap, Hashtable, and HashSet iterator ordering
+interning, new String("xxx") vs "xxx"
+Names with "$" and "_"
+positive integers do not add to give negative numbers
+ArrayIndexOutOfBounds
+java.awt.Color
+native methods
+javax.swing.JFileDialog
+key focus
+LookAndFeel and UI Classes
+System.exit(0) does not stop all processes
+list cell renderers must be JComponents
+myClass.getField not implemented
+"window" and other reserved JavaScript names
+reserved field and method names
+qualified field and method names
+missing Math methods
+Component.getGraphics(), Graphics.dispose()
+Graphics.setClip()
+
+MAJOR ISSUES--for Bob and Udo within SwingJS
+============================================
+
+fonts
+OS-dependent classes
+AWT component peers
+some aspects of reflection
+
+MAJOR ISSUES--to be resolved by implementers
+============================================
+
+fonts
+threads
+modal dialogs
+image loading
+BigDecimal not fully implemented
+no format internationalization
+no winding rules
+text-related field implementation
+Formatter/Regex limitations
+integer 1/0 == Infinity
+
+========================================================================
+
+DISCUSS
+=======
+
+Table row/col sorter needs checking after removal of java.text.Collator references
+
+I had to move all of SunHints class to RenderingHints, or the
+two classes could not be loaded. Shouldn't be a problem, I think. The sun classes are
+not accessible to developers in Java anyway, since they are generally package private.
+
+==========================================================================
+
+//////////////////////////////////////////////////////////////////////////////
+
+UNIMPLEMENTED CLASSES
+=====================
+
+accessibility
+-------------
+
+All Accessibility handling has been commented out to save the download footprint.
+This removes the need for sun.misc.SharedSecrets as well.
+Nothing says we could not implement accessibility. We just didn't.
+
+
+security
+--------
+
+All JavaScript security is handled by the browser natively.
+Thus, Java security checking is no longer necessary, and
+java.security.AccessController has been simplified to work without
+native security checking.
+
+Note that private methods in a class are REALLY private.
+
+
+serialization
+-------------
+
+All serialization has been removed. It was never very useful for Swing anyway,
+because one needs exactly the same Java version to save and restore serialized objects.
+
+
+keyboard accelerators and mnemonics
+-----------------------------------
+
+This work was completed in the spring of 2019. Note that in a browser, some
+key strokes, particularly CTRL-keys, are not available. Bummer.
+
+
+MINOR ISSUES--required some rewriting/refactoring by Bob and Udo
+================================================================
+
+
+Thread.currentThread() == dispatchThread
+----------------------------------------
+
+changed to JSToolkit.isDispatchThread()
+
+
+MINOR ISSUES--requiring some rewriting/refactoring outside of SwingJS
+=====================================================================
+
+restrictions on long
+--------------------
+
+Java's 64-bit long type is not supported in JavaScript. There is no Int64Array in JavaScript,
+and 0x20000000000000 + 1 evaluates to 0x20000000000000, not 0x20000000000001.
+(Likewise, -0x20000000000000 - 1 is left unchanged.)
+
+The largest "integer" value in JavaScript is 9007199254740991 (9.007199254740991E13, or 0x1FFFFFFFFFFFFFF).
+Effectively, you get to use only 53 bits of the long, not 64. Trying to set a long larger than
+0x1FFFFFFFFFFFFFF or smaller than -0x1FFFFFFFFFFFFFF will result in a NumberFormatException.
+
+The transpiler handles conversion to long the same as Java for all cases other than from double.
+
+For small double values, there is no problem, and, in fact, this is a known trick used to round
+doubles and floats toward zero:
+
+double d;
+d = (long) 3.8;
+assert(d == 3);
+d = (long) -3.8;
+assert(d == -3);
+
+SwingJS will evaluate (long) d as 0 for d > 9007199254740991
+or d < -9007199254740991, same as Java returns for Double.NaN.
+So, in Java we have:
+
+ assert(((long) Double.NaN) == 0);
+ assert(((int) Double.NaN) == 0);
+ assert(((long) Float.NaN) == 0);
+ assert(((int) Float.NaN) == 0);
+
+and also, in JavaScript only, we also have:
+
+ double d = 0x2000000000000L;
+ assert(((long) d) == 0);
+
+
+restrictions on BitSet and Scanner
+----------------------------------
+
+Because of the issue of long being only 53 bits, any time a method returns a long value, considerations must
+be made as to whether this will work in JavaScript. In particular, BitSet and Scanner have issues.
+
+In SwingJS, java.util.BitSet has been implemented as a 32-bit integer-based bitset. This was no problem in
+Java 6, but starting with Java 7, a method was added to BitSet that allows for the extraction of the
+underlying long[] word data. This is not work in JavaScript. Instead, SwingJS java.util.Bitset.toLongArray() will deliver
+32-bit int[] data.
+
+SwingJS Scanner has hasNextLong() and nextLong(), and although it will scan through long numbers,
+Scanner will choke on long numbers greater than the JavaScript 53-bit limit. hasNextLong() will
+return false, and nextLong() will throw an InputMismatchException triggered by the NumberFormatException
+thrown by Long.parseLong().
+
+
+HashMap, Hashtable, and HashSet iterator ordering
+-------------------------------------------------
+
+In Java, iterators for HashMap, Hashtable, and HashSet do not guarantee any particular order.
+From the HashMap documentation for Java 8:
+
+ This class makes no guarantees as to the order of the map; in particular, it does not
+ guarantee that the order will remain constant over time.
+
+Likewise, for HashSet (because it is simply a convenience method for HashMap