+++ /dev/null
-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.
-
-
java2script/SwingJS Notes
=========================
+updated 3/11/2023 -- adds support for Java Regex Matcher.start/end(groupID) and .start/end(groupName)
updated 12/31/2020 -- full support for 64-bit long
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
Some browsers cannot process Regex "look-behind" process such as (?<=\W)
java.util.regex.Matcher and Pattern use JavaScript's RegExp object rather than
the native Java object. These are not identical. Only flags /igm are supported.
-Matcher.start(groupID) is not supported.
+Matcher.start(groupID)/.end(groupID) is supported.
+(x*)? failure returns null, not empty string.
java.util.Formatter will function correctly for all standard %... patterns.
-20230210093656
+20230831104534
+++ /dev/null
-This is sources/net.sf.j2s.java.core/dist/DEV_NOTES.txt
-
-_j2sclasslist.txt
-
-the list of .js files concatenated into coreswingjs.js and minified to coreswingjs.z.js
-
-
-SwingJS-site.zip
-
-the full site directory for SwingJS including all files not in the test/ directory.
+++ /dev/null
-java/applet/Applet.js
-java/applet/AppletContext.js
-java/applet/AppletStub.js
-java/applet/JSApplet.js
-java/awt/ActiveEvent.js
-java/awt/Adjustable.js
-java/awt/AWTEvent.js
-java/awt/AWTEventMulticaster.js
-java/awt/AWTKeyStroke.js
-java/awt/BasicStroke.js
-java/awt/BorderLayout.js
-java/awt/Button.js
-java/awt/Color.js
-java/awt/color/ColorSpace.js
-java/awt/Component.js
-java/awt/ComponentOrientation.js
-java/awt/ContainerOrderFocusTraversalPolicy.js
-java/awt/Container.js
-java/awt/Cursor.js
-java/awt/DefaultFocusTraversalPolicy.js
-java/awt/DefaultKeyboardFocusManager.js
-java/awt/Dialog.js
-java/awt/Dimension.js
-java/awt/dnd/peer/DropTargetPeer.js
-java/awt/event/ActionListener.js
-java/awt/event/AdjustmentEvent.js
-java/awt/event/AdjustmentListener.js
-java/awt/event/AWTEventListener.js
-java/awt/event/ComponentAdapter.js
-java/awt/event/ComponentEvent.js
-java/awt/event/ComponentListener.js
-java/awt/event/ContainerListener.js
-java/awt/event/FocusEvent.js
-java/awt/event/FocusListener.js
-java/awt/event/HierarchyBoundsListener.js
-java/awt/event/HierarchyListener.js
-java/awt/event/InputEvent.js
-java/awt/event/InputMethodListener.js
-java/awt/event/InvocationEvent.js
-java/awt/event/ItemEvent.js
-java/awt/event/ItemListener.js
-java/awt/event/KeyListener.js
-java/awt/event/MouseEvent.js
-java/awt/event/MouseListener.js
-java/awt/event/MouseMotionListener.js
-java/awt/event/MouseWheelListener.js
-java/awt/event/TextListener.js
-java/awt/event/WindowAdapter.js
-java/awt/event/WindowEvent.js
-java/awt/event/WindowFocusListener.js
-java/awt/event/WindowListener.js
-java/awt/event/WindowStateListener.js
-java/awt/EventDispatchThread.js
-java/awt/EventFilter.js
-java/awt/EventQueue.js
-java/awt/EventQueueItem.js
-java/awt/FlowLayout.js
-java/awt/FocusTraversalPolicy.js
-java/awt/Font.js
-java/awt/font/FontRenderContext.js
-java/awt/FontMetrics.js
-java/awt/Frame.js
-java/awt/geom/AffineTransform.js
-java/awt/geom/Dimension2D.js
-java/awt/geom/Path2D.js
-java/awt/geom/PathIterator.js
-java/awt/geom/Point2D.js
-java/awt/geom/Rectangle2D.js
-java/awt/geom/RectangularShape.js
-java/awt/geom/RectIterator.js
-java/awt/GraphicsCallback.js
-java/awt/GraphicsConfiguration.js
-java/awt/GraphicsDevice.js
-java/awt/GraphicsEnvironment.js
-java/awt/Image.js
-java/awt/image/ImageObserver.js
-java/awt/Insets.js
-java/awt/ItemSelectable.js
-java/awt/JSComponent.js
-java/awt/JSDialog.js
-java/awt/JSFrame.js
-java/awt/JSPanel.js
-java/awt/KeyboardFocusManager.js
-java/awt/KeyEventDispatcher.js
-java/awt/KeyEventPostProcessor.js
-java/awt/Label.js
-java/awt/LayoutManager.js
-java/awt/LayoutManager2.js
-java/awt/LightweightDispatcher.js
-java/awt/Paint.js
-java/awt/Panel.js
-java/awt/peer/ComponentPeer.js
-java/awt/peer/ContainerPeer.js
-java/awt/peer/FramePeer.js
-java/awt/peer/KeyboardFocusManagerPeer.js
-java/awt/peer/LightweightPeer.js
-java/awt/peer/WindowPeer.js
-java/awt/Point.js
-java/awt/Queue.js
-java/awt/Rectangle.js
-java/awt/RenderingHints.js
-java/awt/Scrollbar.js
-java/awt/ScrollPane.js
-java/awt/Shape.js
-java/awt/Stroke.js
-java/awt/TextArea.js
-java/awt/TextComponent.js
-java/awt/TextField.js
-java/awt/Toolkit.js
-java/awt/Transparency.js
-java/awt/Window.js
-java/beans/ChangeListenerMap.js
-java/beans/PropertyChangeEvent.js
-java/beans/PropertyChangeListener.js
-java/beans/PropertyChangeSupport.js
-java/lang/AbstractStringBuilder.js
-java/lang/Class.js
-java/lang/Enum.js
-java/lang/Iterable.js
-java/lang/reflect/Constructor.js
-java/lang/reflect/Method.js
-java/lang/StringBuffer.js
-java/lang/StringBuilder.js
-java/lang/Thread.js
-java/lang/ThreadGroup.js
-java/math/RoundingMode.js
-java/net/URL.js
-java/net/URLStreamHandlerFactory.js
-java/net/HttpURLConnection.js
-java/net/URLStreamHandler.js
-javax/net/ssl/HttpsUrlConnection.js
-java/text/CharacterIterator.js
-java/text/DecimalFormat.js
-java/text/DecimalFormatSymbols.js
-java/text/DigitList.js
-java/text/FieldPosition.js
-java/text/Format.js
-java/text/NumberFormat.js
-java/util/AbstractCollection.js
-java/util/AbstractList.js
-java/util/AbstractMap.js
-java/util/AbstractSequentialList.js
-java/util/AbstractSet.js
-java/util/ArrayList.js
-java/util/Arrays.js
-java/util/Collection.js
-java/util/Collections.js
-java/util/Comparator.js
-java/util/Deque.js
-java/util/Dictionary.js
-java/util/Enumeration.js
-java/util/EventListener.js
-java/util/EventObject.js
-java/util/HashMap.js
-java/util/HashSet.js
-java/util/Hashtable.js
-java/util/IdentityHashMap.js
-java/util/Iterator.js
-java/util/LinkedHashMap.js
-java/util/LinkedList.js
-java/util/List.js
-java/util/ListResourceBundle.js
-java/util/Locale.js
-java/util/Map.js
-java/util/Objects.js
-java/util/Queue.js
-java/util/Random.js
-java/util/RandomAccess.js
-java/util/ResourceBundle.js
-java/util/Set.js
-java/util/TimSort.js
-java/util/Vector.js
-javajs/api/JSFunction.js
-javajs/util/AjaxURLConnection.js
-javajs/util/AjaxURLStreamHandlerFactory.js
-javajs/util/AU.js
-javajs/util/JSThread.js
-javajs/util/Lst.js
-javajs/util/PT.js
-javajs/util/Rdr.js
-javajs/util/SB.js
-javax/swing/AbstractAction.js
-javax/swing/AbstractButton.js
-javax/swing/AbstractListModel.js
-javax/swing/Action.js
-javax/swing/ActionMap.js
-javax/swing/AncestorNotifier.js
-javax/swing/ArrayTable.js
-javax/swing/border/AbstractBorder.js
-javax/swing/border/BevelBorder.js
-javax/swing/border/Border.js
-javax/swing/border/CompoundBorder.js
-javax/swing/border/EmptyBorder.js
-javax/swing/border/EtchedBorder.js
-javax/swing/border/LineBorder.js
-javax/swing/border/TitledBorder.js
-javax/swing/BorderFactory.js
-javax/swing/BoundedRangeModel.js
-javax/swing/BoxLayout.js
-javax/swing/ButtonGroup.js
-javax/swing/ButtonModel.js
-javax/swing/ClientPropertyKey.js
-javax/swing/ComboBoxModel.js
-javax/swing/DefaultBoundedRangeModel.js
-javax/swing/DefaultButtonModel.js
-javax/swing/DefaultComboBoxModel.js
-javax/swing/DefaultSingleSelectionModel.js
-javax/swing/DropMode.js
-javax/swing/event/AncestorEvent.js
-javax/swing/event/AncestorListener.js
-javax/swing/event/CaretEvent.js
-javax/swing/event/CaretListener.js
-javax/swing/event/ChangeEvent.js
-javax/swing/event/ChangeListener.js
-javax/swing/event/DocumentEvent.js
-javax/swing/event/DocumentListener.js
-javax/swing/event/EventListenerList.js
-javax/swing/event/ListDataEvent.js
-javax/swing/event/ListDataListener.js
-javax/swing/event/UndoableEditEvent.js
-javax/swing/event/UndoableEditListener.js
-javax/swing/FocusManager.js
-javax/swing/InternalFrameFocusTraversalPolicy.js
-javax/swing/LayoutComparator.js
-javax/swing/LayoutFocusTraversalPolicy.js
-javax/swing/SortingFocusTraversalPolicy.js
-javax/swing/SwingContainerOrderFocusTraversalPolicy.js
-javax/swing/SwingDefaultFocusTraversalPolicy.js
-javax/swing/Icon.js
-javax/swing/ImageIcon.js
-javax/swing/InputMap.js
-javax/swing/JApplet.js
-javax/swing/JButton.js
-javax/swing/JCheckBox.js
-javax/swing/JCheckBoxMenuItem.js
-javax/swing/JComboBox.js
-javax/swing/JComponent.js
-javax/swing/JFrame.js
-javax/swing/JLabel.js
-javax/swing/JLayeredPane.js
-javax/swing/JMenu.js
-javax/swing/JMenuBar.js
-javax/swing/JMenuItem.js
-javax/swing/JPanel.js
-javax/swing/JPopupMenu.js
-javax/swing/JRadioButtonMenuItem.js
-javax/swing/JRootPane.js
-javax/swing/JScrollBar.js
-javax/swing/JScrollPane.js
-javax/swing/JSeparator.js
-javax/swing/JTextArea.js
-javax/swing/JTextField.js
-javax/swing/JToggleButton.js
-javax/swing/JViewport.js
-javax/swing/KeyboardManager.js
-javax/swing/KeyStroke.js
-javax/swing/ListModel.js
-javax/swing/LookAndFeel.js
-javax/swing/MenuElement.js
-javax/swing/MutableComboBoxModel.js
-javax/swing/plaf/ActionMapUIResource.js
-javax/swing/plaf/basic/BasicBorders.js
-javax/swing/plaf/BorderUIResource.js
-javax/swing/plaf/ColorUIResource.js
-javax/swing/plaf/ComponentUI.js
-javax/swing/plaf/DimensionUIResource.js
-javax/swing/plaf/FontUIResource.js
-javax/swing/plaf/InputMapUIResource.js
-javax/swing/plaf/InsetsUIResource.js
-javax/swing/plaf/UIResource.js
-javax/swing/RepaintManager.js
-javax/swing/RootPaneContainer.js
-javax/swing/Scrollable.js
-javax/swing/ScrollPaneConstants.js
-javax/swing/ScrollPaneLayout.js
-javax/swing/SingleSelectionModel.js
-javax/swing/SizeRequirements.js
-javax/swing/SwingConstants.js
-javax/swing/SwingPaintEventDispatcher.js
-javax/swing/SwingUtilities.js
-javax/swing/text/AbstractDocument.js
-javax/swing/text/AttributeSet.js
-javax/swing/text/Caret.js
-javax/swing/text/DefaultCaret.js
-javax/swing/text/DefaultEditorKit.js
-javax/swing/text/Document.js
-javax/swing/text/EditorKit.js
-javax/swing/text/Element.js
-javax/swing/text/GapContent.js
-javax/swing/text/GapVector.js
-javax/swing/text/JTextComponent.js
-javax/swing/text/MutableAttributeSet.js
-javax/swing/text/PlainDocument.js
-javax/swing/text/PlainView.js
-javax/swing/text/Position.js
-javax/swing/text/Segment.js
-javax/swing/text/SegmentCache.js
-javax/swing/text/SimpleAttributeSet.js
-javax/swing/text/Style.js
-javax/swing/text/StyleConstants.js
-javax/swing/text/StyleContext.js
-javax/swing/text/TabExpander.js
-javax/swing/text/TextAction.js
-javax/swing/text/Utilities.js
-javax/swing/text/View.js
-javax/swing/tree/TreeNode.js
-javax/swing/UIDefaults.js
-javax/swing/UIManager.js
-javax/swing/undo/AbstractUndoableEdit.js
-javax/swing/undo/CompoundEdit.js
-javax/swing/undo/UndoableEdit.js
-javax/swing/ViewportLayout.js
-javax/swing/WindowConstants.js
-sun/awt/AppContext.js
-sun/awt/AWTAutoShutdown.js
-sun/awt/CausedFocusEvent.js
-sun/awt/ComponentFactory.js
-sun/awt/KeyboardFocusManagerPeerProvider.js
-sun/awt/MostRecentKeyValue.js
-sun/awt/MostRecentThreadAppContext.js
-sun/awt/PaintEventDispatcher.js
-sun/awt/PostEventQueue.js
-sun/awt/RequestFocusController.js
-sun/awt/SunToolkit.js
-sun/awt/WindowClosingListener.js
-sun/awt/WindowClosingSupport.js
-sun/awt/image/DataStealer.js
-sun/awt/image/IntegerComponentRaster.js
-sun/awt/image/IntegerInterleavedRaster.js
-sun/awt/image/SunWritableRaster.js
-sun/font/FontDesignMetrics.js
-sun/swing/DefaultLookup.js
-sun/swing/SwingLazyValue.js
-sun/text/resources/FormatData.js
-sun/text/resources/en/FormatData_en.js
-sun/util/resources/LocaleData.js
-sun/util/locale/BaseLocale.js
-sun/util/locale/LocaleUtils.js
-sun/util/locale/provider/LocaleProviderAdapter.js
-sun/util/locale/provider/LocaleDataMetaInfo.js
-swingjs/a2s/A2SContainer.js
-swingjs/a2s/A2SEvent.js
-swingjs/a2s/A2SListener.js
-swingjs/a2s/Applet.js
-swingjs/a2s/Button.js
-swingjs/a2s/Label.js
-swingjs/a2s/Panel.js
-swingjs/a2s/Scrollbar.js
-swingjs/a2s/ScrollPane.js
-swingjs/a2s/TextArea.js
-swingjs/a2s/TextField.js
-swingjs/api/Interface.js
-swingjs/api/js/DOMNode.js
-swingjs/api/js/HTML5CanvasContext2D.js
-swingjs/api/js/JSInterface.js
-swingjs/jquery/JQueryUI.js
-swingjs/JSApp.js
-swingjs/JSAppletThread.js
-swingjs/JSAppletViewer.js
-swingjs/JSFocusPeer.js
-swingjs/JSFontMetrics.js
-swingjs/JSFrameViewer.js
-swingjs/JSGraphics2D.js
-swingjs/JSGraphicsConfiguration.js
-swingjs/JSGraphicsEnvironment.js
-swingjs/JSImage.js
-swingjs/JSImagekit.js
-swingjs/JSMouse.js
-swingjs/JSNullComponentPeer.js
-swingjs/JSScreenDevice.js
-swingjs/JSThreadGroup.js
-swingjs/JSToolkit.js
-swingjs/JSUtil.js
-swingjs/plaf/ButtonListener.js
-swingjs/plaf/DefaultMenuLayout.js
-swingjs/plaf/HTML5LookAndFeel.js
-swingjs/plaf/JSAppletUI.js
-swingjs/plaf/JSButtonUI.js
-swingjs/plaf/JSCheckBoxMenuItemUI.js
-swingjs/plaf/JSCheckBoxUI.js
-swingjs/plaf/JSComboBoxUI.js
-swingjs/plaf/JSComponentUI.js
-swingjs/plaf/JSEventHandler.js
-swingjs/plaf/JSFrameUI.js
-swingjs/plaf/JSGraphicsUtils.js
-swingjs/plaf/JSLabelUI.js
-swingjs/plaf/JSLayeredPaneUI.js
-swingjs/plaf/JSLightweightUI.js
-swingjs/plaf/JSMenuBarUI.js
-swingjs/plaf/JSMenuItemUI.js
-swingjs/plaf/JSMenuUI.js
-swingjs/plaf/JSPanelUI.js
-swingjs/plaf/JSPopupMenuSeparatorUI.js
-swingjs/plaf/JSPopupMenuUI.js
-swingjs/plaf/JSRadioButtonMenuItemUI.js
-swingjs/plaf/JSRadioButtonUI.js
-swingjs/plaf/JSRootPaneUI.js
-swingjs/plaf/JSScrollBarUI.js
-swingjs/plaf/JSScrollPaneUI.js
-swingjs/plaf/JSSeparatorUI.js
-swingjs/plaf/JSSliderUI.js
-swingjs/plaf/JSTextAreaUI.js
-swingjs/plaf/JSTextFieldUI.js
-swingjs/plaf/JSTextUI.js
-swingjs/plaf/JSTextViewUI.js
-swingjs/plaf/JSViewportUI.js
-swingjs/plaf/JSWindowUI.js
-swingjs/plaf/LazyActionMap.js
-swingjs/plaf/Resizer.js
-swingjs/plaf/TextListener.js
-
-
+++ /dev/null
-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
-
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="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<Object,PRESENT>:
-
- [HashSet] makes no guarantees as to the iteration order of the set.
-
-JavaScript's Map object is different. It is basically a LinkedHashMap, so it guarantees iteration
-in order of object addition.
-
-Starting with java2script 3.2.9.v1, these classes use the JavaScript Map object rather than hash codes
-whenever all keys are strictly of JavaScript typeof "string". If any key is introduced that is not a string, the
-implementation falls back to using hash codes, the same as Java.
-
-Note strings created using new String("xxxx") are NOT typeof "string"; they are typeof "object".
-
-The result is significantly faster performance (3-12 x faster) than originally, and up to 3 x faster
-performance in JavaScript than in Java itself. Right. Faster than Java.
-
-The JavaScript Map implementation is implemented UNLESS the constructor used is the one that
-specifies both initial capacity and load factor in their constructor. Thus,
-
-new Hashtable()
-new HashMap()
-new HashMap(16)
-new HashSet()
-
-all use the JavaScript Map. But
-
-new Hashtable(11, 0.75f)
-new HashMap(16, 0.75f)
-new HashSet(16, 0.75f)
-
-do not.
-
-This design allows for opting out of the JavaScript Map use in order to retain the exact behavior of
-iterators in JavaScript as in Java.
-
-
-interning, new String("xxx") vs "xxx"
--------------------------------------
-
-Note that the following are true in JavaScript:
-
-typeof new String("xxxx") == "object"
-typeof "xxxx" == "string"
-var s = "x";typeof ("xxx" + s) == "string"
-
-There is no equivalence to this behavior in Java, where a String is a String is a String.
-
-Be aware that SwingJS does not always create a JavaScript String object using JavaScript's
-new String(...) constructor. It only does this for Java new String("xxxx") or new String(new String()).
-
-In all other cases, new String(...) (in Java) results in a simple "xxxx" string in JavaScript.
-That is, it will be JavaScript typeof "string", not typeof "object".
-
-The reason for this design is that several classes in the Java core use toString()
-methods that return new String(), and those classes that do that would cause a JavaScript error
-if implicitly stringified if new String() returned a JavaScript String object.
-
-This is fine in JavaScript
-
-test1 = function() { return { toString:function(){ return "OK" } } }
-"testing" + new test1()
->> "testingOK"
-
-But for whatever reason in JavaScript:
-
-test2 = function() { return { toString:function(){ return new String("OK") } } }
-"testing" + new test2()
->> Uncaught TypeError: Cannot convert object to primitive value
-
-The lesson here is never to use
-
- return new String("...");
-
-in a Java toString() method. In Java it will be fine; in JavaScript it will also be fine as long as
-that method is never called in JavaScript implicitly in the context of string concatenation.
-
-A note about interning. Consider the following six Java constructions, where we have a == "x";
-
-"xxx"
-"xx" + "x"
-new String("xxx").intern()
-
-new String("xxx")
-"xx" + a.toString()
-"xx" + a
-
-All six of these will return java.lang.String for .getClass().getName().
-However, the first three are String literals, while the last three are String objects.
-Thus:
- "xxx" == "xxx"
- "xxx" == "xx" + "x"
- "xxx" == new String("xxx").intern()
-
-but none of the other three are equivalent to "xxx" or each other:
-
- "xxx" != new String("xxx")
- "xxx" != "xx" + a.toString()
- "xxx" != "xx" + a
- new String("xxx") != new String("xxx")
- "xx" + a != new String("xxx")
-
-etc.
-
-As in Java, in SwingJS, all of the following Java assertions pass as true:
-
- assert("xxx" == "xx" + "x");
- assert("xxx" == ("xx" + a).intern());
- assert("xxx" === new String("xxx").intern());
-
-and both of these do as well:
-
- assert(new String("xxx") != "xxx");
- assert(new String("xxx") != new String("xxx"));
-
-But the following two fail to assert true:
-
- assert("xxx" != "xx" + a);
- assert("xxx" != "xx" + a.toString());
-
-because in JavaScript, both of these right-side expressions evaluate to a simple "interned" string.
-
-In Java, however, these assertions are true because Java implicitly "boxes" String
-concatentaion as a String object, not a literal.
-
-Most of us know not to generally use == with Strings unless they are explicitly interned.
-Where this problem may arise, though, is in IdentityHashMap, which compares objects using
-System.identityHashCode(), which is not the same for different objects or their string literal equivalents.
-
-My recommendation, if you need to use IdentityHashMap with strings is to always use an explicit String.intern()
-for any keys -- unless you really want to keep every string as separate keys even if they are the same sequence,
-in which case, use new String(). This will work in Java and in JavaScript.
-
-Be aware when working with strings that come from SwingJS and are being used by other JavaScript modules
-that those that are String objects will return "object" for the JavaScript typeof operator, not "string".
-
-The easy way to ensure this is no problem is to concatenate strings with "" to force immediate interning:
-
- var x = aJavaObject.getString() + "";
-
-unless you are certain that the string is being returned is a raw JavaScript string.
-
-Names with "$" and "_"
-----------------------
-
-For the most part, this should be no problem.
-
-Note that the use of $ and _ in Java field names has always been discouraged:
-[https://docs.oracle.com/javase/tutorial/java/nutsandbolts/variables.html]
-
- You may find some situations where auto-generated names will contain the dollar sign,
- but your variable names should always avoid using it. A similar convention
- exists for the underscore character; while it's technically legal to begin your
- variable's name with "_", this practice is discouraged.
-
-Some impacts of transpiling method names with full qualification:
-
-1) SwingJS will introduce fields that start with $ or _. These will not conflict
- if the above convention is followed.
-
-2) Fields that have the same Java name as a method are not an issue.
-
-3) Fields that have a Java name with $ that matches a transpiled method name,
- such as toString$, will need to be refactored in Java to not have that name collision.
-
-4) Fields in a subclass that have the same name as private fields in a superclass
- represent a name collision, because the superclass method needs to call its private
- field even if invoked from a subclass. The solution was to modify the subclass field
- name using one or more prepended $.
-
-5) Use of Class.getDeclaredMethods() reflection will return Method objects having the transpiled
- name, not the Java name. This could require some j2sNative adjustment
- to strip the $... parameters from the name if that is needed.
-
-6) Use of Method.getParameterTypes() should work fine, provided class names
- do not contain "_". This is because the transpiler converts "." to "_" when
- creating the fully qualified JavaScript name.
-
-
-positive integers do not add to give negative numbers
------------------------------------------------------
-
-In Java, the following is true:
-
- 2000000000 + 2000000000 == -294967296
-
-But in SwingJS, that will be 4000000000. So, for example, the following
-strategy will fail in SwingJS:
-
- int newLength = lineBuf.length * 2;
- if (newLength < 0) {
- newLength = Integer.MAX_VALUE;
- }
-
-"-1" in JavaScript is not 0xFFFFFFFF.
-
-And one must take care to not compare a negative number with a 32-bit mask. So
-
-(b & 0xFF000000) == 0xFF000000
-
-is true in Java for (int) b = -1, but is false in JavaScript, because 0xFF000000 is 4278190080,
-while (-1 & 0xFF000000) is, strangely enough, -16777216, and, in fact,
-
-(0xFF000000 & 0xFF000000) != 0xFF000000
-
-because -16777216 is not 4278190080.
-
-The fix is that one must compare similar operations:
-
-if ((b & 0xFF000000) == (0xFF000000 & 0xFF000000)) .....
-
-Importantly, the JavaScript Int32Array does behave properly. From
-the Firefox developer console:
-
->> x = new Int32Array(1)
-<- Int32Array(1) [ 0 ]
->> x[0] = 4000000000
-<- 4000000000
->> x[0]
-<- -294967296
-
-Notice that, perhaps unexpectedly, the following two constructs produce
-different results in JavaScript:
-
-x = new Int32Array(1);
-b = x[0] = 4000000000;
-
-(b will be 4000000000)
-
-and
-
-x = new Int32Array(1);
-x[0] = 4000000000;
-b = x[0];
-
-(b will be -294967296)
-
-
-SwingJS leverages array typing to handle all byte and short arithmetic so as
-to ensure that any byte or short operation in JavaScript does give the same
-result in Java. The design decision to not also do this with integer math was
-a trade-off between performance and handling edge cases.
-
-
-ArrayIndexOutOfBounds
----------------------
-
-You cannot implicitly throw an ArrayIndexOutOfBoundsException in JavaScript.
-JavaScript will simply return "undefined", not throw an Exception. So:
-
-boolean notAGoodIdeaIsOutOfBounds(String[] sa, int i) {
- try {
- return (sa[i] == sa[i]);
- } catch (ArrayIndexOutOfBoundsException e) {
- return false;
- }
-}
-
-will work in Java but not in JavaScript. Code should not depend upon this sort
-of trap anyway, if you ask me.
-
-Throwable vs Error vs Exception
--------------------------------
-
-True JavaScript errors are trapped as Throwable, whereas you can still trap
-Error and Exception as well. So if you want to be sure to catch any JavaScript
-error, use try{}catch (Throwable t){}, not try{}catch (Exception e){}.
-
-j
-ava.awt.Color
---------------
-
-ColorSpace: only "support" CS_sRGB.
-
- TODO -- any volunteers??
-
-
-javax.swing.JFileDialog
------------------------
-
-HTML5 cannot expose a file reading directory structure. But you certainly
-can still do file reading and writing. It just works a little differently.
-It's a simple modification:
-
- b = new JButton("FileOpenDialog");
- b.addActionListener(new ActionListener() {
-
- @Override
- public void actionPerformed(ActionEvent e) {
- JFileChooser fc = new JFileChooser();
- Test_Dialog.this.onDialogReturn(fc.showOpenDialog(Test_Dialog.this));
- // Java will wait until the dialog is closed, then enter the onDialogReturn method.
- // JavaScript will exit with NaN immediately, and then call back with its actual value
- // asynchronously.
- }
-
- });
-
- public void onDialogReturn(int value) {
- if (value != Math.floor(value))
- return; // in JavaScript, this will be NaN, indicating the dialog has been opened
- // If we are here, the dialog has closed, in both Java and JavaScript.
- System.out.println("int value is " + value);
- }
-
-
- @Override
- public void propertyChange(PropertyChangeEvent event) {
- Object val = event.getNewValue();
- String name = event.getPropertyName();
- System.out.println(name);
- switch (event.getSource().getClass().getName()) {
- case "javax.swing.JOptionPane":
- switch (name) {
- case "inputValue":
- onDialogReturn(val);
- return;
- case "value":
- if (val instanceof Integer)
- onDialogReturn(((Integer) val).intValue());
- else
- onDialogReturn(val);
- return;
- }
- break;
- case "javax.swing.ColorChooserDialog":
- switch (name) {
- case "SelectedColor":
- onDialogReturn(val);
- return;
- }
- break;
- case "javax.swing.JFileChooser":
- switch (name) {
- case "SelectedFile":
- File file = (File) val;
- byte[] array = (val == null ? null : /** @j2sNative file.秘bytes || */
- null);
- onDialogReturn("fileName is '" + file.getName() + "'\n\n" + new String(array));
- return;
- }
- break;
- }
- System.out.println(
- event.getSource().getClass().getName() + " " + event.getPropertyName() + ": " + event.getNewValue());
- }
-
-
-Developers are encouraged to create a separate class that handles general calls to JFileDialog.
-An example class can be found in the SwingJS distribution as
-
-/sources/net.sf.j2s.java.core/src/javajs/async/AsyncFileChooser.java.
-
-
-javax.swing.JOptionPane dialogs
--------------------------------
-
-For this action to work, the parentComponent must implement
-propertyChangeListener, and any call to JOptionPanel should allow for
-an asynchronous response, meaning that there is no actionable code following the
-call to the dialog opening.
-
-In addition, for compatibility with the Java version, implementation should
-wrap the call to getConfirmDialog or getOptionDialog in a method call to
-handle the Java:
-
-onDialogReturn(JOptionPane.showConfirmDialog(parentFrame,
-messageOrMessagePanel, "title", JOptionPane.OK_CANCEL_OPTION));
-
-Then parentFrame.propertyChange(event) should also call onDialogReturn.
-
-This will then work in both Java and JavaScript.
-
-Note that there is an int and an Object version of onDialogReturn().
-
-
-In JavaScript:
-
-The initial return from JOptionPane.showConfirmDialog and showMessageDialog
-will be (SwingJS) JDialog.ASYNCHRONOUS_INTEGER (NaN), testable as an impossible
-Java int value using ret != -(-ret) if the parent implements PropertyChangeListener, or -1
-(CLOSE_OPTION) if not.
-
-For showOptionDialog (which returns Object) or showInputDialog (which returns
-String), the initial return will be (SwingJS) JDialog.ASYNCHRONOUS_OBJECT, testable as
-((Object) ret) instanceof javax.swing.plaf.UIResource if the parent implements
-PropertyChangeListeneer, or null if not.
-
-The second return will be the desired return.
-
-In Java:
-
-The initial return will be the one and only modal final return.
-
-
-
-For full compatibility, The calling method must not continue beyond this
-call.
-
-All of the standard Java events associated with Components are also
-available.
-
-Certain fall back mechanisms are possible, where onReturn does not exist, but
-only for the following cases:
-
-
-For showMessageDialog, for WARNING_MESSAGE and ERROR_MESSAGE, a simple
-JavaScript alert() is used, returning 0 (OK_OPTION) or -1 (CLOSED_OPTION).
-
-For showInputDialog, if the message is a string, a simple JavaScript prompt()
-with input box is used, returning the entered string or null.
-
-For showConfirmDialog, a simple JavaScript confirm() is used, in which case:
-
-for YES_NO_OPTION: YES_OPTION or NO_OPTION
-
-for YES_NO_CANCEL_OPTION: YES_OPTION or CANCEL_OPTION
-
-for OK_CANCEL_OPTION or any other: OK_OPTION or CANCEL_OPTION
-
-Note that you should implement a response for CLOSED_OPTION for
-showConfirmDialog. For other dialogs, a null return indicates the dialog was
-closed, just as for Java.
-
-Developers are encouraged to create a separate class that handles general calls.
-An example class can be found in the SwingJS distribution as src/javajs/async/AsyncDialog.java.
-Very simple modifications to the Java allows asynchronous operation using AsyncDialog. Here
-is a simple "do you want to close this frame" example, where you can see that what we have
-done is to set the reply into an ActionListener that is defined in the constructor of
-the AsyncDisplay object:
-
-// Original:
-//
-// private void promptQuit() {
-// int sel = JOptionPane.showConfirmDialog(null, PROMPT_EXIT, NAME, JOptionPane.YES_NO_OPTION);
-// switch (sel) {
-// case JOptionPane.YES_OPTION:
-// resultsTab.clean();
-// seqs.dispose();
-// if (fromMain) {
-// System.exit(0);
-// }
-// break;
-// }
-// }
-
- private void promptQuitAsync() {
- new AsyncDialog(new ActionListener() {
-
- @Override
- public void actionPerformed(ActionEvent e) {
- int sel = ((AsyncDialog)e.getSource()).getOption();
- switch (sel) {
- case JOptionPane.YES_OPTION:
- resultsTab.clean();
- seqs.dispose();
- if (fromMain) {
- System.exit(0);
- }
- break;
- }
- }}).showConfirmDialog(null, PROMPT_EXIT, NAME, JOptionPane.YES_NO_OPTION);
- }
-
-Very simple!
-
-
-native methods
---------------
-
-The J2S compiler ignores all static native method declarations.
-Anything of this nature needs to be implemented in JavaScript if it is needed,
-using j2sNative blocks:
-
-/**
- * @j2sNative
- *
- * var putYourJavaScriptCodeHere
- *
- */
-
- Note that if you follow that directly with a {...} block, then
- the javadoc code will run in JavaScript, and the {...} code will run in Java.
-
-
-key Focus
----------
-
-As of June, 2019, the keyboard focus manager is fully implemented.
-The one catch is that JTextPane and JTextArea, which already consume
-VK_TAB in Java, cannot use CTRL-TAB to continue a tabbing cycle around
-the components in a window. Instead, CTRL-TAB is absorbed by the browser.
-
-
-LookAndFeel and UI Classes
---------------------------
-
-SwingJS implements the native browser look and feel as swingjs.plaf.HTML5LookAndFeel.
-There are small differences between all look and feels -- MacOS, Windows, SwingJS.
-
-Expert developers know how to coerce changes in the UI by subclassing the UI for a
-component. This probably will not work in SwingJS.
-
-Note that LookAndFeel in Java usually determines canvas size in a Frame because
-different operating systems (Mac OS vs Windows vs HTML5) will have
-different edge sizes on their frames. If you want to ensure a component size,
-use getContentPane().setPreferredSize().
-
-
-System.exit(0) does not stop all processes
-------------------------------------------
-
-Although System.ext(int) has been implemented in JavaScript, it just closes the
-frames, stops all pending javax.swing.Timer objects in the queue, and runs any
-threads added using Runtime.getRuntime().addShutdownHook(Thread).
-It may not stop all "threads." So don't rely on that.
-Applications are responsible for shutting down prior to executing System.exit(0).
-
-
-myClass.getField not implemented
---------------------------------
-
-java.lang.reflect.Field is implemented minimally. It is not
-certain that Field.getDeclaringClass() will work. If you just want a
-value of a field, you can do this:
-
-/**
- *@j2sNative
- *
- * return myClass[name]
- */
-
-But that is not a java.lang.reflection.Field object.
-
-
-"window" and other reserved JavaScript names
---------------------------------------------
-
-No reserved top-level JavaScript name is allowed for a package name. So, for example,
-one must rename packages such as "window" or "document" to names such as "win" or "doc".
-
-reserved field and method names
--------------------------------
-
-In order to minimize the chance of added SwingJS field and method names colliding with ones
-developers might use in subclassing Java classes, we have added U+79D8 (first character of Mandarin
-"secret") to the characters already disrecommended by Java documentation ("$" and "_"). The only problem
-would be if you use that character followed by certain English words in certain classes. For example
-\u79D8canvas for JComponents (in java.awt.JSComponent) and \u79D8byte (in java.io.File).
-
-qualified field and method names
---------------------------------
-
-Method names in SwingJS are fully qualified, meaning two methods with the same Java name but different
-parameters, such as write(int) and write(double), must not have the same name in JavaScript. (In this
-case, we will have write$I and write$D.) However, in certain cases it may be desirable to leave the
-method names unqualified. In particular, when an interface actually represents a JavaScript object,
-the transpiler can leave a method name unqualified. The default situation for this is a class name
-includes ".api.js" (case-sensitive). This means that any method in any class in a package js within
-a package api, or any private interface js that has an outer interface api, will have all-unqualified
-methods. An example of this is swingjs.plaf.JSComboPopupList, which needs to communicate with a jQuery
-object directly using the following interface:
-
- private interface api {
-
- interface js extends JQueryObject {
-
- abstract js j2sCB(Object options);
-
- abstract Object[] j2sCB(String method);
-
- abstract Object[] j2sCB(String method, Object o);
-
- abstract Object[] j2sCB(String method, int i);
-
- abstract int j2sCB(String OPTION, String name);
-
- }
- }
-
-Notice that all these variants of j2sCB() will call the same method in JavaScript by design.
-
-
-missing Math methods
---------------------
-
-java.lang.Math is worked out, but some methods are missing, either because they
-involve long integer value that are inaccessible in JavaScript, or because I just
-didn't implement them. This is a result of continued Java development.
-It is easy enough to add these methods if you have the source. They go into j2sClazz.js,
-which is combined with other initial libraries into swingjs2.js by build_site.xml
-
-
-Component.getGraphics(), Graphics.dispose()
--------------------------------------------
-
-Use of component.getGraphics() is discouraged in Java and in SwingJS.
-Specifically in SwingJS, any call to component.getGraphics() or
-BufferedImage.createGraphics() or Graphics.create(...) should be matched with graphics.dispose(),
-particularly when it is called outside the context of a paint(Graphics)
-call from the system.
-
-If you see your graphics scrolling down the page with each repaint,
-look for where you have used Component.getGraphics() and not Graphics.dispose().
-For example, this will definitely NOT work in SwingJS:
-
- this.paint(getGraphics())
-
-and really should not work in Java, either, as it is technically a resource memory leak.
-
-Instead, if you really do not want to use repaint(), use this:
-
- Graphics g = getGraphics();
- paint(g);
- g.dispose();
-
-
-
-Graphics.setClip()
-------------------
-
-The HTML5 canvas.clip() method is permanent. You can only reset the clip using
-save/restore. This is different from Java, where you can temporarily change it using
-
- Shape oldClip = Graphics.getClip();
- Graphics.setClip(newClip);
- ...
- Graphics.setClip(oldClip);
-
-If you need to do something like this, you must schedule the paints
-to not have overlapping clip needs.
-
-
-MAJOR ISSUES--for Bob and Udo within SwingJS
-============================================
-
-fonts
------
-
-Fonts and FontMetrics will all be handled in JavaScript. Font matching will
-not be exact, and composite (drawn) fonts will not be supported.
-
-SwingJS handles calls such as font.getFontMetrics(g).stringWidth("xxx") by
-creating a <div> containing that text, placing it in an obscure location on
-the page, and reading div.getBoundingClientRect(). This is a VERY precise
-value, but can be a pixel or two off from what Java reports for the same font.
-
-
-OS-dependent classes
---------------------
-
-Static classes such as:
-
- java.awt.Toolkit
- java.awt.GraphicsEnvironment
-
-
-which are created using Class.forName are implemented using classes in the swingjs package.
-
-AWTAccessor is not implemented.
-
-
-AWT component peers and component "ui" user interfaces
-------------------------------------------------------
-
-ComponentPeer is a class that represents a native AWT component.
-Components with such peers are called "heavy-weight" components.
-They are expected to do the dirty work of graphics drawing.
-
-Java Swing implements peers only for JApplet, JDialog, JFrame, and JWindow.
-References to such objects have been removed, but clearly there must be
-some connection to similar DOM objects, even for "light-weight" components.
-
-
-
-MAJOR ISSUES--to be resolved by implementers
-============================================
-
-fonts
------
-
-Glyph/composite/outline fonts are not supported.
-
-
-
-threads
--------
-
-Thread locking and synchronization are not relevant to JavaScript.
-Thus, anything requiring "notify.." or "waitFor.." could be a serious issue.
-
-All threading must be "faked" in JavaScript. Specifically not available is:
-
- Thread.sleep()
-
-javax.swing.AbstractButton#doClick(pressTime) will not work, as it requires Thread.sleep();
-
-However, java.lang.Thread itself is implemented and used extensively.
-
-Methods thread.start() and thread.run() both work fine.
-
-For simple applications that use Thread.sleep() just to have a delay, as in a frame rate, for
-example, one can use javax.swing.Timer instead. That is fully implemented.
-
-Likewise, java.util.Timer can be replaced with no loss of performance with javax.Swing.Timer.
-Note that java.util.TimerTask is implemented, but it can also be replaced by an implementation of Runnable.
-
-task = new TimerTask(){....};
-t = new java.util.Timer();
-t.schedule(task, 0, 1);
-
-becomes
-
-task = new TimerTask(){....}; // or task = new Runnable() {...}
-t = new javax.swing.Timer(1, new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- task.run();
- }
-};
-t.setInitialDelay(0); // not particularly necessary
-t.start();
-
-In addition, SwingJS provides swingjs.JSThread, which can be subclassed
-if desired. This class allows simple
-
- while(!interrupted()){
- wait()
- ...
- }
-
-action through an asynchronous function run1(mode). For example:
-
- protected void run1(int mode) {
- try {
- while (true)
- switch (mode) {
- case INIT:
- // once-through stuff here
- mode = LOOP;
- break;
- case LOOP:
- if (!doDispatch || isInterrupted()) {
- mode = DONE;
- } else {
- Runnable r = new Runnable() {
- public void run() {
- // put the loop code here
- }
- };
- dispatchAndReturn(r);
- if (isJS)
- return;
- }
- break;
- // add more cases as needed
- case DONE:
- // finish up here
- if (isInterrupted())
- return;
- // or here
- break;
- }
- } finally {
- // stuff here to be executed after each loop in JS or at the end in Java
- }
- }
-
-image loading
--------------
-- All image loading in SwingJS is synchronous. A MediaTracker call will immediately return "complete".
- However, it still may take one system clock tick to fully load images. Thus, it is recommended that
- images be preloaded in the static block of the applet if it is necessary that they be available in init().
- This is only an issue if you are trying to access the pixel buffer of the image in JavaScript.
-
-- Applet.getImage(path, name) will return null if the image does not exist.
-
-- BufferedImage: only "support" imageType RGB and ARGB
-
- -BH: This is a temporary edit, just to get us started. Certainly GRAY will be needed
-
-
-BigInteger and BigDecimal
--------------------------
-
-java.math.BigInteger is fully supported; java.math.BigDecimal is roughed
-in and not fully tested (07/2019).
-
-Both classes present significant issues for JavaScript, as they are based in
-Java's 64-bit long for all their operations. Here is the JavaDoc note I added
-to BigInteger:
-
- * SwingJS note: Because of the limitations of JavaScript with regard
- * to long-integer bit storage as a double, this implementation drops
- * the integer storage bit length to 24, giving 48 for long and leaving
- * the last 16 bits clear for the exponent of the double number. This should
- * not affect performance significantly. It does increase the storage
- * size by about 33%. By bringing an "int" to 3 bytes, we can easily construct
- * and use byte[] data intended for the original BitSet.
-
-"Easily" may be a bit strong there. This was a serious challenge.
-
-BigDecimal seems to run normally, but in order to do that, my hack involves
-reducing the size of an integer that is allowed to be stored as such and not
-in byte[] as a BigInteger. I'm sure there is a performance hit, but it does work.
-
-no format internationalization
-------------------------------
-
-For now, just en for number and date formatters
-
-no winding rules
-----------------
-
- When filling a graphic, only nonzero winding rule is implemented in HTML5 Canvas2D.
-
-
-
-text-related field implementation
----------------------------------
-
-Text fields are:
-
-JTextField (JavaScript <input type="text">)
-JTextArea (JavaScript <textarea>)
-JTextPane (JavaScript <div>)
-JEditorPane (JavaScript <div>)
-
-For the initial implementation, we don't implement infinite undo/redo, and the abstract
-document model is much less elaborate. Only PlainDocument (in the form of JSPlainDocument)
-is implemented. The Document returned by JTextField.getDocument() is a javax.swing.text.Document.
-
-All scrolling is handled by HTML5. javax.swing.AutoScroller is not implemented.
-public static methods .stop, .isRunning, .processMouseDragged require true Java threading
-and so are not implmented. javax.swing.text.View and its subclasses are not implemented.
-
-The JS document model does not allow two text fields to address the same underlying document.
-
-JavaScript is slightly different from Java in that the field value is changed asynchronously after
-the keypressed event, so Java actions that are keyed to KEY_PRESSED may not pick up the new
-key value even after SwingUtilities.invokeLater() is called. Thus, key pressed actions may need
-to be recorded after a key released event instead.
-
-Formatter/Regex limitations
----------------------------
-
-Some browsers cannot process Regex "look-behind" process such as (?<=\W)
-java.util.regex.Matcher and Pattern use JavaScript's RegExp object rather than
-the native Java object. These are not identical. Only flags /igm are supported.
-Matcher.start(groupID) is not supported.
-
-java.util.Formatter will function correctly for all standard %... patterns.
-
-integer 1/0 == Infinity
------------------------
-
-1/0 in Java throws "java.lang.ArithmeticException: / by zero", but in JavaScript is just Infinity.
-
-
-
-Summary
--------
-
-These are all the known limitations of SwingJS. We have not found any of these limitations
-to be show-stoppers. The primary issue for newcomers to SwingJS is having the source code.
-You must check that source code for all your library jar files is available or, if you
-choose, you will need to decompile those classes. We have used decompilation on some projects,
-and it works just fine. So, technically, all we really need are JAR/class files. But the
-source is by far superior. It's generally prettier, and it has the license information that
-may or may not be present with the JAR or class files. Use class files at your own risk.
-
-Bob Hanson
-2019.08.16
-
-
-Additional Issues
------------------
-
-Annotation is working for classes, methods, and fields (12/22/19). Method reflection, however,
-is limited. Interfaces do not expose their methods, as the transpiler does not actually transpile
-the interfaces themselves. And method reflection only includes annotated methods.
-
-java.util.concurrent is not fully elaborated. This package is rewritten to not actually use the
-memory handling capabilities of concurrency, which JavaScript does not have access to.
-
-System.getProperties() just returns a minimal set of properties.
-
-
+++ /dev/null
-20201222130550
+++ /dev/null
-This is sources/net.sf.j2s.java.core/dist/DEV_NOTES.txt
-
-_j2sclasslist.txt
-
-the list of .js files concatenated into coreswingjs.js and minified to coreswingjs.z.js
-
-
-SwingJS-site.zip
-
-the full site directory for SwingJS including all files not in the test/ directory.
+++ /dev/null
-java/applet/Applet.js
-java/applet/AppletContext.js
-java/applet/AppletStub.js
-java/applet/JSApplet.js
-java/awt/ActiveEvent.js
-java/awt/Adjustable.js
-java/awt/AWTEvent.js
-java/awt/AWTEventMulticaster.js
-java/awt/AWTKeyStroke.js
-java/awt/BasicStroke.js
-java/awt/BorderLayout.js
-java/awt/Button.js
-java/awt/Color.js
-java/awt/color/ColorSpace.js
-java/awt/Component.js
-java/awt/ComponentOrientation.js
-java/awt/ContainerOrderFocusTraversalPolicy.js
-java/awt/Container.js
-java/awt/Cursor.js
-java/awt/DefaultFocusTraversalPolicy.js
-java/awt/DefaultKeyboardFocusManager.js
-java/awt/Dialog.js
-java/awt/Dimension.js
-java/awt/dnd/peer/DropTargetPeer.js
-java/awt/event/ActionListener.js
-java/awt/event/AdjustmentEvent.js
-java/awt/event/AdjustmentListener.js
-java/awt/event/AWTEventListener.js
-java/awt/event/ComponentAdapter.js
-java/awt/event/ComponentEvent.js
-java/awt/event/ComponentListener.js
-java/awt/event/ContainerListener.js
-java/awt/event/FocusEvent.js
-java/awt/event/FocusListener.js
-java/awt/event/HierarchyBoundsListener.js
-java/awt/event/HierarchyListener.js
-java/awt/event/InputEvent.js
-java/awt/event/InputMethodListener.js
-java/awt/event/InvocationEvent.js
-java/awt/event/ItemEvent.js
-java/awt/event/ItemListener.js
-java/awt/event/KeyListener.js
-java/awt/event/MouseEvent.js
-java/awt/event/MouseListener.js
-java/awt/event/MouseMotionListener.js
-java/awt/event/MouseWheelListener.js
-java/awt/event/TextListener.js
-java/awt/event/WindowAdapter.js
-java/awt/event/WindowEvent.js
-java/awt/event/WindowFocusListener.js
-java/awt/event/WindowListener.js
-java/awt/event/WindowStateListener.js
-java/awt/EventDispatchThread.js
-java/awt/EventFilter.js
-java/awt/EventQueue.js
-java/awt/EventQueueItem.js
-java/awt/FlowLayout.js
-java/awt/FocusTraversalPolicy.js
-java/awt/Font.js
-java/awt/font/FontRenderContext.js
-java/awt/FontMetrics.js
-java/awt/Frame.js
-java/awt/geom/AffineTransform.js
-java/awt/geom/Dimension2D.js
-java/awt/geom/Path2D.js
-java/awt/geom/PathIterator.js
-java/awt/geom/Point2D.js
-java/awt/geom/Rectangle2D.js
-java/awt/geom/RectangularShape.js
-java/awt/geom/RectIterator.js
-java/awt/GraphicsCallback.js
-java/awt/GraphicsConfiguration.js
-java/awt/GraphicsDevice.js
-java/awt/GraphicsEnvironment.js
-java/awt/Image.js
-java/awt/image/ImageObserver.js
-java/awt/Insets.js
-java/awt/ItemSelectable.js
-java/awt/JSComponent.js
-java/awt/JSDialog.js
-java/awt/JSFrame.js
-java/awt/JSPanel.js
-java/awt/KeyboardFocusManager.js
-java/awt/KeyEventDispatcher.js
-java/awt/KeyEventPostProcessor.js
-java/awt/Label.js
-java/awt/LayoutManager.js
-java/awt/LayoutManager2.js
-java/awt/LightweightDispatcher.js
-java/awt/Paint.js
-java/awt/Panel.js
-java/awt/peer/ComponentPeer.js
-java/awt/peer/ContainerPeer.js
-java/awt/peer/FramePeer.js
-java/awt/peer/KeyboardFocusManagerPeer.js
-java/awt/peer/LightweightPeer.js
-java/awt/peer/WindowPeer.js
-java/awt/Point.js
-java/awt/Queue.js
-java/awt/Rectangle.js
-java/awt/RenderingHints.js
-java/awt/Scrollbar.js
-java/awt/ScrollPane.js
-java/awt/Shape.js
-java/awt/Stroke.js
-java/awt/TextArea.js
-java/awt/TextComponent.js
-java/awt/TextField.js
-java/awt/Toolkit.js
-java/awt/Transparency.js
-java/awt/Window.js
-java/beans/ChangeListenerMap.js
-java/beans/PropertyChangeEvent.js
-java/beans/PropertyChangeListener.js
-java/beans/PropertyChangeSupport.js
-java/lang/AbstractStringBuilder.js
-java/lang/Class.js
-java/lang/Enum.js
-java/lang/Iterable.js
-java/lang/reflect/Constructor.js
-java/lang/reflect/Method.js
-java/lang/StringBuffer.js
-java/lang/StringBuilder.js
-java/lang/Thread.js
-java/lang/ThreadGroup.js
-java/math/RoundingMode.js
-java/net/URL.js
-java/net/URLStreamHandlerFactory.js
-java/net/HttpURLConnection.js
-java/net/URLStreamHandler.js
-javax/net/ssl/HttpsUrlConnection.js
-java/text/CharacterIterator.js
-java/text/DecimalFormat.js
-java/text/DecimalFormatSymbols.js
-java/text/DigitList.js
-java/text/FieldPosition.js
-java/text/Format.js
-java/text/NumberFormat.js
-java/util/AbstractCollection.js
-java/util/AbstractList.js
-java/util/AbstractMap.js
-java/util/AbstractSequentialList.js
-java/util/AbstractSet.js
-java/util/ArrayList.js
-java/util/Arrays.js
-java/util/Collection.js
-java/util/Collections.js
-java/util/Comparator.js
-java/util/Deque.js
-java/util/Dictionary.js
-java/util/Enumeration.js
-java/util/EventListener.js
-java/util/EventObject.js
-java/util/HashMap.js
-java/util/HashSet.js
-java/util/Hashtable.js
-java/util/IdentityHashMap.js
-java/util/Iterator.js
-java/util/LinkedHashMap.js
-java/util/LinkedList.js
-java/util/List.js
-java/util/ListResourceBundle.js
-java/util/Locale.js
-java/util/Map.js
-java/util/Objects.js
-java/util/Queue.js
-java/util/Random.js
-java/util/RandomAccess.js
-java/util/ResourceBundle.js
-java/util/Set.js
-java/util/TimSort.js
-java/util/Vector.js
-javajs/api/JSFunction.js
-javajs/util/AjaxURLConnection.js
-javajs/util/AjaxURLStreamHandlerFactory.js
-javajs/util/AU.js
-javajs/util/JSThread.js
-javajs/util/Lst.js
-javajs/util/PT.js
-javajs/util/Rdr.js
-javajs/util/SB.js
-javax/swing/AbstractAction.js
-javax/swing/AbstractButton.js
-javax/swing/AbstractListModel.js
-javax/swing/Action.js
-javax/swing/ActionMap.js
-javax/swing/AncestorNotifier.js
-javax/swing/ArrayTable.js
-javax/swing/border/AbstractBorder.js
-javax/swing/border/BevelBorder.js
-javax/swing/border/Border.js
-javax/swing/border/CompoundBorder.js
-javax/swing/border/EmptyBorder.js
-javax/swing/border/EtchedBorder.js
-javax/swing/border/LineBorder.js
-javax/swing/border/TitledBorder.js
-javax/swing/BorderFactory.js
-javax/swing/BoundedRangeModel.js
-javax/swing/BoxLayout.js
-javax/swing/ButtonGroup.js
-javax/swing/ButtonModel.js
-javax/swing/ClientPropertyKey.js
-javax/swing/ComboBoxModel.js
-javax/swing/DefaultBoundedRangeModel.js
-javax/swing/DefaultButtonModel.js
-javax/swing/DefaultComboBoxModel.js
-javax/swing/DefaultSingleSelectionModel.js
-javax/swing/DropMode.js
-javax/swing/event/AncestorEvent.js
-javax/swing/event/AncestorListener.js
-javax/swing/event/CaretEvent.js
-javax/swing/event/CaretListener.js
-javax/swing/event/ChangeEvent.js
-javax/swing/event/ChangeListener.js
-javax/swing/event/DocumentEvent.js
-javax/swing/event/DocumentListener.js
-javax/swing/event/EventListenerList.js
-javax/swing/event/ListDataEvent.js
-javax/swing/event/ListDataListener.js
-javax/swing/event/UndoableEditEvent.js
-javax/swing/event/UndoableEditListener.js
-javax/swing/FocusManager.js
-javax/swing/InternalFrameFocusTraversalPolicy.js
-javax/swing/LayoutComparator.js
-javax/swing/LayoutFocusTraversalPolicy.js
-javax/swing/SortingFocusTraversalPolicy.js
-javax/swing/SwingContainerOrderFocusTraversalPolicy.js
-javax/swing/SwingDefaultFocusTraversalPolicy.js
-javax/swing/Icon.js
-javax/swing/ImageIcon.js
-javax/swing/InputMap.js
-javax/swing/JApplet.js
-javax/swing/JButton.js
-javax/swing/JCheckBox.js
-javax/swing/JCheckBoxMenuItem.js
-javax/swing/JComboBox.js
-javax/swing/JComponent.js
-javax/swing/JFrame.js
-javax/swing/JLabel.js
-javax/swing/JLayeredPane.js
-javax/swing/JMenu.js
-javax/swing/JMenuBar.js
-javax/swing/JMenuItem.js
-javax/swing/JPanel.js
-javax/swing/JPopupMenu.js
-javax/swing/JRadioButtonMenuItem.js
-javax/swing/JRootPane.js
-javax/swing/JScrollBar.js
-javax/swing/JScrollPane.js
-javax/swing/JSeparator.js
-javax/swing/JTextArea.js
-javax/swing/JTextField.js
-javax/swing/JToggleButton.js
-javax/swing/JViewport.js
-javax/swing/KeyboardManager.js
-javax/swing/KeyStroke.js
-javax/swing/ListModel.js
-javax/swing/LookAndFeel.js
-javax/swing/MenuElement.js
-javax/swing/MutableComboBoxModel.js
-javax/swing/plaf/ActionMapUIResource.js
-javax/swing/plaf/basic/BasicBorders.js
-javax/swing/plaf/BorderUIResource.js
-javax/swing/plaf/ColorUIResource.js
-javax/swing/plaf/ComponentUI.js
-javax/swing/plaf/DimensionUIResource.js
-javax/swing/plaf/FontUIResource.js
-javax/swing/plaf/InputMapUIResource.js
-javax/swing/plaf/InsetsUIResource.js
-javax/swing/plaf/UIResource.js
-javax/swing/RepaintManager.js
-javax/swing/RootPaneContainer.js
-javax/swing/Scrollable.js
-javax/swing/ScrollPaneConstants.js
-javax/swing/ScrollPaneLayout.js
-javax/swing/SingleSelectionModel.js
-javax/swing/SizeRequirements.js
-javax/swing/SwingConstants.js
-javax/swing/SwingPaintEventDispatcher.js
-javax/swing/SwingUtilities.js
-javax/swing/text/AbstractDocument.js
-javax/swing/text/AttributeSet.js
-javax/swing/text/Caret.js
-javax/swing/text/DefaultCaret.js
-javax/swing/text/DefaultEditorKit.js
-javax/swing/text/Document.js
-javax/swing/text/EditorKit.js
-javax/swing/text/Element.js
-javax/swing/text/GapContent.js
-javax/swing/text/GapVector.js
-javax/swing/text/JTextComponent.js
-javax/swing/text/MutableAttributeSet.js
-javax/swing/text/PlainDocument.js
-javax/swing/text/PlainView.js
-javax/swing/text/Position.js
-javax/swing/text/Segment.js
-javax/swing/text/SegmentCache.js
-javax/swing/text/SimpleAttributeSet.js
-javax/swing/text/Style.js
-javax/swing/text/StyleConstants.js
-javax/swing/text/StyleContext.js
-javax/swing/text/TabExpander.js
-javax/swing/text/TextAction.js
-javax/swing/text/Utilities.js
-javax/swing/text/View.js
-javax/swing/tree/TreeNode.js
-javax/swing/UIDefaults.js
-javax/swing/UIManager.js
-javax/swing/undo/AbstractUndoableEdit.js
-javax/swing/undo/CompoundEdit.js
-javax/swing/undo/UndoableEdit.js
-javax/swing/ViewportLayout.js
-javax/swing/WindowConstants.js
-sun/awt/AppContext.js
-sun/awt/AWTAutoShutdown.js
-sun/awt/CausedFocusEvent.js
-sun/awt/ComponentFactory.js
-sun/awt/KeyboardFocusManagerPeerProvider.js
-sun/awt/MostRecentKeyValue.js
-sun/awt/MostRecentThreadAppContext.js
-sun/awt/PaintEventDispatcher.js
-sun/awt/PostEventQueue.js
-sun/awt/RequestFocusController.js
-sun/awt/SunToolkit.js
-sun/awt/WindowClosingListener.js
-sun/awt/WindowClosingSupport.js
-sun/awt/image/DataStealer.js
-sun/awt/image/IntegerComponentRaster.js
-sun/awt/image/IntegerInterleavedRaster.js
-sun/awt/image/SunWritableRaster.js
-sun/font/FontDesignMetrics.js
-sun/swing/DefaultLookup.js
-sun/swing/SwingLazyValue.js
-sun/text/resources/FormatData.js
-sun/text/resources/en/FormatData_en.js
-sun/util/resources/LocaleData.js
-sun/util/locale/BaseLocale.js
-sun/util/locale/LocaleUtils.js
-sun/util/locale/provider/LocaleProviderAdapter.js
-sun/util/locale/provider/LocaleDataMetaInfo.js
-swingjs/a2s/A2SContainer.js
-swingjs/a2s/A2SEvent.js
-swingjs/a2s/A2SListener.js
-swingjs/a2s/Applet.js
-swingjs/a2s/Button.js
-swingjs/a2s/Label.js
-swingjs/a2s/Panel.js
-swingjs/a2s/Scrollbar.js
-swingjs/a2s/ScrollPane.js
-swingjs/a2s/TextArea.js
-swingjs/a2s/TextField.js
-swingjs/api/Interface.js
-swingjs/api/js/DOMNode.js
-swingjs/api/js/HTML5CanvasContext2D.js
-swingjs/api/js/JSInterface.js
-swingjs/jquery/JQueryUI.js
-swingjs/JSApp.js
-swingjs/JSAppletThread.js
-swingjs/JSAppletViewer.js
-swingjs/JSFocusPeer.js
-swingjs/JSFontMetrics.js
-swingjs/JSFrameViewer.js
-swingjs/JSGraphics2D.js
-swingjs/JSGraphicsConfiguration.js
-swingjs/JSGraphicsEnvironment.js
-swingjs/JSImage.js
-swingjs/JSImagekit.js
-swingjs/JSMouse.js
-swingjs/JSNullComponentPeer.js
-swingjs/JSScreenDevice.js
-swingjs/JSThreadGroup.js
-swingjs/JSToolkit.js
-swingjs/JSUtil.js
-swingjs/plaf/ButtonListener.js
-swingjs/plaf/DefaultMenuLayout.js
-swingjs/plaf/HTML5LookAndFeel.js
-swingjs/plaf/JSAppletUI.js
-swingjs/plaf/JSButtonUI.js
-swingjs/plaf/JSCheckBoxMenuItemUI.js
-swingjs/plaf/JSCheckBoxUI.js
-swingjs/plaf/JSComboBoxUI.js
-swingjs/plaf/JSComponentUI.js
-swingjs/plaf/JSEventHandler.js
-swingjs/plaf/JSFrameUI.js
-swingjs/plaf/JSGraphicsUtils.js
-swingjs/plaf/JSLabelUI.js
-swingjs/plaf/JSLayeredPaneUI.js
-swingjs/plaf/JSLightweightUI.js
-swingjs/plaf/JSMenuBarUI.js
-swingjs/plaf/JSMenuItemUI.js
-swingjs/plaf/JSMenuUI.js
-swingjs/plaf/JSPanelUI.js
-swingjs/plaf/JSPopupMenuSeparatorUI.js
-swingjs/plaf/JSPopupMenuUI.js
-swingjs/plaf/JSRadioButtonMenuItemUI.js
-swingjs/plaf/JSRadioButtonUI.js
-swingjs/plaf/JSRootPaneUI.js
-swingjs/plaf/JSScrollBarUI.js
-swingjs/plaf/JSScrollPaneUI.js
-swingjs/plaf/JSSeparatorUI.js
-swingjs/plaf/JSSliderUI.js
-swingjs/plaf/JSTextAreaUI.js
-swingjs/plaf/JSTextFieldUI.js
-swingjs/plaf/JSTextUI.js
-swingjs/plaf/JSTextViewUI.js
-swingjs/plaf/JSViewportUI.js
-swingjs/plaf/JSWindowUI.js
-swingjs/plaf/LazyActionMap.js
-swingjs/plaf/Resizer.js
-swingjs/plaf/TextListener.js
-
-
+++ /dev/null
-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
-
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="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<Object,PRESENT>:
-
- [HashSet] makes no guarantees as to the iteration order of the set.
-
-JavaScript's Map object is different. It is basically a LinkedHashMap, so it guarantees iteration
-in order of object addition.
-
-Starting with java2script 3.2.9.v1, these classes use the JavaScript Map object rather than hash codes
-whenever all keys are strictly of JavaScript typeof "string". If any key is introduced that is not a string, the
-implementation falls back to using hash codes, the same as Java.
-
-Note strings created using new String("xxxx") are NOT typeof "string"; they are typeof "object".
-
-The result is significantly faster performance (3-12 x faster) than originally, and up to 3 x faster
-performance in JavaScript than in Java itself. Right. Faster than Java.
-
-The JavaScript Map implementation is implemented UNLESS the constructor used is the one that
-specifies both initial capacity and load factor in their constructor. Thus,
-
-new Hashtable()
-new HashMap()
-new HashMap(16)
-new HashSet()
-
-all use the JavaScript Map. But
-
-new Hashtable(11, 0.75f)
-new HashMap(16, 0.75f)
-new HashSet(16, 0.75f)
-
-do not.
-
-This design allows for opting out of the JavaScript Map use in order to retain the exact behavior of
-iterators in JavaScript as in Java.
-
-
-interning, new String("xxx") vs "xxx"
--------------------------------------
-
-Note that the following are true in JavaScript:
-
-typeof new String("xxxx") == "object"
-typeof "xxxx" == "string"
-var s = "x";typeof ("xxx" + s) == "string"
-
-There is no equivalence to this behavior in Java, where a String is a String is a String.
-
-Be aware that SwingJS does not always create a JavaScript String object using JavaScript's
-new String(...) constructor. It only does this for Java new String("xxxx") or new String(new String()).
-
-In all other cases, new String(...) (in Java) results in a simple "xxxx" string in JavaScript.
-That is, it will be JavaScript typeof "string", not typeof "object".
-
-The reason for this design is that several classes in the Java core use toString()
-methods that return new String(), and those classes that do that would cause a JavaScript error
-if implicitly stringified if new String() returned a JavaScript String object.
-
-This is fine in JavaScript
-
-test1 = function() { return { toString:function(){ return "OK" } } }
-"testing" + new test1()
->> "testingOK"
-
-But for whatever reason in JavaScript:
-
-test2 = function() { return { toString:function(){ return new String("OK") } } }
-"testing" + new test2()
->> Uncaught TypeError: Cannot convert object to primitive value
-
-The lesson here is never to use
-
- return new String("...");
-
-in a Java toString() method. In Java it will be fine; in JavaScript it will also be fine as long as
-that method is never called in JavaScript implicitly in the context of string concatenation.
-
-A note about interning. Consider the following six Java constructions, where we have a == "x";
-
-"xxx"
-"xx" + "x"
-new String("xxx").intern()
-
-new String("xxx")
-"xx" + a.toString()
-"xx" + a
-
-All six of these will return java.lang.String for .getClass().getName().
-However, the first three are String literals, while the last three are String objects.
-Thus:
- "xxx" == "xxx"
- "xxx" == "xx" + "x"
- "xxx" == new String("xxx").intern()
-
-but none of the other three are equivalent to "xxx" or each other:
-
- "xxx" != new String("xxx")
- "xxx" != "xx" + a.toString()
- "xxx" != "xx" + a
- new String("xxx") != new String("xxx")
- "xx" + a != new String("xxx")
-
-etc.
-
-As in Java, in SwingJS, all of the following Java assertions pass as true:
-
- assert("xxx" == "xx" + "x");
- assert("xxx" == ("xx" + a).intern());
- assert("xxx" === new String("xxx").intern());
-
-and both of these do as well:
-
- assert(new String("xxx") != "xxx");
- assert(new String("xxx") != new String("xxx"));
-
-But the following two fail to assert true:
-
- assert("xxx" != "xx" + a);
- assert("xxx" != "xx" + a.toString());
-
-because in JavaScript, both of these right-side expressions evaluate to a simple "interned" string.
-
-In Java, however, these assertions are true because Java implicitly "boxes" String
-concatentaion as a String object, not a literal.
-
-Most of us know not to generally use == with Strings unless they are explicitly interned.
-Where this problem may arise, though, is in IdentityHashMap, which compares objects using
-System.identityHashCode(), which is not the same for different objects or their string literal equivalents.
-
-My recommendation, if you need to use IdentityHashMap with strings is to always use an explicit String.intern()
-for any keys -- unless you really want to keep every string as separate keys even if they are the same sequence,
-in which case, use new String(). This will work in Java and in JavaScript.
-
-Be aware when working with strings that come from SwingJS and are being used by other JavaScript modules
-that those that are String objects will return "object" for the JavaScript typeof operator, not "string".
-
-The easy way to ensure this is no problem is to concatenate strings with "" to force immediate interning:
-
- var x = aJavaObject.getString() + "";
-
-unless you are certain that the string is being returned is a raw JavaScript string.
-
-Names with "$" and "_"
-----------------------
-
-For the most part, this should be no problem.
-
-Note that the use of $ and _ in Java field names has always been discouraged:
-[https://docs.oracle.com/javase/tutorial/java/nutsandbolts/variables.html]
-
- You may find some situations where auto-generated names will contain the dollar sign,
- but your variable names should always avoid using it. A similar convention
- exists for the underscore character; while it's technically legal to begin your
- variable's name with "_", this practice is discouraged.
-
-Some impacts of transpiling method names with full qualification:
-
-1) SwingJS will introduce fields that start with $ or _. These will not conflict
- if the above convention is followed.
-
-2) Fields that have the same Java name as a method are not an issue.
-
-3) Fields that have a Java name with $ that matches a transpiled method name,
- such as toString$, will need to be refactored in Java to not have that name collision.
-
-4) Fields in a subclass that have the same name as private fields in a superclass
- represent a name collision, because the superclass method needs to call its private
- field even if invoked from a subclass. The solution was to modify the subclass field
- name using one or more prepended $.
-
-5) Use of Class.getDeclaredMethods() reflection will return Method objects having the transpiled
- name, not the Java name. This could require some j2sNative adjustment
- to strip the $... parameters from the name if that is needed.
-
-6) Use of Method.getParameterTypes() should work fine, provided class names
- do not contain "_". This is because the transpiler converts "." to "_" when
- creating the fully qualified JavaScript name.
-
-
-positive integers do not add to give negative numbers
------------------------------------------------------
-
-In Java, the following is true:
-
- 2000000000 + 2000000000 == -294967296
-
-But in SwingJS, that will be 4000000000. So, for example, the following
-strategy will fail in SwingJS:
-
- int newLength = lineBuf.length * 2;
- if (newLength < 0) {
- newLength = Integer.MAX_VALUE;
- }
-
-"-1" in JavaScript is not 0xFFFFFFFF.
-
-And one must take care to not compare a negative number with a 32-bit mask. So
-
-(b & 0xFF000000) == 0xFF000000
-
-is true in Java for (int) b = -1, but is false in JavaScript, because 0xFF000000 is 4278190080,
-while (-1 & 0xFF000000) is, strangely enough, -16777216, and, in fact,
-
-(0xFF000000 & 0xFF000000) != 0xFF000000
-
-because -16777216 is not 4278190080.
-
-The fix is that one must compare similar operations:
-
-if ((b & 0xFF000000) == (0xFF000000 & 0xFF000000)) .....
-
-Importantly, the JavaScript Int32Array does behave properly. From
-the Firefox developer console:
-
->> x = new Int32Array(1)
-<- Int32Array(1) [ 0 ]
->> x[0] = 4000000000
-<- 4000000000
->> x[0]
-<- -294967296
-
-Notice that, perhaps unexpectedly, the following two constructs produce
-different results in JavaScript:
-
-x = new Int32Array(1);
-b = x[0] = 4000000000;
-
-(b will be 4000000000)
-
-and
-
-x = new Int32Array(1);
-x[0] = 4000000000;
-b = x[0];
-
-(b will be -294967296)
-
-
-SwingJS leverages array typing to handle all byte and short arithmetic so as
-to ensure that any byte or short operation in JavaScript does give the same
-result in Java. The design decision to not also do this with integer math was
-a trade-off between performance and handling edge cases.
-
-
-ArrayIndexOutOfBounds
----------------------
-
-You cannot implicitly throw an ArrayIndexOutOfBoundsException in JavaScript.
-JavaScript will simply return "undefined", not throw an Exception. So:
-
-boolean notAGoodIdeaIsOutOfBounds(String[] sa, int i) {
- try {
- return (sa[i] == sa[i]);
- } catch (ArrayIndexOutOfBoundsException e) {
- return false;
- }
-}
-
-will work in Java but not in JavaScript. Code should not depend upon this sort
-of trap anyway, if you ask me.
-
-Throwable vs Error vs Exception
--------------------------------
-
-True JavaScript errors are trapped as Throwable, whereas you can still trap
-Error and Exception as well. So if you want to be sure to catch any JavaScript
-error, use try{}catch (Throwable t){}, not try{}catch (Exception e){}.
-
-j
-ava.awt.Color
---------------
-
-ColorSpace: only "support" CS_sRGB.
-
- TODO -- any volunteers??
-
-
-javax.swing.JFileDialog
------------------------
-
-HTML5 cannot expose a file reading directory structure. But you certainly
-can still do file reading and writing. It just works a little differently.
-It's a simple modification:
-
- b = new JButton("FileOpenDialog");
- b.addActionListener(new ActionListener() {
-
- @Override
- public void actionPerformed(ActionEvent e) {
- JFileChooser fc = new JFileChooser();
- Test_Dialog.this.onDialogReturn(fc.showOpenDialog(Test_Dialog.this));
- // Java will wait until the dialog is closed, then enter the onDialogReturn method.
- // JavaScript will exit with NaN immediately, and then call back with its actual value
- // asynchronously.
- }
-
- });
-
- public void onDialogReturn(int value) {
- if (value != Math.floor(value))
- return; // in JavaScript, this will be NaN, indicating the dialog has been opened
- // If we are here, the dialog has closed, in both Java and JavaScript.
- System.out.println("int value is " + value);
- }
-
-
- @Override
- public void propertyChange(PropertyChangeEvent event) {
- Object val = event.getNewValue();
- String name = event.getPropertyName();
- System.out.println(name);
- switch (event.getSource().getClass().getName()) {
- case "javax.swing.JOptionPane":
- switch (name) {
- case "inputValue":
- onDialogReturn(val);
- return;
- case "value":
- if (val instanceof Integer)
- onDialogReturn(((Integer) val).intValue());
- else
- onDialogReturn(val);
- return;
- }
- break;
- case "javax.swing.ColorChooserDialog":
- switch (name) {
- case "SelectedColor":
- onDialogReturn(val);
- return;
- }
- break;
- case "javax.swing.JFileChooser":
- switch (name) {
- case "SelectedFile":
- File file = (File) val;
- byte[] array = (val == null ? null : /** @j2sNative file.秘bytes || */
- null);
- onDialogReturn("fileName is '" + file.getName() + "'\n\n" + new String(array));
- return;
- }
- break;
- }
- System.out.println(
- event.getSource().getClass().getName() + " " + event.getPropertyName() + ": " + event.getNewValue());
- }
-
-
-Developers are encouraged to create a separate class that handles general calls to JFileDialog.
-An example class can be found in the SwingJS distribution as
-
-/sources/net.sf.j2s.java.core/src/javajs/async/AsyncFileChooser.java.
-
-
-javax.swing.JOptionPane dialogs
--------------------------------
-
-For this action to work, the parentComponent must implement
-propertyChangeListener, and any call to JOptionPanel should allow for
-an asynchronous response, meaning that there is no actionable code following the
-call to the dialog opening.
-
-In addition, for compatibility with the Java version, implementation should
-wrap the call to getConfirmDialog or getOptionDialog in a method call to
-handle the Java:
-
-onDialogReturn(JOptionPane.showConfirmDialog(parentFrame,
-messageOrMessagePanel, "title", JOptionPane.OK_CANCEL_OPTION));
-
-Then parentFrame.propertyChange(event) should also call onDialogReturn.
-
-This will then work in both Java and JavaScript.
-
-Note that there is an int and an Object version of onDialogReturn().
-
-
-In JavaScript:
-
-The initial return from JOptionPane.showConfirmDialog and showMessageDialog
-will be (SwingJS) JDialog.ASYNCHRONOUS_INTEGER (NaN), testable as an impossible
-Java int value using ret != -(-ret) if the parent implements PropertyChangeListener, or -1
-(CLOSE_OPTION) if not.
-
-For showOptionDialog (which returns Object) or showInputDialog (which returns
-String), the initial return will be (SwingJS) JDialog.ASYNCHRONOUS_OBJECT, testable as
-((Object) ret) instanceof javax.swing.plaf.UIResource if the parent implements
-PropertyChangeListeneer, or null if not.
-
-The second return will be the desired return.
-
-In Java:
-
-The initial return will be the one and only modal final return.
-
-
-
-For full compatibility, The calling method must not continue beyond this
-call.
-
-All of the standard Java events associated with Components are also
-available.
-
-Certain fall back mechanisms are possible, where onReturn does not exist, but
-only for the following cases:
-
-
-For showMessageDialog, for WARNING_MESSAGE and ERROR_MESSAGE, a simple
-JavaScript alert() is used, returning 0 (OK_OPTION) or -1 (CLOSED_OPTION).
-
-For showInputDialog, if the message is a string, a simple JavaScript prompt()
-with input box is used, returning the entered string or null.
-
-For showConfirmDialog, a simple JavaScript confirm() is used, in which case:
-
-for YES_NO_OPTION: YES_OPTION or NO_OPTION
-
-for YES_NO_CANCEL_OPTION: YES_OPTION or CANCEL_OPTION
-
-for OK_CANCEL_OPTION or any other: OK_OPTION or CANCEL_OPTION
-
-Note that you should implement a response for CLOSED_OPTION for
-showConfirmDialog. For other dialogs, a null return indicates the dialog was
-closed, just as for Java.
-
-Developers are encouraged to create a separate class that handles general calls.
-An example class can be found in the SwingJS distribution as src/javajs/async/AsyncDialog.java.
-Very simple modifications to the Java allows asynchronous operation using AsyncDialog. Here
-is a simple "do you want to close this frame" example, where you can see that what we have
-done is to set the reply into an ActionListener that is defined in the constructor of
-the AsyncDisplay object:
-
-// Original:
-//
-// private void promptQuit() {
-// int sel = JOptionPane.showConfirmDialog(null, PROMPT_EXIT, NAME, JOptionPane.YES_NO_OPTION);
-// switch (sel) {
-// case JOptionPane.YES_OPTION:
-// resultsTab.clean();
-// seqs.dispose();
-// if (fromMain) {
-// System.exit(0);
-// }
-// break;
-// }
-// }
-
- private void promptQuitAsync() {
- new AsyncDialog(new ActionListener() {
-
- @Override
- public void actionPerformed(ActionEvent e) {
- int sel = ((AsyncDialog)e.getSource()).getOption();
- switch (sel) {
- case JOptionPane.YES_OPTION:
- resultsTab.clean();
- seqs.dispose();
- if (fromMain) {
- System.exit(0);
- }
- break;
- }
- }}).showConfirmDialog(null, PROMPT_EXIT, NAME, JOptionPane.YES_NO_OPTION);
- }
-
-Very simple!
-
-
-native methods
---------------
-
-The J2S compiler ignores all static native method declarations.
-Anything of this nature needs to be implemented in JavaScript if it is needed,
-using j2sNative blocks:
-
-/**
- * @j2sNative
- *
- * var putYourJavaScriptCodeHere
- *
- */
-
- Note that if you follow that directly with a {...} block, then
- the javadoc code will run in JavaScript, and the {...} code will run in Java.
-
-
-key Focus
----------
-
-As of June, 2019, the keyboard focus manager is fully implemented.
-The one catch is that JTextPane and JTextArea, which already consume
-VK_TAB in Java, cannot use CTRL-TAB to continue a tabbing cycle around
-the components in a window. Instead, CTRL-TAB is absorbed by the browser.
-
-
-LookAndFeel and UI Classes
---------------------------
-
-SwingJS implements the native browser look and feel as swingjs.plaf.HTML5LookAndFeel.
-There are small differences between all look and feels -- MacOS, Windows, SwingJS.
-
-Expert developers know how to coerce changes in the UI by subclassing the UI for a
-component. This probably will not work in SwingJS.
-
-Note that LookAndFeel in Java usually determines canvas size in a Frame because
-different operating systems (Mac OS vs Windows vs HTML5) will have
-different edge sizes on their frames. If you want to ensure a component size,
-use getContentPane().setPreferredSize().
-
-
-System.exit(0) does not stop all processes
-------------------------------------------
-
-Although System.ext(int) has been implemented in JavaScript, it just closes the
-frames, stops all pending javax.swing.Timer objects in the queue, and runs any
-threads added using Runtime.getRuntime().addShutdownHook(Thread).
-It may not stop all "threads." So don't rely on that.
-Applications are responsible for shutting down prior to executing System.exit(0).
-
-
-myClass.getField not implemented
---------------------------------
-
-java.lang.reflect.Field is implemented minimally. It is not
-certain that Field.getDeclaringClass() will work. If you just want a
-value of a field, you can do this:
-
-/**
- *@j2sNative
- *
- * return myClass[name]
- */
-
-But that is not a java.lang.reflection.Field object.
-
-
-"window" and other reserved JavaScript names
---------------------------------------------
-
-No reserved top-level JavaScript name is allowed for a package name. So, for example,
-one must rename packages such as "window" or "document" to names such as "win" or "doc".
-
-reserved field and method names
--------------------------------
-
-In order to minimize the chance of added SwingJS field and method names colliding with ones
-developers might use in subclassing Java classes, we have added U+79D8 (first character of Mandarin
-"secret") to the characters already disrecommended by Java documentation ("$" and "_"). The only problem
-would be if you use that character followed by certain English words in certain classes. For example
-\u79D8canvas for JComponents (in java.awt.JSComponent) and \u79D8byte (in java.io.File).
-
-qualified field and method names
---------------------------------
-
-Method names in SwingJS are fully qualified, meaning two methods with the same Java name but different
-parameters, such as write(int) and write(double), must not have the same name in JavaScript. (In this
-case, we will have write$I and write$D.) However, in certain cases it may be desirable to leave the
-method names unqualified. In particular, when an interface actually represents a JavaScript object,
-the transpiler can leave a method name unqualified. The default situation for this is a class name
-includes ".api.js" (case-sensitive). This means that any method in any class in a package js within
-a package api, or any private interface js that has an outer interface api, will have all-unqualified
-methods. An example of this is swingjs.plaf.JSComboPopupList, which needs to communicate with a jQuery
-object directly using the following interface:
-
- private interface api {
-
- interface js extends JQueryObject {
-
- abstract js j2sCB(Object options);
-
- abstract Object[] j2sCB(String method);
-
- abstract Object[] j2sCB(String method, Object o);
-
- abstract Object[] j2sCB(String method, int i);
-
- abstract int j2sCB(String OPTION, String name);
-
- }
- }
-
-Notice that all these variants of j2sCB() will call the same method in JavaScript by design.
-
-
-missing Math methods
---------------------
-
-java.lang.Math is worked out, but some methods are missing, either because they
-involve long integer value that are inaccessible in JavaScript, or because I just
-didn't implement them. This is a result of continued Java development.
-It is easy enough to add these methods if you have the source. They go into j2sClazz.js,
-which is combined with other initial libraries into swingjs2.js by build_site.xml
-
-
-Component.getGraphics(), Graphics.dispose()
--------------------------------------------
-
-Use of component.getGraphics() is discouraged in Java and in SwingJS.
-Specifically in SwingJS, any call to component.getGraphics() or
-BufferedImage.createGraphics() or Graphics.create(...) should be matched with graphics.dispose(),
-particularly when it is called outside the context of a paint(Graphics)
-call from the system.
-
-If you see your graphics scrolling down the page with each repaint,
-look for where you have used Component.getGraphics() and not Graphics.dispose().
-For example, this will definitely NOT work in SwingJS:
-
- this.paint(getGraphics())
-
-and really should not work in Java, either, as it is technically a resource memory leak.
-
-Instead, if you really do not want to use repaint(), use this:
-
- Graphics g = getGraphics();
- paint(g);
- g.dispose();
-
-
-
-Graphics.setClip()
-------------------
-
-The HTML5 canvas.clip() method is permanent. You can only reset the clip using
-save/restore. This is different from Java, where you can temporarily change it using
-
- Shape oldClip = Graphics.getClip();
- Graphics.setClip(newClip);
- ...
- Graphics.setClip(oldClip);
-
-If you need to do something like this, you must schedule the paints
-to not have overlapping clip needs.
-
-
-MAJOR ISSUES--for Bob and Udo within SwingJS
-============================================
-
-fonts
------
-
-Fonts and FontMetrics will all be handled in JavaScript. Font matching will
-not be exact, and composite (drawn) fonts will not be supported.
-
-SwingJS handles calls such as font.getFontMetrics(g).stringWidth("xxx") by
-creating a <div> containing that text, placing it in an obscure location on
-the page, and reading div.getBoundingClientRect(). This is a VERY precise
-value, but can be a pixel or two off from what Java reports for the same font.
-
-
-OS-dependent classes
---------------------
-
-Static classes such as:
-
- java.awt.Toolkit
- java.awt.GraphicsEnvironment
-
-
-which are created using Class.forName are implemented using classes in the swingjs package.
-
-AWTAccessor is not implemented.
-
-
-AWT component peers and component "ui" user interfaces
-------------------------------------------------------
-
-ComponentPeer is a class that represents a native AWT component.
-Components with such peers are called "heavy-weight" components.
-They are expected to do the dirty work of graphics drawing.
-
-Java Swing implements peers only for JApplet, JDialog, JFrame, and JWindow.
-References to such objects have been removed, but clearly there must be
-some connection to similar DOM objects, even for "light-weight" components.
-
-
-
-MAJOR ISSUES--to be resolved by implementers
-============================================
-
-fonts
------
-
-Glyph/composite/outline fonts are not supported.
-
-
-
-threads
--------
-
-Thread locking and synchronization are not relevant to JavaScript.
-Thus, anything requiring "notify.." or "waitFor.." could be a serious issue.
-
-All threading must be "faked" in JavaScript. Specifically not available is:
-
- Thread.sleep()
-
-javax.swing.AbstractButton#doClick(pressTime) will not work, as it requires Thread.sleep();
-
-However, java.lang.Thread itself is implemented and used extensively.
-
-Methods thread.start() and thread.run() both work fine.
-
-For simple applications that use Thread.sleep() just to have a delay, as in a frame rate, for
-example, one can use javax.swing.Timer instead. That is fully implemented.
-
-Likewise, java.util.Timer can be replaced with no loss of performance with javax.Swing.Timer.
-Note that java.util.TimerTask is implemented, but it can also be replaced by an implementation of Runnable.
-
-task = new TimerTask(){....};
-t = new java.util.Timer();
-t.schedule(task, 0, 1);
-
-becomes
-
-task = new TimerTask(){....}; // or task = new Runnable() {...}
-t = new javax.swing.Timer(1, new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- task.run();
- }
-};
-t.setInitialDelay(0); // not particularly necessary
-t.start();
-
-In addition, SwingJS provides swingjs.JSThread, which can be subclassed
-if desired. This class allows simple
-
- while(!interrupted()){
- wait()
- ...
- }
-
-action through an asynchronous function run1(mode). For example:
-
- protected void run1(int mode) {
- try {
- while (true)
- switch (mode) {
- case INIT:
- // once-through stuff here
- mode = LOOP;
- break;
- case LOOP:
- if (!doDispatch || isInterrupted()) {
- mode = DONE;
- } else {
- Runnable r = new Runnable() {
- public void run() {
- // put the loop code here
- }
- };
- dispatchAndReturn(r);
- if (isJS)
- return;
- }
- break;
- // add more cases as needed
- case DONE:
- // finish up here
- if (isInterrupted())
- return;
- // or here
- break;
- }
- } finally {
- // stuff here to be executed after each loop in JS or at the end in Java
- }
- }
-
-image loading
--------------
-- All image loading in SwingJS is synchronous. A MediaTracker call will immediately return "complete".
- However, it still may take one system clock tick to fully load images. Thus, it is recommended that
- images be preloaded in the static block of the applet if it is necessary that they be available in init().
- This is only an issue if you are trying to access the pixel buffer of the image in JavaScript.
-
-- Applet.getImage(path, name) will return null if the image does not exist.
-
-- BufferedImage: only "support" imageType RGB and ARGB
-
- -BH: This is a temporary edit, just to get us started. Certainly GRAY will be needed
-
-
-BigInteger and BigDecimal
--------------------------
-
-java.math.BigInteger is fully supported; java.math.BigDecimal is roughed
-in and not fully tested (07/2019).
-
-Both classes present significant issues for JavaScript, as they are based in
-Java's 64-bit long for all their operations. Here is the JavaDoc note I added
-to BigInteger:
-
- * SwingJS note: Because of the limitations of JavaScript with regard
- * to long-integer bit storage as a double, this implementation drops
- * the integer storage bit length to 24, giving 48 for long and leaving
- * the last 16 bits clear for the exponent of the double number. This should
- * not affect performance significantly. It does increase the storage
- * size by about 33%. By bringing an "int" to 3 bytes, we can easily construct
- * and use byte[] data intended for the original BitSet.
-
-"Easily" may be a bit strong there. This was a serious challenge.
-
-BigDecimal seems to run normally, but in order to do that, my hack involves
-reducing the size of an integer that is allowed to be stored as such and not
-in byte[] as a BigInteger. I'm sure there is a performance hit, but it does work.
-
-no format internationalization
-------------------------------
-
-For now, just en for number and date formatters
-
-no winding rules
-----------------
-
- When filling a graphic, only nonzero winding rule is implemented in HTML5 Canvas2D.
-
-
-
-text-related field implementation
----------------------------------
-
-Text fields are:
-
-JTextField (JavaScript <input type="text">)
-JTextArea (JavaScript <textarea>)
-JTextPane (JavaScript <div>)
-JEditorPane (JavaScript <div>)
-
-For the initial implementation, we don't implement infinite undo/redo, and the abstract
-document model is much less elaborate. Only PlainDocument (in the form of JSPlainDocument)
-is implemented. The Document returned by JTextField.getDocument() is a javax.swing.text.Document.
-
-All scrolling is handled by HTML5. javax.swing.AutoScroller is not implemented.
-public static methods .stop, .isRunning, .processMouseDragged require true Java threading
-and so are not implmented. javax.swing.text.View and its subclasses are not implemented.
-
-The JS document model does not allow two text fields to address the same underlying document.
-
-JavaScript is slightly different from Java in that the field value is changed asynchronously after
-the keypressed event, so Java actions that are keyed to KEY_PRESSED may not pick up the new
-key value even after SwingUtilities.invokeLater() is called. Thus, key pressed actions may need
-to be recorded after a key released event instead.
-
-Formatter/Regex limitations
----------------------------
-
-Some browsers cannot process Regex "look-behind" process such as (?<=\W)
-java.util.regex.Matcher and Pattern use JavaScript's RegExp object rather than
-the native Java object. These are not identical. Only flags /igm are supported.
-Matcher.start(groupID) is not supported.
-
-java.util.Formatter will function correctly for all standard %... patterns.
-
-integer 1/0 == Infinity
------------------------
-
-1/0 in Java throws "java.lang.ArithmeticException: / by zero", but in JavaScript is just Infinity.
-
-
-
-Summary
--------
-
-These are all the known limitations of SwingJS. We have not found any of these limitations
-to be show-stoppers. The primary issue for newcomers to SwingJS is having the source code.
-You must check that source code for all your library jar files is available or, if you
-choose, you will need to decompile those classes. We have used decompilation on some projects,
-and it works just fine. So, technically, all we really need are JAR/class files. But the
-source is by far superior. It's generally prettier, and it has the license information that
-may or may not be present with the JAR or class files. Use class files at your own risk.
-
-Bob Hanson
-2019.08.16
-
-
-Additional Issues
------------------
-
-Annotation is working for classes, methods, and fields (12/22/19). Method reflection, however,
-is limited. Interfaces do not expose their methods, as the transpiler does not actually transpile
-the interfaces themselves. And method reflection only includes annotated methods.
-
-java.util.concurrent is not fully elaborated. This package is rewritten to not actually use the
-memory handling capabilities of concurrency, which JavaScript does not have access to.
-
-System.getProperties() just returns a minimal set of properties.
-
-
+++ /dev/null
-20201231144345
+++ /dev/null
-20180923174836
+++ /dev/null
-20180927214151
+++ /dev/null
-This is sources/net.sf.j2s.java.core/dist/DEV_NOTES.txt
-
-_j2sclasslist.txt
-
-the list of .js files concatenated into coreswingjs.js and minified to coreswingjs.z.js
-
-
-SwingJS-site.zip
-
-the full site directory for SwingJS including all files not in the test/ directory.
+++ /dev/null
-java/applet/Applet.js
-java/applet/AppletContext.js
-java/applet/AppletStub.js
-java/applet/JSApplet.js
-java/awt/ActiveEvent.js
-java/awt/Adjustable.js
-java/awt/AWTEvent.js
-java/awt/AWTEventMulticaster.js
-java/awt/AWTKeyStroke.js
-java/awt/BasicStroke.js
-java/awt/BorderLayout.js
-java/awt/Button.js
-java/awt/Color.js
-java/awt/color/ColorSpace.js
-java/awt/Component.js
-java/awt/ComponentOrientation.js
-java/awt/ContainerOrderFocusTraversalPolicy.js
-java/awt/Container.js
-java/awt/Cursor.js
-java/awt/DefaultFocusTraversalPolicy.js
-java/awt/DefaultKeyboardFocusManager.js
-java/awt/Dialog.js
-java/awt/Dimension.js
-java/awt/dnd/peer/DropTargetPeer.js
-java/awt/event/ActionListener.js
-java/awt/event/AdjustmentEvent.js
-java/awt/event/AdjustmentListener.js
-java/awt/event/AWTEventListener.js
-java/awt/event/ComponentAdapter.js
-java/awt/event/ComponentEvent.js
-java/awt/event/ComponentListener.js
-java/awt/event/ContainerListener.js
-java/awt/event/FocusEvent.js
-java/awt/event/FocusListener.js
-java/awt/event/HierarchyBoundsListener.js
-java/awt/event/HierarchyListener.js
-java/awt/event/InputEvent.js
-java/awt/event/InputMethodListener.js
-java/awt/event/InvocationEvent.js
-java/awt/event/ItemEvent.js
-java/awt/event/ItemListener.js
-java/awt/event/KeyListener.js
-java/awt/event/MouseEvent.js
-java/awt/event/MouseListener.js
-java/awt/event/MouseMotionListener.js
-java/awt/event/MouseWheelListener.js
-java/awt/event/TextListener.js
-java/awt/event/WindowAdapter.js
-java/awt/event/WindowEvent.js
-java/awt/event/WindowFocusListener.js
-java/awt/event/WindowListener.js
-java/awt/event/WindowStateListener.js
-java/awt/EventDispatchThread.js
-java/awt/EventFilter.js
-java/awt/EventQueue.js
-java/awt/EventQueueItem.js
-java/awt/FlowLayout.js
-java/awt/FocusTraversalPolicy.js
-java/awt/Font.js
-java/awt/font/FontRenderContext.js
-java/awt/FontMetrics.js
-java/awt/Frame.js
-java/awt/geom/AffineTransform.js
-java/awt/geom/Dimension2D.js
-java/awt/geom/Path2D.js
-java/awt/geom/PathIterator.js
-java/awt/geom/Point2D.js
-java/awt/geom/Rectangle2D.js
-java/awt/geom/RectangularShape.js
-java/awt/geom/RectIterator.js
-java/awt/GraphicsCallback.js
-java/awt/GraphicsConfiguration.js
-java/awt/GraphicsDevice.js
-java/awt/GraphicsEnvironment.js
-java/awt/image/ImageObserver.js
-java/awt/Insets.js
-java/awt/ItemSelectable.js
-java/awt/JSComponent.js
-java/awt/JSDialog.js
-java/awt/JSFrame.js
-java/awt/JSPanel.js
-java/awt/KeyboardFocusManager.js
-java/awt/KeyEventDispatcher.js
-java/awt/KeyEventPostProcessor.js
-java/awt/Label.js
-java/awt/LayoutManager.js
-java/awt/LayoutManager2.js
-java/awt/LightweightDispatcher.js
-java/awt/Paint.js
-java/awt/Panel.js
-java/awt/peer/ComponentPeer.js
-java/awt/peer/ContainerPeer.js
-java/awt/peer/FramePeer.js
-java/awt/peer/KeyboardFocusManagerPeer.js
-java/awt/peer/LightweightPeer.js
-java/awt/peer/WindowPeer.js
-java/awt/Point.js
-java/awt/Queue.js
-java/awt/Rectangle.js
-java/awt/RenderingHints.js
-java/awt/Scrollbar.js
-java/awt/ScrollPane.js
-java/awt/Shape.js
-java/awt/Stroke.js
-java/awt/TextArea.js
-java/awt/TextComponent.js
-java/awt/TextField.js
-java/awt/Toolkit.js
-java/awt/Transparency.js
-java/awt/Window.js
-java/beans/ChangeListenerMap.js
-java/beans/PropertyChangeEvent.js
-java/beans/PropertyChangeListener.js
-java/beans/PropertyChangeSupport.js
-java/lang/AbstractStringBuilder.js
-java/lang/Class.js
-java/lang/Enum.js
-java/lang/Iterable.js
-java/lang/reflect/Constructor.js
-java/lang/reflect/Method.js
-java/lang/StringBuffer.js
-java/lang/StringBuilder.js
-java/lang/Thread.js
-java/lang/ThreadGroup.js
-java/math/RoundingMode.js
-java/net/URL.js
-java/net/URLStreamHandlerFactory.js
-java/text/CharacterIterator.js
-java/text/DecimalFormat.js
-java/text/DecimalFormatSymbols.js
-java/text/DigitList.js
-java/text/FieldPosition.js
-java/text/Format.js
-java/text/NumberFormat.js
-java/util/AbstractCollection.js
-java/util/AbstractList.js
-java/util/AbstractMap.js
-java/util/AbstractSequentialList.js
-java/util/AbstractSet.js
-java/util/ArrayList.js
-java/util/Arrays.js
-java/util/Collection.js
-java/util/Collections.js
-java/util/Comparator.js
-java/util/Deque.js
-java/util/Dictionary.js
-java/util/Enumeration.js
-java/util/EventListener.js
-java/util/EventObject.js
-java/util/HashMap.js
-java/util/HashSet.js
-java/util/Hashtable.js
-java/util/IdentityHashMap.js
-java/util/Iterator.js
-java/util/LinkedHashMap.js
-java/util/LinkedList.js
-java/util/List.js
-java/util/ListResourceBundle.js
-java/util/Locale.js
-java/util/Map.js
-java/util/Objects.js
-java/util/Queue.js
-java/util/Random.js
-java/util/RandomAccess.js
-java/util/ResourceBundle.js
-java/util/Set.js
-java/util/TimSort.js
-java/util/Vector.js
-javajs/api/JSFunction.js
-javajs/util/AjaxURLConnection.js
-javajs/util/AjaxURLStreamHandlerFactory.js
-javajs/util/AU.js
-javajs/util/JSThread.js
-javajs/util/Lst.js
-javajs/util/PT.js
-javajs/util/SB.js
-javax/net/ssl/HttpsUrlConnection.js
-javax/swing/AbstractAction.js
-javax/swing/AbstractButton.js
-javax/swing/AbstractListModel.js
-javax/swing/Action.js
-javax/swing/ActionMap.js
-javax/swing/AncestorNotifier.js
-javax/swing/ArrayTable.js
-javax/swing/border/AbstractBorder.js
-javax/swing/border/BevelBorder.js
-javax/swing/border/Border.js
-javax/swing/border/CompoundBorder.js
-javax/swing/border/EmptyBorder.js
-javax/swing/border/EtchedBorder.js
-javax/swing/border/LineBorder.js
-javax/swing/BorderFactory.js
-javax/swing/BoundedRangeModel.js
-javax/swing/BoxLayout.js
-javax/swing/ButtonGroup.js
-javax/swing/ButtonModel.js
-javax/swing/ClientPropertyKey.js
-javax/swing/ComboBoxModel.js
-javax/swing/DefaultBoundedRangeModel.js
-javax/swing/DefaultButtonModel.js
-javax/swing/DefaultComboBoxModel.js
-javax/swing/DefaultSingleSelectionModel.js
-javax/swing/DropMode.js
-javax/swing/event/AncestorEvent.js
-javax/swing/event/AncestorListener.js
-javax/swing/event/CaretEvent.js
-javax/swing/event/CaretListener.js
-javax/swing/event/ChangeEvent.js
-javax/swing/event/ChangeListener.js
-javax/swing/event/DocumentEvent.js
-javax/swing/event/DocumentListener.js
-javax/swing/event/EventListenerList.js
-javax/swing/event/ListDataEvent.js
-javax/swing/event/ListDataListener.js
-javax/swing/event/UndoableEditEvent.js
-javax/swing/event/UndoableEditListener.js
-javax/swing/FocusManager.js
-javax/swing/InternalFrameFocusTraversalPolicy.js
-javax/swing/LayoutComparator.js
-javax/swing/LayoutFocusTraversalPolicy.js
-javax/swing/SortingFocusTraversalPolicy.js
-javax/swing/SwingContainerOrderFocusTraversalPolicy.js
-javax/swing/SwingDefaultFocusTraversalPolicy.js
-javax/swing/InputMap.js
-javax/swing/JApplet.js
-javax/swing/JButton.js
-javax/swing/JCheckBox.js
-javax/swing/JCheckBoxMenuItem.js
-javax/swing/JComboBox.js
-javax/swing/JComponent.js
-javax/swing/JFrame.js
-javax/swing/JLabel.js
-javax/swing/JLayeredPane.js
-javax/swing/JMenu.js
-javax/swing/JMenuBar.js
-javax/swing/JMenuItem.js
-javax/swing/JPanel.js
-javax/swing/JPopupMenu.js
-javax/swing/JRadioButtonMenuItem.js
-javax/swing/JRootPane.js
-javax/swing/JScrollBar.js
-javax/swing/JScrollPane.js
-javax/swing/JSeparator.js
-javax/swing/JTextArea.js
-javax/swing/JTextField.js
-javax/swing/JToggleButton.js
-javax/swing/JViewport.js
-javax/swing/KeyboardManager.js
-javax/swing/KeyStroke.js
-javax/swing/ListModel.js
-javax/swing/LookAndFeel.js
-javax/swing/MenuElement.js
-javax/swing/MutableComboBoxModel.js
-javax/swing/plaf/ActionMapUIResource.js
-javax/swing/plaf/basic/BasicBorders.js
-javax/swing/plaf/BorderUIResource.js
-javax/swing/plaf/ColorUIResource.js
-javax/swing/plaf/ComponentUI.js
-javax/swing/plaf/DimensionUIResource.js
-javax/swing/plaf/FontUIResource.js
-javax/swing/plaf/InputMapUIResource.js
-javax/swing/plaf/InsetsUIResource.js
-javax/swing/plaf/UIResource.js
-javax/swing/RepaintManager.js
-javax/swing/RootPaneContainer.js
-javax/swing/Scrollable.js
-javax/swing/ScrollPaneConstants.js
-javax/swing/ScrollPaneLayout.js
-javax/swing/SingleSelectionModel.js
-javax/swing/SizeRequirements.js
-javax/swing/SwingConstants.js
-javax/swing/SwingPaintEventDispatcher.js
-javax/swing/SwingUtilities.js
-javax/swing/text/AbstractDocument.js
-javax/swing/text/AttributeSet.js
-javax/swing/text/Caret.js
-javax/swing/text/DefaultCaret.js
-javax/swing/text/DefaultEditorKit.js
-javax/swing/text/Document.js
-javax/swing/text/EditorKit.js
-javax/swing/text/Element.js
-javax/swing/text/GapContent.js
-javax/swing/text/GapVector.js
-javax/swing/text/JTextComponent.js
-javax/swing/text/MutableAttributeSet.js
-javax/swing/text/PlainDocument.js
-javax/swing/text/PlainView.js
-javax/swing/text/Position.js
-javax/swing/text/Segment.js
-javax/swing/text/SegmentCache.js
-javax/swing/text/SimpleAttributeSet.js
-javax/swing/text/Style.js
-javax/swing/text/StyleConstants.js
-javax/swing/text/StyleContext.js
-javax/swing/text/TabExpander.js
-javax/swing/text/TextAction.js
-javax/swing/text/Utilities.js
-javax/swing/text/View.js
-javax/swing/tree/TreeNode.js
-javax/swing/UIDefaults.js
-javax/swing/UIManager.js
-javax/swing/undo/AbstractUndoableEdit.js
-javax/swing/undo/CompoundEdit.js
-javax/swing/undo/UndoableEdit.js
-javax/swing/ViewportLayout.js
-javax/swing/WindowConstants.js
-sun/awt/AppContext.js
-sun/awt/AWTAutoShutdown.js
-sun/awt/CausedFocusEvent.js
-sun/awt/ComponentFactory.js
-sun/awt/KeyboardFocusManagerPeerProvider.js
-sun/awt/MostRecentKeyValue.js
-sun/awt/MostRecentThreadAppContext.js
-sun/awt/PaintEventDispatcher.js
-sun/awt/PostEventQueue.js
-sun/awt/RequestFocusController.js
-sun/awt/SunToolkit.js
-sun/awt/WindowClosingListener.js
-sun/awt/WindowClosingSupport.js
-sun/font/FontDesignMetrics.js
-sun/swing/DefaultLookup.js
-sun/swing/SwingLazyValue.js
-sun/text/resources/FormatData.js
-sun/text/resources/FormatData_en.js
-sun/util/resources/LocaleData.js
-swingjs/a2s/A2SContainer.js
-swingjs/a2s/A2SEvent.js
-swingjs/a2s/A2SListener.js
-swingjs/a2s/Applet.js
-swingjs/a2s/Button.js
-swingjs/a2s/Label.js
-swingjs/a2s/Panel.js
-swingjs/a2s/Scrollbar.js
-swingjs/a2s/ScrollPane.js
-swingjs/a2s/TextArea.js
-swingjs/a2s/TextField.js
-swingjs/api/Interface.js
-swingjs/api/js/DOMNode.js
-swingjs/api/js/HTML5CanvasContext2D.js
-swingjs/api/js/JSInterface.js
-swingjs/jquery/JQueryUI.js
-swingjs/JSApp.js
-swingjs/JSAppletThread.js
-swingjs/JSAppletViewer.js
-swingjs/JSFocusPeer.js
-swingjs/JSFontMetrics.js
-swingjs/JSFrameViewer.js
-swingjs/JSGraphics2D.js
-swingjs/JSGraphicsConfiguration.js
-swingjs/JSGraphicsEnvironment.js
-swingjs/JSMouse.js
-swingjs/JSNullComponentPeer.js
-swingjs/JSScreenDevice.js
-swingjs/JSThreadGroup.js
-swingjs/JSToolkit.js
-swingjs/JSUtil.js
-swingjs/plaf/ButtonListener.js
-swingjs/plaf/DefaultMenuLayout.js
-swingjs/plaf/HTML5LookAndFeel.js
-swingjs/plaf/JSAppletUI.js
-swingjs/plaf/JSButtonUI.js
-swingjs/plaf/JSCheckBoxMenuItemUI.js
-swingjs/plaf/JSCheckBoxUI.js
-swingjs/plaf/JSComboBoxUI.js
-swingjs/plaf/JSComponentUI.js
-swingjs/plaf/JSEventHandler.js
-swingjs/plaf/JSFrameUI.js
-swingjs/plaf/JSGraphicsUtils.js
-swingjs/plaf/JSLabelUI.js
-swingjs/plaf/JSLayeredPaneUI.js
-swingjs/plaf/JSLightweightUI.js
-swingjs/plaf/JSMenuBarUI.js
-swingjs/plaf/JSMenuItemUI.js
-swingjs/plaf/JSMenuUI.js
-swingjs/plaf/JSPanelUI.js
-swingjs/plaf/JSPopupMenuSeparatorUI.js
-swingjs/plaf/JSPopupMenuUI.js
-swingjs/plaf/JSRadioButtonMenuItemUI.js
-swingjs/plaf/JSRadioButtonUI.js
-swingjs/plaf/JSRootPaneUI.js
-swingjs/plaf/JSScrollBarUI.js
-swingjs/plaf/JSScrollPaneUI.js
-swingjs/plaf/JSSeparatorUI.js
-swingjs/plaf/JSSliderUI.js
-swingjs/plaf/JSTextAreaUI.js
-swingjs/plaf/JSTextFieldUI.js
-swingjs/plaf/JSTextUI.js
-swingjs/plaf/JSTextViewUI.js
-swingjs/plaf/JSViewportUI.js
-swingjs/plaf/JSWindowUI.js
-swingjs/plaf/LazyActionMap.js
-swingjs/plaf/Resizer.js
-swingjs/plaf/TextListener.js
-
-
+++ /dev/null
-20191108205610
+++ /dev/null
-This is sources/net.sf.j2s.java.core/dist/DEV_NOTES.txt
-
-_j2sclasslist.txt
-
-the list of .js files concatenated into coreswingjs.js and minified to coreswingjs.z.js
-
-
-SwingJS-site.zip
-
-the full site directory for SwingJS including all files not in the test/ directory.
+++ /dev/null
-java/applet/Applet.js
-java/applet/AppletContext.js
-java/applet/AppletStub.js
-java/applet/JSApplet.js
-java/awt/ActiveEvent.js
-java/awt/Adjustable.js
-java/awt/AWTEvent.js
-java/awt/AWTEventMulticaster.js
-java/awt/AWTKeyStroke.js
-java/awt/BasicStroke.js
-java/awt/BorderLayout.js
-java/awt/Button.js
-java/awt/Color.js
-java/awt/color/ColorSpace.js
-java/awt/Component.js
-java/awt/ComponentOrientation.js
-java/awt/ContainerOrderFocusTraversalPolicy.js
-java/awt/Container.js
-java/awt/Cursor.js
-java/awt/DefaultFocusTraversalPolicy.js
-java/awt/DefaultKeyboardFocusManager.js
-java/awt/Dialog.js
-java/awt/Dimension.js
-java/awt/dnd/peer/DropTargetPeer.js
-java/awt/event/ActionListener.js
-java/awt/event/AdjustmentEvent.js
-java/awt/event/AdjustmentListener.js
-java/awt/event/AWTEventListener.js
-java/awt/event/ComponentAdapter.js
-java/awt/event/ComponentEvent.js
-java/awt/event/ComponentListener.js
-java/awt/event/ContainerListener.js
-java/awt/event/FocusEvent.js
-java/awt/event/FocusListener.js
-java/awt/event/HierarchyBoundsListener.js
-java/awt/event/HierarchyListener.js
-java/awt/event/InputEvent.js
-java/awt/event/InputMethodListener.js
-java/awt/event/InvocationEvent.js
-java/awt/event/ItemEvent.js
-java/awt/event/ItemListener.js
-java/awt/event/KeyListener.js
-java/awt/event/MouseEvent.js
-java/awt/event/MouseListener.js
-java/awt/event/MouseMotionListener.js
-java/awt/event/MouseWheelListener.js
-java/awt/event/TextListener.js
-java/awt/event/WindowAdapter.js
-java/awt/event/WindowEvent.js
-java/awt/event/WindowFocusListener.js
-java/awt/event/WindowListener.js
-java/awt/event/WindowStateListener.js
-java/awt/EventDispatchThread.js
-java/awt/EventFilter.js
-java/awt/EventQueue.js
-java/awt/EventQueueItem.js
-java/awt/FlowLayout.js
-java/awt/FocusTraversalPolicy.js
-java/awt/Font.js
-java/awt/font/FontRenderContext.js
-java/awt/FontMetrics.js
-java/awt/Frame.js
-java/awt/geom/AffineTransform.js
-java/awt/geom/Dimension2D.js
-java/awt/geom/Path2D.js
-java/awt/geom/PathIterator.js
-java/awt/geom/Point2D.js
-java/awt/geom/Rectangle2D.js
-java/awt/geom/RectangularShape.js
-java/awt/geom/RectIterator.js
-java/awt/GraphicsCallback.js
-java/awt/GraphicsConfiguration.js
-java/awt/GraphicsDevice.js
-java/awt/GraphicsEnvironment.js
-java/awt/Image.js
-java/awt/image/ImageObserver.js
-java/awt/Insets.js
-java/awt/ItemSelectable.js
-java/awt/JSComponent.js
-java/awt/JSDialog.js
-java/awt/JSFrame.js
-java/awt/JSPanel.js
-java/awt/KeyboardFocusManager.js
-java/awt/KeyEventDispatcher.js
-java/awt/KeyEventPostProcessor.js
-java/awt/Label.js
-java/awt/LayoutManager.js
-java/awt/LayoutManager2.js
-java/awt/LightweightDispatcher.js
-java/awt/Paint.js
-java/awt/Panel.js
-java/awt/peer/ComponentPeer.js
-java/awt/peer/ContainerPeer.js
-java/awt/peer/FramePeer.js
-java/awt/peer/KeyboardFocusManagerPeer.js
-java/awt/peer/LightweightPeer.js
-java/awt/peer/WindowPeer.js
-java/awt/Point.js
-java/awt/Queue.js
-java/awt/Rectangle.js
-java/awt/RenderingHints.js
-java/awt/Scrollbar.js
-java/awt/ScrollPane.js
-java/awt/Shape.js
-java/awt/Stroke.js
-java/awt/TextArea.js
-java/awt/TextComponent.js
-java/awt/TextField.js
-java/awt/Toolkit.js
-java/awt/Transparency.js
-java/awt/Window.js
-java/beans/ChangeListenerMap.js
-java/beans/PropertyChangeEvent.js
-java/beans/PropertyChangeListener.js
-java/beans/PropertyChangeSupport.js
-java/lang/AbstractStringBuilder.js
-java/lang/Class.js
-java/lang/Enum.js
-java/lang/Iterable.js
-java/lang/reflect/Constructor.js
-java/lang/reflect/Method.js
-java/lang/StringBuffer.js
-java/lang/StringBuilder.js
-java/lang/Thread.js
-java/lang/ThreadGroup.js
-java/math/RoundingMode.js
-java/net/URL.js
-java/net/URLStreamHandlerFactory.js
-java/net/HttpURLConnection.js
-java/net/URLStreamHandler.js
-javax/net/ssl/HttpsUrlConnection.js
-java/text/CharacterIterator.js
-java/text/DecimalFormat.js
-java/text/DecimalFormatSymbols.js
-java/text/DigitList.js
-java/text/FieldPosition.js
-java/text/Format.js
-java/text/NumberFormat.js
-java/util/AbstractCollection.js
-java/util/AbstractList.js
-java/util/AbstractMap.js
-java/util/AbstractSequentialList.js
-java/util/AbstractSet.js
-java/util/ArrayList.js
-java/util/Arrays.js
-java/util/Collection.js
-java/util/Collections.js
-java/util/Comparator.js
-java/util/Deque.js
-java/util/Dictionary.js
-java/util/Enumeration.js
-java/util/EventListener.js
-java/util/EventObject.js
-java/util/HashMap.js
-java/util/HashSet.js
-java/util/Hashtable.js
-java/util/IdentityHashMap.js
-java/util/Iterator.js
-java/util/LinkedHashMap.js
-java/util/LinkedList.js
-java/util/List.js
-java/util/ListResourceBundle.js
-java/util/Locale.js
-java/util/Map.js
-java/util/Objects.js
-java/util/Queue.js
-java/util/Random.js
-java/util/RandomAccess.js
-java/util/ResourceBundle.js
-java/util/Set.js
-java/util/TimSort.js
-java/util/Vector.js
-javajs/api/JSFunction.js
-javajs/util/AjaxURLConnection.js
-javajs/util/AjaxURLStreamHandlerFactory.js
-javajs/util/AU.js
-javajs/util/JSThread.js
-javajs/util/Lst.js
-javajs/util/PT.js
-javajs/util/Rdr.js
-javajs/util/SB.js
-javax/swing/AbstractAction.js
-javax/swing/AbstractButton.js
-javax/swing/AbstractListModel.js
-javax/swing/Action.js
-javax/swing/ActionMap.js
-javax/swing/AncestorNotifier.js
-javax/swing/ArrayTable.js
-javax/swing/border/AbstractBorder.js
-javax/swing/border/BevelBorder.js
-javax/swing/border/Border.js
-javax/swing/border/CompoundBorder.js
-javax/swing/border/EmptyBorder.js
-javax/swing/border/EtchedBorder.js
-javax/swing/border/LineBorder.js
-javax/swing/border/TitledBorder.js
-javax/swing/BorderFactory.js
-javax/swing/BoundedRangeModel.js
-javax/swing/BoxLayout.js
-javax/swing/ButtonGroup.js
-javax/swing/ButtonModel.js
-javax/swing/ClientPropertyKey.js
-javax/swing/ComboBoxModel.js
-javax/swing/DefaultBoundedRangeModel.js
-javax/swing/DefaultButtonModel.js
-javax/swing/DefaultComboBoxModel.js
-javax/swing/DefaultSingleSelectionModel.js
-javax/swing/DropMode.js
-javax/swing/event/AncestorEvent.js
-javax/swing/event/AncestorListener.js
-javax/swing/event/CaretEvent.js
-javax/swing/event/CaretListener.js
-javax/swing/event/ChangeEvent.js
-javax/swing/event/ChangeListener.js
-javax/swing/event/DocumentEvent.js
-javax/swing/event/DocumentListener.js
-javax/swing/event/EventListenerList.js
-javax/swing/event/ListDataEvent.js
-javax/swing/event/ListDataListener.js
-javax/swing/event/UndoableEditEvent.js
-javax/swing/event/UndoableEditListener.js
-javax/swing/FocusManager.js
-javax/swing/InternalFrameFocusTraversalPolicy.js
-javax/swing/LayoutComparator.js
-javax/swing/LayoutFocusTraversalPolicy.js
-javax/swing/SortingFocusTraversalPolicy.js
-javax/swing/SwingContainerOrderFocusTraversalPolicy.js
-javax/swing/SwingDefaultFocusTraversalPolicy.js
-javax/swing/Icon.js
-javax/swing/ImageIcon.js
-javax/swing/InputMap.js
-javax/swing/JApplet.js
-javax/swing/JButton.js
-javax/swing/JCheckBox.js
-javax/swing/JCheckBoxMenuItem.js
-javax/swing/JComboBox.js
-javax/swing/JComponent.js
-javax/swing/JFrame.js
-javax/swing/JLabel.js
-javax/swing/JLayeredPane.js
-javax/swing/JMenu.js
-javax/swing/JMenuBar.js
-javax/swing/JMenuItem.js
-javax/swing/JPanel.js
-javax/swing/JPopupMenu.js
-javax/swing/JRadioButtonMenuItem.js
-javax/swing/JRootPane.js
-javax/swing/JScrollBar.js
-javax/swing/JScrollPane.js
-javax/swing/JSeparator.js
-javax/swing/JTextArea.js
-javax/swing/JTextField.js
-javax/swing/JToggleButton.js
-javax/swing/JViewport.js
-javax/swing/KeyboardManager.js
-javax/swing/KeyStroke.js
-javax/swing/ListModel.js
-javax/swing/LookAndFeel.js
-javax/swing/MenuElement.js
-javax/swing/MutableComboBoxModel.js
-javax/swing/plaf/ActionMapUIResource.js
-javax/swing/plaf/basic/BasicBorders.js
-javax/swing/plaf/BorderUIResource.js
-javax/swing/plaf/ColorUIResource.js
-javax/swing/plaf/ComponentUI.js
-javax/swing/plaf/DimensionUIResource.js
-javax/swing/plaf/FontUIResource.js
-javax/swing/plaf/InputMapUIResource.js
-javax/swing/plaf/InsetsUIResource.js
-javax/swing/plaf/UIResource.js
-javax/swing/RepaintManager.js
-javax/swing/RootPaneContainer.js
-javax/swing/Scrollable.js
-javax/swing/ScrollPaneConstants.js
-javax/swing/ScrollPaneLayout.js
-javax/swing/SingleSelectionModel.js
-javax/swing/SizeRequirements.js
-javax/swing/SwingConstants.js
-javax/swing/SwingPaintEventDispatcher.js
-javax/swing/SwingUtilities.js
-javax/swing/text/AbstractDocument.js
-javax/swing/text/AttributeSet.js
-javax/swing/text/Caret.js
-javax/swing/text/DefaultCaret.js
-javax/swing/text/DefaultEditorKit.js
-javax/swing/text/Document.js
-javax/swing/text/EditorKit.js
-javax/swing/text/Element.js
-javax/swing/text/GapContent.js
-javax/swing/text/GapVector.js
-javax/swing/text/JTextComponent.js
-javax/swing/text/MutableAttributeSet.js
-javax/swing/text/PlainDocument.js
-javax/swing/text/PlainView.js
-javax/swing/text/Position.js
-javax/swing/text/Segment.js
-javax/swing/text/SegmentCache.js
-javax/swing/text/SimpleAttributeSet.js
-javax/swing/text/Style.js
-javax/swing/text/StyleConstants.js
-javax/swing/text/StyleContext.js
-javax/swing/text/TabExpander.js
-javax/swing/text/TextAction.js
-javax/swing/text/Utilities.js
-javax/swing/text/View.js
-javax/swing/tree/TreeNode.js
-javax/swing/UIDefaults.js
-javax/swing/UIManager.js
-javax/swing/undo/AbstractUndoableEdit.js
-javax/swing/undo/CompoundEdit.js
-javax/swing/undo/UndoableEdit.js
-javax/swing/ViewportLayout.js
-javax/swing/WindowConstants.js
-sun/awt/AppContext.js
-sun/awt/AWTAutoShutdown.js
-sun/awt/CausedFocusEvent.js
-sun/awt/ComponentFactory.js
-sun/awt/KeyboardFocusManagerPeerProvider.js
-sun/awt/MostRecentKeyValue.js
-sun/awt/MostRecentThreadAppContext.js
-sun/awt/PaintEventDispatcher.js
-sun/awt/PostEventQueue.js
-sun/awt/RequestFocusController.js
-sun/awt/SunToolkit.js
-sun/awt/WindowClosingListener.js
-sun/awt/WindowClosingSupport.js
-sun/awt/image/DataStealer.js
-sun/awt/image/IntegerComponentRaster.js
-sun/awt/image/IntegerInterleavedRaster.js
-sun/awt/image/SunWritableRaster.js
-sun/font/FontDesignMetrics.js
-sun/swing/DefaultLookup.js
-sun/swing/SwingLazyValue.js
-sun/text/resources/FormatData.js
-sun/text/resources/en/FormatData_en.js
-sun/util/resources/LocaleData.js
-sun/util/locale/BaseLocale.js
-sun/util/locale/LocaleUtils.js
-sun/util/locale/provider/LocaleProviderAdapter.js
-sun/util/locale/provider/LocaleDataMetaInfo.js
-swingjs/a2s/A2SContainer.js
-swingjs/a2s/A2SEvent.js
-swingjs/a2s/A2SListener.js
-swingjs/a2s/Applet.js
-swingjs/a2s/Button.js
-swingjs/a2s/Label.js
-swingjs/a2s/Panel.js
-swingjs/a2s/Scrollbar.js
-swingjs/a2s/ScrollPane.js
-swingjs/a2s/TextArea.js
-swingjs/a2s/TextField.js
-swingjs/api/Interface.js
-swingjs/api/js/DOMNode.js
-swingjs/api/js/HTML5CanvasContext2D.js
-swingjs/api/js/JSInterface.js
-swingjs/jquery/JQueryUI.js
-swingjs/JSApp.js
-swingjs/JSAppletThread.js
-swingjs/JSAppletViewer.js
-swingjs/JSFocusPeer.js
-swingjs/JSFontMetrics.js
-swingjs/JSFrameViewer.js
-swingjs/JSGraphics2D.js
-swingjs/JSGraphicsConfiguration.js
-swingjs/JSGraphicsEnvironment.js
-swingjs/JSImage.js
-swingjs/JSImagekit.js
-swingjs/JSMouse.js
-swingjs/JSNullComponentPeer.js
-swingjs/JSScreenDevice.js
-swingjs/JSThreadGroup.js
-swingjs/JSToolkit.js
-swingjs/JSUtil.js
-swingjs/plaf/ButtonListener.js
-swingjs/plaf/DefaultMenuLayout.js
-swingjs/plaf/HTML5LookAndFeel.js
-swingjs/plaf/JSAppletUI.js
-swingjs/plaf/JSButtonUI.js
-swingjs/plaf/JSCheckBoxMenuItemUI.js
-swingjs/plaf/JSCheckBoxUI.js
-swingjs/plaf/JSComboBoxUI.js
-swingjs/plaf/JSComponentUI.js
-swingjs/plaf/JSEventHandler.js
-swingjs/plaf/JSFrameUI.js
-swingjs/plaf/JSGraphicsUtils.js
-swingjs/plaf/JSLabelUI.js
-swingjs/plaf/JSLayeredPaneUI.js
-swingjs/plaf/JSLightweightUI.js
-swingjs/plaf/JSMenuBarUI.js
-swingjs/plaf/JSMenuItemUI.js
-swingjs/plaf/JSMenuUI.js
-swingjs/plaf/JSPanelUI.js
-swingjs/plaf/JSPopupMenuSeparatorUI.js
-swingjs/plaf/JSPopupMenuUI.js
-swingjs/plaf/JSRadioButtonMenuItemUI.js
-swingjs/plaf/JSRadioButtonUI.js
-swingjs/plaf/JSRootPaneUI.js
-swingjs/plaf/JSScrollBarUI.js
-swingjs/plaf/JSScrollPaneUI.js
-swingjs/plaf/JSSeparatorUI.js
-swingjs/plaf/JSSliderUI.js
-swingjs/plaf/JSTextAreaUI.js
-swingjs/plaf/JSTextFieldUI.js
-swingjs/plaf/JSTextUI.js
-swingjs/plaf/JSTextViewUI.js
-swingjs/plaf/JSViewportUI.js
-swingjs/plaf/JSWindowUI.js
-swingjs/plaf/LazyActionMap.js
-swingjs/plaf/Resizer.js
-swingjs/plaf/TextListener.js
-
-
+++ /dev/null
-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
-
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="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<Object,PRESENT>:
-
- [HashSet] makes no guarantees as to the iteration order of the set.
-
-JavaScript's Map object is different. It is basically a LinkedHashMap, so it guarantees iteration
-in order of object addition.
-
-Starting with java2script 3.2.9.v1, these classes use the JavaScript Map object rather than hash codes
-whenever all keys are strictly of JavaScript typeof "string". If any key is introduced that is not a string, the
-implementation falls back to using hash codes, the same as Java.
-
-Note strings created using new String("xxxx") are NOT typeof "string"; they are typeof "object".
-
-The result is significantly faster performance (3-12 x faster) than originally, and up to 3 x faster
-performance in JavaScript than in Java itself. Right. Faster than Java.
-
-The JavaScript Map implementation is implemented UNLESS the constructor used is the one that
-specifies both initial capacity and load factor in their constructor. Thus,
-
-new Hashtable()
-new HashMap()
-new HashMap(16)
-new HashSet()
-
-all use the JavaScript Map. But
-
-new Hashtable(11, 0.75f)
-new HashMap(16, 0.75f)
-new HashSet(16, 0.75f)
-
-do not.
-
-This design allows for opting out of the JavaScript Map use in order to retain the exact behavior of
-iterators in JavaScript as in Java.
-
-
-interning, new String("xxx") vs "xxx"
--------------------------------------
-
-Note that the following are true in JavaScript:
-
-typeof new String("xxxx") == "object"
-typeof "xxxx" == "string"
-var s = "x";typeof ("xxx" + s) == "string"
-
-There is no equivalence to this behavior in Java, where a String is a String is a String.
-
-Be aware that SwingJS does not always create a JavaScript String object using JavaScript's
-new String(...) constructor. It only does this for Java new String("xxxx") or new String(new String()).
-
-In all other cases, new String(...) (in Java) results in a simple "xxxx" string in JavaScript.
-That is, it will be JavaScript typeof "string", not typeof "object".
-
-The reason for this design is that several classes in the Java core use toString()
-methods that return new String(), and those classes that do that would cause a JavaScript error
-if implicitly stringified if new String() returned a JavaScript String object.
-
-This is fine in JavaScript
-
-test1 = function() { return { toString:function(){ return "OK" } } }
-"testing" + new test1()
->> "testingOK"
-
-But for whatever reason in JavaScript:
-
-test2 = function() { return { toString:function(){ return new String("OK") } } }
-"testing" + new test2()
->> Uncaught TypeError: Cannot convert object to primitive value
-
-The lesson here is never to use
-
- return new String("...");
-
-in a Java toString() method. In Java it will be fine; in JavaScript it will also be fine as long as
-that method is never called in JavaScript implicitly in the context of string concatenation.
-
-A note about interning. Consider the following six Java constructions, where we have a == "x";
-
-"xxx"
-"xx" + "x"
-new String("xxx").intern()
-
-new String("xxx")
-"xx" + a.toString()
-"xx" + a
-
-All six of these will return java.lang.String for .getClass().getName().
-However, the first three are String literals, while the last three are String objects.
-Thus:
- "xxx" == "xxx"
- "xxx" == "xx" + "x"
- "xxx" == new String("xxx").intern()
-
-but none of the other three are equivalent to "xxx" or each other:
-
- "xxx" != new String("xxx")
- "xxx" != "xx" + a.toString()
- "xxx" != "xx" + a
- new String("xxx") != new String("xxx")
- "xx" + a != new String("xxx")
-
-etc.
-
-As in Java, in SwingJS, all of the following Java assertions pass as true:
-
- assert("xxx" == "xx" + "x");
- assert("xxx" == ("xx" + a).intern());
- assert("xxx" === new String("xxx").intern());
-
-and both of these do as well:
-
- assert(new String("xxx") != "xxx");
- assert(new String("xxx") != new String("xxx"));
-
-But the following two fail to assert true:
-
- assert("xxx" != "xx" + a);
- assert("xxx" != "xx" + a.toString());
-
-because in JavaScript, both of these right-side expressions evaluate to a simple "interned" string.
-
-In Java, however, these assertions are true because Java implicitly "boxes" String
-concatentaion as a String object, not a literal.
-
-Most of us know not to generally use == with Strings unless they are explicitly interned.
-Where this problem may arise, though, is in IdentityHashMap, which compares objects using
-System.identityHashCode(), which is not the same for different objects or their string literal equivalents.
-
-My recommendation, if you need to use IdentityHashMap with strings is to always use an explicit String.intern()
-for any keys -- unless you really want to keep every string as separate keys even if they are the same sequence,
-in which case, use new String(). This will work in Java and in JavaScript.
-
-Be aware when working with strings that come from SwingJS and are being used by other JavaScript modules
-that those that are String objects will return "object" for the JavaScript typeof operator, not "string".
-
-The easy way to ensure this is no problem is to concatenate strings with "" to force immediate interning:
-
- var x = aJavaObject.getString() + "";
-
-unless you are certain that the string is being returned is a raw JavaScript string.
-
-Names with "$" and "_"
-----------------------
-
-For the most part, this should be no problem.
-
-Note that the use of $ and _ in Java field names has always been discouraged:
-[https://docs.oracle.com/javase/tutorial/java/nutsandbolts/variables.html]
-
- You may find some situations where auto-generated names will contain the dollar sign,
- but your variable names should always avoid using it. A similar convention
- exists for the underscore character; while it's technically legal to begin your
- variable's name with "_", this practice is discouraged.
-
-Some impacts of transpiling method names with full qualification:
-
-1) SwingJS will introduce fields that start with $ or _. These will not conflict
- if the above convention is followed.
-
-2) Fields that have the same Java name as a method are not an issue.
-
-3) Fields that have a Java name with $ that matches a transpiled method name,
- such as toString$, will need to be refactored in Java to not have that name collision.
-
-4) Fields in a subclass that have the same name as private fields in a superclass
- represent a name collision, because the superclass method needs to call its private
- field even if invoked from a subclass. The solution was to modify the subclass field
- name using one or more prepended $.
-
-5) Use of Class.getDeclaredMethods() reflection will return Method objects having the transpiled
- name, not the Java name. This could require some j2sNative adjustment
- to strip the $... parameters from the name if that is needed.
-
-6) Use of Method.getParameterTypes() should work fine, provided class names
- do not contain "_". This is because the transpiler converts "." to "_" when
- creating the fully qualified JavaScript name.
-
-
-positive integers do not add to give negative numbers
------------------------------------------------------
-
-In Java, the following is true:
-
- 2000000000 + 2000000000 == -294967296
-
-But in SwingJS, that will be 4000000000. So, for example, the following
-strategy will fail in SwingJS:
-
- int newLength = lineBuf.length * 2;
- if (newLength < 0) {
- newLength = Integer.MAX_VALUE;
- }
-
-"-1" in JavaScript is not 0xFFFFFFFF.
-
-And one must take care to not compare a negative number with a 32-bit mask. So
-
-(b & 0xFF000000) == 0xFF000000
-
-is true in Java for (int) b = -1, but is false in JavaScript, because 0xFF000000 is 4278190080,
-while (-1 & 0xFF000000) is, strangely enough, -16777216, and, in fact,
-
-(0xFF000000 & 0xFF000000) != 0xFF000000
-
-because -16777216 is not 4278190080.
-
-The fix is that one must compare similar operations:
-
-if ((b & 0xFF000000) == (0xFF000000 & 0xFF000000)) .....
-
-Importantly, the JavaScript Int32Array does behave properly. From
-the Firefox developer console:
-
->> x = new Int32Array(1)
-<- Int32Array(1) [ 0 ]
->> x[0] = 4000000000
-<- 4000000000
->> x[0]
-<- -294967296
-
-Notice that, perhaps unexpectedly, the following two constructs produce
-different results in JavaScript:
-
-x = new Int32Array(1);
-b = x[0] = 4000000000;
-
-(b will be 4000000000)
-
-and
-
-x = new Int32Array(1);
-x[0] = 4000000000;
-b = x[0];
-
-(b will be -294967296)
-
-
-SwingJS leverages array typing to handle all byte and short arithmetic so as
-to ensure that any byte or short operation in JavaScript does give the same
-result in Java. The design decision to not also do this with integer math was
-a trade-off between performance and handling edge cases.
-
-
-ArrayIndexOutOfBounds
----------------------
-
-You cannot implicitly throw an ArrayIndexOutOfBoundsException in JavaScript.
-JavaScript will simply return "undefined", not throw an Exception. So:
-
-boolean notAGoodIdeaIsOutOfBounds(String[] sa, int i) {
- try {
- return (sa[i] == sa[i]);
- } catch (ArrayIndexOutOfBoundsException e) {
- return false;
- }
-}
-
-will work in Java but not in JavaScript. Code should not depend upon this sort
-of trap anyway, if you ask me.
-
-Throwable vs Error vs Exception
--------------------------------
-
-True JavaScript errors are trapped as Throwable, whereas you can still trap
-Error and Exception as well. So if you want to be sure to catch any JavaScript
-error, use try{}catch (Throwable t){}, not try{}catch (Exception e){}.
-
-j
-ava.awt.Color
---------------
-
-ColorSpace: only "support" CS_sRGB.
-
- TODO -- any volunteers??
-
-
-javax.swing.JFileDialog
------------------------
-
-HTML5 cannot expose a file reading directory structure. But you certainly
-can still do file reading and writing. It just works a little differently.
-It's a simple modification:
-
- b = new JButton("FileOpenDialog");
- b.addActionListener(new ActionListener() {
-
- @Override
- public void actionPerformed(ActionEvent e) {
- JFileChooser fc = new JFileChooser();
- Test_Dialog.this.onDialogReturn(fc.showOpenDialog(Test_Dialog.this));
- // Java will wait until the dialog is closed, then enter the onDialogReturn method.
- // JavaScript will exit with NaN immediately, and then call back with its actual value
- // asynchronously.
- }
-
- });
-
- public void onDialogReturn(int value) {
- if (value != Math.floor(value))
- return; // in JavaScript, this will be NaN, indicating the dialog has been opened
- // If we are here, the dialog has closed, in both Java and JavaScript.
- System.out.println("int value is " + value);
- }
-
-
- @Override
- public void propertyChange(PropertyChangeEvent event) {
- Object val = event.getNewValue();
- String name = event.getPropertyName();
- System.out.println(name);
- switch (event.getSource().getClass().getName()) {
- case "javax.swing.JOptionPane":
- switch (name) {
- case "inputValue":
- onDialogReturn(val);
- return;
- case "value":
- if (val instanceof Integer)
- onDialogReturn(((Integer) val).intValue());
- else
- onDialogReturn(val);
- return;
- }
- break;
- case "javax.swing.ColorChooserDialog":
- switch (name) {
- case "SelectedColor":
- onDialogReturn(val);
- return;
- }
- break;
- case "javax.swing.JFileChooser":
- switch (name) {
- case "SelectedFile":
- File file = (File) val;
- byte[] array = (val == null ? null : /** @j2sNative file.秘bytes || */
- null);
- onDialogReturn("fileName is '" + file.getName() + "'\n\n" + new String(array));
- return;
- }
- break;
- }
- System.out.println(
- event.getSource().getClass().getName() + " " + event.getPropertyName() + ": " + event.getNewValue());
- }
-
-
-Developers are encouraged to create a separate class that handles general calls to JFileDialog.
-An example class can be found in the SwingJS distribution as
-
-/sources/net.sf.j2s.java.core/src/javajs/async/AsyncFileChooser.java.
-
-
-javax.swing.JOptionPane dialogs
--------------------------------
-
-For this action to work, the parentComponent must implement
-propertyChangeListener, and any call to JOptionPanel should allow for
-an asynchronous response, meaning that there is no actionable code following the
-call to the dialog opening.
-
-In addition, for compatibility with the Java version, implementation should
-wrap the call to getConfirmDialog or getOptionDialog in a method call to
-handle the Java:
-
-onDialogReturn(JOptionPane.showConfirmDialog(parentFrame,
-messageOrMessagePanel, "title", JOptionPane.OK_CANCEL_OPTION));
-
-Then parentFrame.propertyChange(event) should also call onDialogReturn.
-
-This will then work in both Java and JavaScript.
-
-Note that there is an int and an Object version of onDialogReturn().
-
-
-In JavaScript:
-
-The initial return from JOptionPane.showConfirmDialog and showMessageDialog
-will be (SwingJS) JDialog.ASYNCHRONOUS_INTEGER (NaN), testable as an impossible
-Java int value using ret != -(-ret) if the parent implements PropertyChangeListener, or -1
-(CLOSE_OPTION) if not.
-
-For showOptionDialog (which returns Object) or showInputDialog (which returns
-String), the initial return will be (SwingJS) JDialog.ASYNCHRONOUS_OBJECT, testable as
-((Object) ret) instanceof javax.swing.plaf.UIResource if the parent implements
-PropertyChangeListeneer, or null if not.
-
-The second return will be the desired return.
-
-In Java:
-
-The initial return will be the one and only modal final return.
-
-
-
-For full compatibility, The calling method must not continue beyond this
-call.
-
-All of the standard Java events associated with Components are also
-available.
-
-Certain fall back mechanisms are possible, where onReturn does not exist, but
-only for the following cases:
-
-
-For showMessageDialog, for WARNING_MESSAGE and ERROR_MESSAGE, a simple
-JavaScript alert() is used, returning 0 (OK_OPTION) or -1 (CLOSED_OPTION).
-
-For showInputDialog, if the message is a string, a simple JavaScript prompt()
-with input box is used, returning the entered string or null.
-
-For showConfirmDialog, a simple JavaScript confirm() is used, in which case:
-
-for YES_NO_OPTION: YES_OPTION or NO_OPTION
-
-for YES_NO_CANCEL_OPTION: YES_OPTION or CANCEL_OPTION
-
-for OK_CANCEL_OPTION or any other: OK_OPTION or CANCEL_OPTION
-
-Note that you should implement a response for CLOSED_OPTION for
-showConfirmDialog. For other dialogs, a null return indicates the dialog was
-closed, just as for Java.
-
-Developers are encouraged to create a separate class that handles general calls.
-An example class can be found in the SwingJS distribution as src/javajs/async/AsyncDialog.java.
-Very simple modifications to the Java allows asynchronous operation using AsyncDialog. Here
-is a simple "do you want to close this frame" example, where you can see that what we have
-done is to set the reply into an ActionListener that is defined in the constructor of
-the AsyncDisplay object:
-
-// Original:
-//
-// private void promptQuit() {
-// int sel = JOptionPane.showConfirmDialog(null, PROMPT_EXIT, NAME, JOptionPane.YES_NO_OPTION);
-// switch (sel) {
-// case JOptionPane.YES_OPTION:
-// resultsTab.clean();
-// seqs.dispose();
-// if (fromMain) {
-// System.exit(0);
-// }
-// break;
-// }
-// }
-
- private void promptQuitAsync() {
- new AsyncDialog(new ActionListener() {
-
- @Override
- public void actionPerformed(ActionEvent e) {
- int sel = ((AsyncDialog)e.getSource()).getOption();
- switch (sel) {
- case JOptionPane.YES_OPTION:
- resultsTab.clean();
- seqs.dispose();
- if (fromMain) {
- System.exit(0);
- }
- break;
- }
- }}).showConfirmDialog(null, PROMPT_EXIT, NAME, JOptionPane.YES_NO_OPTION);
- }
-
-Very simple!
-
-
-native methods
---------------
-
-The J2S compiler ignores all static native method declarations.
-Anything of this nature needs to be implemented in JavaScript if it is needed,
-using j2sNative blocks:
-
-/**
- * @j2sNative
- *
- * var putYourJavaScriptCodeHere
- *
- */
-
- Note that if you follow that directly with a {...} block, then
- the javadoc code will run in JavaScript, and the {...} code will run in Java.
-
-
-key Focus
----------
-
-As of June, 2019, the keyboard focus manager is fully implemented.
-The one catch is that JTextPane and JTextArea, which already consume
-VK_TAB in Java, cannot use CTRL-TAB to continue a tabbing cycle around
-the components in a window. Instead, CTRL-TAB is absorbed by the browser.
-
-
-LookAndFeel and UI Classes
---------------------------
-
-SwingJS implements the native browser look and feel as swingjs.plaf.HTML5LookAndFeel.
-There are small differences between all look and feels -- MacOS, Windows, SwingJS.
-
-Expert developers know how to coerce changes in the UI by subclassing the UI for a
-component. This probably will not work in SwingJS.
-
-Note that LookAndFeel in Java usually determines canvas size in a Frame because
-different operating systems (Mac OS vs Windows vs HTML5) will have
-different edge sizes on their frames. If you want to ensure a component size,
-use getContentPane().setPreferredSize().
-
-
-System.exit(0) does not stop all processes
-------------------------------------------
-
-Although System.ext(int) has been implemented in JavaScript, it just closes the
-frames, stops all pending javax.swing.Timer objects in the queue, and runs any
-threads added using Runtime.getRuntime().addShutdownHook(Thread).
-It may not stop all "threads." So don't rely on that.
-Applications are responsible for shutting down prior to executing System.exit(0).
-
-
-myClass.getField not implemented
---------------------------------
-
-java.lang.reflect.Field is implemented minimally. It is not
-certain that Field.getDeclaringClass() will work. If you just want a
-value of a field, you can do this:
-
-/**
- *@j2sNative
- *
- * return myClass[name]
- */
-
-But that is not a java.lang.reflection.Field object.
-
-
-"window" and other reserved JavaScript names
---------------------------------------------
-
-No reserved top-level JavaScript name is allowed for a package name. So, for example,
-one must rename packages such as "window" or "document" to names such as "win" or "doc".
-
-reserved field and method names
--------------------------------
-
-In order to minimize the chance of added SwingJS field and method names colliding with ones
-developers might use in subclassing Java classes, we have added U+79D8 (first character of Mandarin
-"secret") to the characters already disrecommended by Java documentation ("$" and "_"). The only problem
-would be if you use that character followed by certain English words in certain classes. For example
-\u79D8canvas for JComponents (in java.awt.JSComponent) and \u79D8byte (in java.io.File).
-
-qualified field and method names
---------------------------------
-
-Method names in SwingJS are fully qualified, meaning two methods with the same Java name but different
-parameters, such as write(int) and write(double), must not have the same name in JavaScript. (In this
-case, we will have write$I and write$D.) However, in certain cases it may be desirable to leave the
-method names unqualified. In particular, when an interface actually represents a JavaScript object,
-the transpiler can leave a method name unqualified. The default situation for this is a class name
-includes ".api.js" (case-sensitive). This means that any method in any class in a package js within
-a package api, or any private interface js that has an outer interface api, will have all-unqualified
-methods. An example of this is swingjs.plaf.JSComboPopupList, which needs to communicate with a jQuery
-object directly using the following interface:
-
- private interface api {
-
- interface js extends JQueryObject {
-
- abstract js j2sCB(Object options);
-
- abstract Object[] j2sCB(String method);
-
- abstract Object[] j2sCB(String method, Object o);
-
- abstract Object[] j2sCB(String method, int i);
-
- abstract int j2sCB(String OPTION, String name);
-
- }
- }
-
-Notice that all these variants of j2sCB() will call the same method in JavaScript by design.
-
-
-missing Math methods
---------------------
-
-java.lang.Math is worked out, but some methods are missing, either because they
-involve long integer value that are inaccessible in JavaScript, or because I just
-didn't implement them. This is a result of continued Java development.
-It is easy enough to add these methods if you have the source. They go into j2sClazz.js,
-which is combined with other initial libraries into swingjs2.js by build_site.xml
-
-
-Component.getGraphics(), Graphics.dispose()
--------------------------------------------
-
-Use of component.getGraphics() is discouraged in Java and in SwingJS.
-Specifically in SwingJS, any call to component.getGraphics() or
-BufferedImage.createGraphics() or Graphics.create(...) should be matched with graphics.dispose(),
-particularly when it is called outside the context of a paint(Graphics)
-call from the system.
-
-If you see your graphics scrolling down the page with each repaint,
-look for where you have used Component.getGraphics() and not Graphics.dispose().
-For example, this will definitely NOT work in SwingJS:
-
- this.paint(getGraphics())
-
-and really should not work in Java, either, as it is technically a resource memory leak.
-
-Instead, if you really do not want to use repaint(), use this:
-
- Graphics g = getGraphics();
- paint(g);
- g.dispose();
-
-
-
-Graphics.setClip()
-------------------
-
-The HTML5 canvas.clip() method is permanent. You can only reset the clip using
-save/restore. This is different from Java, where you can temporarily change it using
-
- Shape oldClip = Graphics.getClip();
- Graphics.setClip(newClip);
- ...
- Graphics.setClip(oldClip);
-
-If you need to do something like this, you must schedule the paints
-to not have overlapping clip needs.
-
-
-MAJOR ISSUES--for Bob and Udo within SwingJS
-============================================
-
-fonts
------
-
-Fonts and FontMetrics will all be handled in JavaScript. Font matching will
-not be exact, and composite (drawn) fonts will not be supported.
-
-SwingJS handles calls such as font.getFontMetrics(g).stringWidth("xxx") by
-creating a <div> containing that text, placing it in an obscure location on
-the page, and reading div.getBoundingClientRect(). This is a VERY precise
-value, but can be a pixel or two off from what Java reports for the same font.
-
-
-OS-dependent classes
---------------------
-
-Static classes such as:
-
- java.awt.Toolkit
- java.awt.GraphicsEnvironment
-
-
-which are created using Class.forName are implemented using classes in the swingjs package.
-
-AWTAccessor is not implemented.
-
-
-AWT component peers and component "ui" user interfaces
-------------------------------------------------------
-
-ComponentPeer is a class that represents a native AWT component.
-Components with such peers are called "heavy-weight" components.
-They are expected to do the dirty work of graphics drawing.
-
-Java Swing implements peers only for JApplet, JDialog, JFrame, and JWindow.
-References to such objects have been removed, but clearly there must be
-some connection to similar DOM objects, even for "light-weight" components.
-
-
-
-MAJOR ISSUES--to be resolved by implementers
-============================================
-
-fonts
------
-
-Glyph/composite/outline fonts are not supported.
-
-
-
-threads
--------
-
-Thread locking and synchronization are not relevant to JavaScript.
-Thus, anything requiring "notify.." or "waitFor.." could be a serious issue.
-
-All threading must be "faked" in JavaScript. Specifically not available is:
-
- Thread.sleep()
-
-javax.swing.AbstractButton#doClick(pressTime) will not work, as it requires Thread.sleep();
-
-However, java.lang.Thread itself is implemented and used extensively.
-
-Methods thread.start() and thread.run() both work fine.
-
-For simple applications that use Thread.sleep() just to have a delay, as in a frame rate, for
-example, one can use javax.swing.Timer instead. That is fully implemented.
-
-Likewise, java.util.Timer can be replaced with no loss of performance with javax.Swing.Timer.
-Note that java.util.TimerTask is implemented, but it can also be replaced by an implementation of Runnable.
-
-task = new TimerTask(){....};
-t = new java.util.Timer();
-t.schedule(task, 0, 1);
-
-becomes
-
-task = new TimerTask(){....}; // or task = new Runnable() {...}
-t = new javax.swing.Timer(1, new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- task.run();
- }
-};
-t.setInitialDelay(0); // not particularly necessary
-t.start();
-
-In addition, SwingJS provides swingjs.JSThread, which can be subclassed
-if desired. This class allows simple
-
- while(!interrupted()){
- wait()
- ...
- }
-
-action through an asynchronous function run1(mode). For example:
-
- protected void run1(int mode) {
- try {
- while (true)
- switch (mode) {
- case INIT:
- // once-through stuff here
- mode = LOOP;
- break;
- case LOOP:
- if (!doDispatch || isInterrupted()) {
- mode = DONE;
- } else {
- Runnable r = new Runnable() {
- public void run() {
- // put the loop code here
- }
- };
- dispatchAndReturn(r);
- if (isJS)
- return;
- }
- break;
- // add more cases as needed
- case DONE:
- // finish up here
- if (isInterrupted())
- return;
- // or here
- break;
- }
- } finally {
- // stuff here to be executed after each loop in JS or at the end in Java
- }
- }
-
-image loading
--------------
-- All image loading in SwingJS is synchronous. A MediaTracker call will immediately return "complete".
- However, it still may take one system clock tick to fully load images. Thus, it is recommended that
- images be preloaded in the static block of the applet if it is necessary that they be available in init().
- This is only an issue if you are trying to access the pixel buffer of the image in JavaScript.
-
-- Applet.getImage(path, name) will return null if the image does not exist.
-
-- BufferedImage: only "support" imageType RGB and ARGB
-
- -BH: This is a temporary edit, just to get us started. Certainly GRAY will be needed
-
-
-BigInteger and BigDecimal
--------------------------
-
-java.math.BigInteger is fully supported; java.math.BigDecimal is roughed
-in and not fully tested (07/2019).
-
-Both classes present significant issues for JavaScript, as they are based in
-Java's 64-bit long for all their operations. Here is the JavaDoc note I added
-to BigInteger:
-
- * SwingJS note: Because of the limitations of JavaScript with regard
- * to long-integer bit storage as a double, this implementation drops
- * the integer storage bit length to 24, giving 48 for long and leaving
- * the last 16 bits clear for the exponent of the double number. This should
- * not affect performance significantly. It does increase the storage
- * size by about 33%. By bringing an "int" to 3 bytes, we can easily construct
- * and use byte[] data intended for the original BitSet.
-
-"Easily" may be a bit strong there. This was a serious challenge.
-
-BigDecimal seems to run normally, but in order to do that, my hack involves
-reducing the size of an integer that is allowed to be stored as such and not
-in byte[] as a BigInteger. I'm sure there is a performance hit, but it does work.
-
-no format internationalization
-------------------------------
-
-For now, just en for number and date formatters
-
-no winding rules
-----------------
-
- When filling a graphic, only nonzero winding rule is implemented in HTML5 Canvas2D.
-
-
-
-text-related field implementation
----------------------------------
-
-Text fields are:
-
-JTextField (JavaScript <input type="text">)
-JTextArea (JavaScript <textarea>)
-JTextPane (JavaScript <div>)
-JEditorPane (JavaScript <div>)
-
-For the initial implementation, we don't implement infinite undo/redo, and the abstract
-document model is much less elaborate. Only PlainDocument (in the form of JSPlainDocument)
-is implemented. The Document returned by JTextField.getDocument() is a javax.swing.text.Document.
-
-All scrolling is handled by HTML5. javax.swing.AutoScroller is not implemented.
-public static methods .stop, .isRunning, .processMouseDragged require true Java threading
-and so are not implmented. javax.swing.text.View and its subclasses are not implemented.
-
-The JS document model does not allow two text fields to address the same underlying document.
-
-JavaScript is slightly different from Java in that the field value is changed asynchronously after
-the keypressed event, so Java actions that are keyed to KEY_PRESSED may not pick up the new
-key value even after SwingUtilities.invokeLater() is called. Thus, key pressed actions may need
-to be recorded after a key released event instead.
-
-Formatter/Regex limitations
----------------------------
-
-Some browsers cannot process Regex "look-behind" process such as (?<=\W)
-java.util.regex.Matcher and Pattern use JavaScript's RegExp object rather than
-the native Java object. These are not identical. Only flags /igm are supported.
-Matcher.start(groupID) is not supported.
-
-java.util.Formatter will function correctly for all standard %... patterns.
-
-integer 1/0 == Infinity
------------------------
-
-1/0 in Java throws "java.lang.ArithmeticException: / by zero", but in JavaScript is just Infinity.
-
-
-
-Summary
--------
-
-These are all the known limitations of SwingJS. We have not found any of these limitations
-to be show-stoppers. The primary issue for newcomers to SwingJS is having the source code.
-You must check that source code for all your library jar files is available or, if you
-choose, you will need to decompile those classes. We have used decompilation on some projects,
-and it works just fine. So, technically, all we really need are JAR/class files. But the
-source is by far superior. It's generally prettier, and it has the license information that
-may or may not be present with the JAR or class files. Use class files at your own risk.
-
-Bob Hanson
-2019.08.16
-
-
-Additional Issues
------------------
-
-Annotation is working for classes, methods, and fields (12/22/19). Method reflection, however,
-is limited. Interfaces do not expose their methods, as the transpiler does not actually transpile
-the interfaces themselves. And method reflection only includes annotated methods.
-
-java.util.concurrent is not fully elaborated. This package is rewritten to not actually use the
-memory handling capabilities of concurrency, which JavaScript does not have access to.
-
-System.getProperties() just returns a minimal set of properties.
-
-
+++ /dev/null
-20201219175119
+++ /dev/null
-This is sources/net.sf.j2s.java.core/dist/DEV_NOTES.txt
-
-_j2sclasslist.txt
-
-the list of .js files concatenated into coreswingjs.js and minified to coreswingjs.z.js
-
-
-SwingJS-site.zip
-
-the full site directory for SwingJS including all files not in the test/ directory.
+++ /dev/null
-java/applet/Applet.js
-java/applet/AppletContext.js
-java/applet/AppletStub.js
-java/applet/JSApplet.js
-java/awt/ActiveEvent.js
-java/awt/Adjustable.js
-java/awt/AWTEvent.js
-java/awt/AWTEventMulticaster.js
-java/awt/AWTKeyStroke.js
-java/awt/BasicStroke.js
-java/awt/BorderLayout.js
-java/awt/Button.js
-java/awt/Color.js
-java/awt/color/ColorSpace.js
-java/awt/Component.js
-java/awt/ComponentOrientation.js
-java/awt/ContainerOrderFocusTraversalPolicy.js
-java/awt/Container.js
-java/awt/Cursor.js
-java/awt/DefaultFocusTraversalPolicy.js
-java/awt/DefaultKeyboardFocusManager.js
-java/awt/Dialog.js
-java/awt/Dimension.js
-java/awt/dnd/peer/DropTargetPeer.js
-java/awt/event/ActionListener.js
-java/awt/event/AdjustmentEvent.js
-java/awt/event/AdjustmentListener.js
-java/awt/event/AWTEventListener.js
-java/awt/event/ComponentAdapter.js
-java/awt/event/ComponentEvent.js
-java/awt/event/ComponentListener.js
-java/awt/event/ContainerListener.js
-java/awt/event/FocusEvent.js
-java/awt/event/FocusListener.js
-java/awt/event/HierarchyBoundsListener.js
-java/awt/event/HierarchyListener.js
-java/awt/event/InputEvent.js
-java/awt/event/InputMethodListener.js
-java/awt/event/InvocationEvent.js
-java/awt/event/ItemEvent.js
-java/awt/event/ItemListener.js
-java/awt/event/KeyListener.js
-java/awt/event/MouseEvent.js
-java/awt/event/MouseListener.js
-java/awt/event/MouseMotionListener.js
-java/awt/event/MouseWheelListener.js
-java/awt/event/TextListener.js
-java/awt/event/WindowAdapter.js
-java/awt/event/WindowEvent.js
-java/awt/event/WindowFocusListener.js
-java/awt/event/WindowListener.js
-java/awt/event/WindowStateListener.js
-java/awt/EventDispatchThread.js
-java/awt/EventFilter.js
-java/awt/EventQueue.js
-java/awt/EventQueueItem.js
-java/awt/FlowLayout.js
-java/awt/FocusTraversalPolicy.js
-java/awt/Font.js
-java/awt/font/FontRenderContext.js
-java/awt/FontMetrics.js
-java/awt/Frame.js
-java/awt/geom/AffineTransform.js
-java/awt/geom/Dimension2D.js
-java/awt/geom/Path2D.js
-java/awt/geom/PathIterator.js
-java/awt/geom/Point2D.js
-java/awt/geom/Rectangle2D.js
-java/awt/geom/RectangularShape.js
-java/awt/geom/RectIterator.js
-java/awt/GraphicsCallback.js
-java/awt/GraphicsConfiguration.js
-java/awt/GraphicsDevice.js
-java/awt/GraphicsEnvironment.js
-java/awt/Image.js
-java/awt/image/ImageObserver.js
-java/awt/Insets.js
-java/awt/ItemSelectable.js
-java/awt/JSComponent.js
-java/awt/JSDialog.js
-java/awt/JSFrame.js
-java/awt/JSPanel.js
-java/awt/KeyboardFocusManager.js
-java/awt/KeyEventDispatcher.js
-java/awt/KeyEventPostProcessor.js
-java/awt/Label.js
-java/awt/LayoutManager.js
-java/awt/LayoutManager2.js
-java/awt/LightweightDispatcher.js
-java/awt/Paint.js
-java/awt/Panel.js
-java/awt/peer/ComponentPeer.js
-java/awt/peer/ContainerPeer.js
-java/awt/peer/FramePeer.js
-java/awt/peer/KeyboardFocusManagerPeer.js
-java/awt/peer/LightweightPeer.js
-java/awt/peer/WindowPeer.js
-java/awt/Point.js
-java/awt/Queue.js
-java/awt/Rectangle.js
-java/awt/RenderingHints.js
-java/awt/Scrollbar.js
-java/awt/ScrollPane.js
-java/awt/Shape.js
-java/awt/Stroke.js
-java/awt/TextArea.js
-java/awt/TextComponent.js
-java/awt/TextField.js
-java/awt/Toolkit.js
-java/awt/Transparency.js
-java/awt/Window.js
-java/beans/ChangeListenerMap.js
-java/beans/PropertyChangeEvent.js
-java/beans/PropertyChangeListener.js
-java/beans/PropertyChangeSupport.js
-java/lang/AbstractStringBuilder.js
-java/lang/Class.js
-java/lang/Enum.js
-java/lang/Iterable.js
-java/lang/reflect/Constructor.js
-java/lang/reflect/Method.js
-java/lang/StringBuffer.js
-java/lang/StringBuilder.js
-java/lang/Thread.js
-java/lang/ThreadGroup.js
-java/math/RoundingMode.js
-java/net/URL.js
-java/net/URLStreamHandlerFactory.js
-java/net/HttpURLConnection.js
-java/net/URLStreamHandler.js
-javax/net/ssl/HttpsUrlConnection.js
-java/text/CharacterIterator.js
-java/text/DecimalFormat.js
-java/text/DecimalFormatSymbols.js
-java/text/DigitList.js
-java/text/FieldPosition.js
-java/text/Format.js
-java/text/NumberFormat.js
-java/util/AbstractCollection.js
-java/util/AbstractList.js
-java/util/AbstractMap.js
-java/util/AbstractSequentialList.js
-java/util/AbstractSet.js
-java/util/ArrayList.js
-java/util/Arrays.js
-java/util/Collection.js
-java/util/Collections.js
-java/util/Comparator.js
-java/util/Deque.js
-java/util/Dictionary.js
-java/util/Enumeration.js
-java/util/EventListener.js
-java/util/EventObject.js
-java/util/HashMap.js
-java/util/HashSet.js
-java/util/Hashtable.js
-java/util/IdentityHashMap.js
-java/util/Iterator.js
-java/util/LinkedHashMap.js
-java/util/LinkedList.js
-java/util/List.js
-java/util/ListResourceBundle.js
-java/util/Locale.js
-java/util/Map.js
-java/util/Objects.js
-java/util/Queue.js
-java/util/Random.js
-java/util/RandomAccess.js
-java/util/ResourceBundle.js
-java/util/Set.js
-java/util/TimSort.js
-java/util/Vector.js
-javajs/api/JSFunction.js
-javajs/util/AjaxURLConnection.js
-javajs/util/AjaxURLStreamHandlerFactory.js
-javajs/util/AU.js
-javajs/util/JSThread.js
-javajs/util/Lst.js
-javajs/util/PT.js
-javajs/util/Rdr.js
-javajs/util/SB.js
-javax/swing/AbstractAction.js
-javax/swing/AbstractButton.js
-javax/swing/AbstractListModel.js
-javax/swing/Action.js
-javax/swing/ActionMap.js
-javax/swing/AncestorNotifier.js
-javax/swing/ArrayTable.js
-javax/swing/border/AbstractBorder.js
-javax/swing/border/BevelBorder.js
-javax/swing/border/Border.js
-javax/swing/border/CompoundBorder.js
-javax/swing/border/EmptyBorder.js
-javax/swing/border/EtchedBorder.js
-javax/swing/border/LineBorder.js
-javax/swing/border/TitledBorder.js
-javax/swing/BorderFactory.js
-javax/swing/BoundedRangeModel.js
-javax/swing/BoxLayout.js
-javax/swing/ButtonGroup.js
-javax/swing/ButtonModel.js
-javax/swing/ClientPropertyKey.js
-javax/swing/ComboBoxModel.js
-javax/swing/DefaultBoundedRangeModel.js
-javax/swing/DefaultButtonModel.js
-javax/swing/DefaultComboBoxModel.js
-javax/swing/DefaultSingleSelectionModel.js
-javax/swing/DropMode.js
-javax/swing/event/AncestorEvent.js
-javax/swing/event/AncestorListener.js
-javax/swing/event/CaretEvent.js
-javax/swing/event/CaretListener.js
-javax/swing/event/ChangeEvent.js
-javax/swing/event/ChangeListener.js
-javax/swing/event/DocumentEvent.js
-javax/swing/event/DocumentListener.js
-javax/swing/event/EventListenerList.js
-javax/swing/event/ListDataEvent.js
-javax/swing/event/ListDataListener.js
-javax/swing/event/UndoableEditEvent.js
-javax/swing/event/UndoableEditListener.js
-javax/swing/FocusManager.js
-javax/swing/InternalFrameFocusTraversalPolicy.js
-javax/swing/LayoutComparator.js
-javax/swing/LayoutFocusTraversalPolicy.js
-javax/swing/SortingFocusTraversalPolicy.js
-javax/swing/SwingContainerOrderFocusTraversalPolicy.js
-javax/swing/SwingDefaultFocusTraversalPolicy.js
-javax/swing/Icon.js
-javax/swing/ImageIcon.js
-javax/swing/InputMap.js
-javax/swing/JApplet.js
-javax/swing/JButton.js
-javax/swing/JCheckBox.js
-javax/swing/JCheckBoxMenuItem.js
-javax/swing/JComboBox.js
-javax/swing/JComponent.js
-javax/swing/JFrame.js
-javax/swing/JLabel.js
-javax/swing/JLayeredPane.js
-javax/swing/JMenu.js
-javax/swing/JMenuBar.js
-javax/swing/JMenuItem.js
-javax/swing/JPanel.js
-javax/swing/JPopupMenu.js
-javax/swing/JRadioButtonMenuItem.js
-javax/swing/JRootPane.js
-javax/swing/JScrollBar.js
-javax/swing/JScrollPane.js
-javax/swing/JSeparator.js
-javax/swing/JTextArea.js
-javax/swing/JTextField.js
-javax/swing/JToggleButton.js
-javax/swing/JViewport.js
-javax/swing/KeyboardManager.js
-javax/swing/KeyStroke.js
-javax/swing/ListModel.js
-javax/swing/LookAndFeel.js
-javax/swing/MenuElement.js
-javax/swing/MutableComboBoxModel.js
-javax/swing/plaf/ActionMapUIResource.js
-javax/swing/plaf/basic/BasicBorders.js
-javax/swing/plaf/BorderUIResource.js
-javax/swing/plaf/ColorUIResource.js
-javax/swing/plaf/ComponentUI.js
-javax/swing/plaf/DimensionUIResource.js
-javax/swing/plaf/FontUIResource.js
-javax/swing/plaf/InputMapUIResource.js
-javax/swing/plaf/InsetsUIResource.js
-javax/swing/plaf/UIResource.js
-javax/swing/RepaintManager.js
-javax/swing/RootPaneContainer.js
-javax/swing/Scrollable.js
-javax/swing/ScrollPaneConstants.js
-javax/swing/ScrollPaneLayout.js
-javax/swing/SingleSelectionModel.js
-javax/swing/SizeRequirements.js
-javax/swing/SwingConstants.js
-javax/swing/SwingPaintEventDispatcher.js
-javax/swing/SwingUtilities.js
-javax/swing/text/AbstractDocument.js
-javax/swing/text/AttributeSet.js
-javax/swing/text/Caret.js
-javax/swing/text/DefaultCaret.js
-javax/swing/text/DefaultEditorKit.js
-javax/swing/text/Document.js
-javax/swing/text/EditorKit.js
-javax/swing/text/Element.js
-javax/swing/text/GapContent.js
-javax/swing/text/GapVector.js
-javax/swing/text/JTextComponent.js
-javax/swing/text/MutableAttributeSet.js
-javax/swing/text/PlainDocument.js
-javax/swing/text/PlainView.js
-javax/swing/text/Position.js
-javax/swing/text/Segment.js
-javax/swing/text/SegmentCache.js
-javax/swing/text/SimpleAttributeSet.js
-javax/swing/text/Style.js
-javax/swing/text/StyleConstants.js
-javax/swing/text/StyleContext.js
-javax/swing/text/TabExpander.js
-javax/swing/text/TextAction.js
-javax/swing/text/Utilities.js
-javax/swing/text/View.js
-javax/swing/tree/TreeNode.js
-javax/swing/UIDefaults.js
-javax/swing/UIManager.js
-javax/swing/undo/AbstractUndoableEdit.js
-javax/swing/undo/CompoundEdit.js
-javax/swing/undo/UndoableEdit.js
-javax/swing/ViewportLayout.js
-javax/swing/WindowConstants.js
-sun/awt/AppContext.js
-sun/awt/AWTAutoShutdown.js
-sun/awt/CausedFocusEvent.js
-sun/awt/ComponentFactory.js
-sun/awt/KeyboardFocusManagerPeerProvider.js
-sun/awt/MostRecentKeyValue.js
-sun/awt/MostRecentThreadAppContext.js
-sun/awt/PaintEventDispatcher.js
-sun/awt/PostEventQueue.js
-sun/awt/RequestFocusController.js
-sun/awt/SunToolkit.js
-sun/awt/WindowClosingListener.js
-sun/awt/WindowClosingSupport.js
-sun/awt/image/DataStealer.js
-sun/awt/image/IntegerComponentRaster.js
-sun/awt/image/IntegerInterleavedRaster.js
-sun/awt/image/SunWritableRaster.js
-sun/font/FontDesignMetrics.js
-sun/swing/DefaultLookup.js
-sun/swing/SwingLazyValue.js
-sun/text/resources/FormatData.js
-sun/text/resources/FormatData_en.js
-sun/util/resources/LocaleData.js
-swingjs/a2s/A2SContainer.js
-swingjs/a2s/A2SEvent.js
-swingjs/a2s/A2SListener.js
-swingjs/a2s/Applet.js
-swingjs/a2s/Button.js
-swingjs/a2s/Label.js
-swingjs/a2s/Panel.js
-swingjs/a2s/Scrollbar.js
-swingjs/a2s/ScrollPane.js
-swingjs/a2s/TextArea.js
-swingjs/a2s/TextField.js
-swingjs/api/Interface.js
-swingjs/api/js/DOMNode.js
-swingjs/api/js/HTML5CanvasContext2D.js
-swingjs/api/js/JSInterface.js
-swingjs/jquery/JQueryUI.js
-swingjs/JSApp.js
-swingjs/JSAppletThread.js
-swingjs/JSAppletViewer.js
-swingjs/JSFocusPeer.js
-swingjs/JSFontMetrics.js
-swingjs/JSFrameViewer.js
-swingjs/JSGraphics2D.js
-swingjs/JSGraphicsConfiguration.js
-swingjs/JSGraphicsEnvironment.js
-swingjs/JSImage.js
-swingjs/JSImagekit.js
-swingjs/JSMouse.js
-swingjs/JSNullComponentPeer.js
-swingjs/JSScreenDevice.js
-swingjs/JSThreadGroup.js
-swingjs/JSToolkit.js
-swingjs/JSUtil.js
-swingjs/plaf/ButtonListener.js
-swingjs/plaf/DefaultMenuLayout.js
-swingjs/plaf/HTML5LookAndFeel.js
-swingjs/plaf/JSAppletUI.js
-swingjs/plaf/JSButtonUI.js
-swingjs/plaf/JSCheckBoxMenuItemUI.js
-swingjs/plaf/JSCheckBoxUI.js
-swingjs/plaf/JSComboBoxUI.js
-swingjs/plaf/JSComponentUI.js
-swingjs/plaf/JSEventHandler.js
-swingjs/plaf/JSFrameUI.js
-swingjs/plaf/JSGraphicsUtils.js
-swingjs/plaf/JSLabelUI.js
-swingjs/plaf/JSLayeredPaneUI.js
-swingjs/plaf/JSLightweightUI.js
-swingjs/plaf/JSMenuBarUI.js
-swingjs/plaf/JSMenuItemUI.js
-swingjs/plaf/JSMenuUI.js
-swingjs/plaf/JSPanelUI.js
-swingjs/plaf/JSPopupMenuSeparatorUI.js
-swingjs/plaf/JSPopupMenuUI.js
-swingjs/plaf/JSRadioButtonMenuItemUI.js
-swingjs/plaf/JSRadioButtonUI.js
-swingjs/plaf/JSRootPaneUI.js
-swingjs/plaf/JSScrollBarUI.js
-swingjs/plaf/JSScrollPaneUI.js
-swingjs/plaf/JSSeparatorUI.js
-swingjs/plaf/JSSliderUI.js
-swingjs/plaf/JSTextAreaUI.js
-swingjs/plaf/JSTextFieldUI.js
-swingjs/plaf/JSTextUI.js
-swingjs/plaf/JSTextViewUI.js
-swingjs/plaf/JSViewportUI.js
-swingjs/plaf/JSWindowUI.js
-swingjs/plaf/LazyActionMap.js
-swingjs/plaf/Resizer.js
-swingjs/plaf/TextListener.js
-
-
+++ /dev/null
-20200105111457
+++ /dev/null
-This is sources/net.sf.j2s.java.core/dist/DEV_NOTES.txt
-
-_j2sclasslist.txt
-
-the list of .js files concatenated into coreswingjs.js and minified to coreswingjs.z.js
-
-
-SwingJS-site.zip
-
-the full site directory for SwingJS including all files not in the test/ directory.
+++ /dev/null
-Unexpected error. File contents could not be restored from local history during undo/redo.
\ No newline at end of file
+++ /dev/null
-java/applet/Applet.js
-java/applet/AppletContext.js
-java/applet/AppletStub.js
-java/applet/JSApplet.js
-java/awt/ActiveEvent.js
-java/awt/Adjustable.js
-java/awt/AWTEvent.js
-java/awt/AWTEventMulticaster.js
-java/awt/AWTKeyStroke.js
-java/awt/BasicStroke.js
-java/awt/BorderLayout.js
-java/awt/Button.js
-java/awt/Color.js
-java/awt/color/ColorSpace.js
-java/awt/Component.js
-java/awt/ComponentOrientation.js
-java/awt/ContainerOrderFocusTraversalPolicy.js
-java/awt/Container.js
-java/awt/Cursor.js
-java/awt/DefaultFocusTraversalPolicy.js
-java/awt/DefaultKeyboardFocusManager.js
-java/awt/Dialog.js
-java/awt/Dimension.js
-java/awt/dnd/peer/DropTargetPeer.js
-java/awt/event/ActionListener.js
-java/awt/event/AdjustmentEvent.js
-java/awt/event/AdjustmentListener.js
-java/awt/event/AWTEventListener.js
-java/awt/event/ComponentAdapter.js
-java/awt/event/ComponentEvent.js
-java/awt/event/ComponentListener.js
-java/awt/event/ContainerListener.js
-java/awt/event/FocusEvent.js
-java/awt/event/FocusListener.js
-java/awt/event/HierarchyBoundsListener.js
-java/awt/event/HierarchyListener.js
-java/awt/event/InputEvent.js
-java/awt/event/InputMethodListener.js
-java/awt/event/InvocationEvent.js
-java/awt/event/ItemEvent.js
-java/awt/event/ItemListener.js
-java/awt/event/KeyListener.js
-java/awt/event/MouseEvent.js
-java/awt/event/MouseListener.js
-java/awt/event/MouseMotionListener.js
-java/awt/event/MouseWheelListener.js
-java/awt/event/TextListener.js
-java/awt/event/WindowAdapter.js
-java/awt/event/WindowEvent.js
-java/awt/event/WindowFocusListener.js
-java/awt/event/WindowListener.js
-java/awt/event/WindowStateListener.js
-java/awt/EventDispatchThread.js
-java/awt/EventFilter.js
-java/awt/EventQueue.js
-java/awt/EventQueueItem.js
-java/awt/FlowLayout.js
-java/awt/FocusTraversalPolicy.js
-java/awt/Font.js
-java/awt/font/FontRenderContext.js
-java/awt/FontMetrics.js
-java/awt/Frame.js
-java/awt/geom/AffineTransform.js
-java/awt/geom/Dimension2D.js
-java/awt/geom/Path2D.js
-java/awt/geom/PathIterator.js
-java/awt/geom/Point2D.js
-java/awt/geom/Rectangle2D.js
-java/awt/geom/RectangularShape.js
-java/awt/geom/RectIterator.js
-java/awt/GraphicsCallback.js
-java/awt/GraphicsConfiguration.js
-java/awt/GraphicsDevice.js
-java/awt/GraphicsEnvironment.js
-java/awt/Image.js
-java/awt/image/ImageObserver.js
-java/awt/Insets.js
-java/awt/ItemSelectable.js
-java/awt/JSComponent.js
-java/awt/JSDialog.js
-java/awt/JSFrame.js
-java/awt/JSPanel.js
-java/awt/KeyboardFocusManager.js
-java/awt/KeyEventDispatcher.js
-java/awt/KeyEventPostProcessor.js
-java/awt/Label.js
-java/awt/LayoutManager.js
-java/awt/LayoutManager2.js
-java/awt/LightweightDispatcher.js
-java/awt/Paint.js
-java/awt/Panel.js
-java/awt/peer/ComponentPeer.js
-java/awt/peer/ContainerPeer.js
-java/awt/peer/FramePeer.js
-java/awt/peer/KeyboardFocusManagerPeer.js
-java/awt/peer/LightweightPeer.js
-java/awt/peer/WindowPeer.js
-java/awt/Point.js
-java/awt/Queue.js
-java/awt/Rectangle.js
-java/awt/RenderingHints.js
-java/awt/Scrollbar.js
-java/awt/ScrollPane.js
-java/awt/Shape.js
-java/awt/Stroke.js
-java/awt/TextArea.js
-java/awt/TextComponent.js
-java/awt/TextField.js
-java/awt/Toolkit.js
-java/awt/Transparency.js
-java/awt/Window.js
-java/beans/ChangeListenerMap.js
-java/beans/PropertyChangeEvent.js
-java/beans/PropertyChangeListener.js
-java/beans/PropertyChangeSupport.js
-java/lang/AbstractStringBuilder.js
-java/lang/Class.js
-java/lang/Enum.js
-java/lang/Iterable.js
-java/lang/reflect/Constructor.js
-java/lang/reflect/Method.js
-java/lang/StringBuffer.js
-java/lang/StringBuilder.js
-java/lang/Thread.js
-java/lang/ThreadGroup.js
-java/math/RoundingMode.js
-java/net/URL.js
-java/net/URLStreamHandlerFactory.js
-java/net/HttpURLConnection.js
-java/net/URLStreamHandler.js
-javax/net/ssl/HttpsUrlConnection.js
-java/text/CharacterIterator.js
-java/text/DecimalFormat.js
-java/text/DecimalFormatSymbols.js
-java/text/DigitList.js
-java/text/FieldPosition.js
-java/text/Format.js
-java/text/NumberFormat.js
-java/util/AbstractCollection.js
-java/util/AbstractList.js
-java/util/AbstractMap.js
-java/util/AbstractSequentialList.js
-java/util/AbstractSet.js
-java/util/ArrayList.js
-java/util/Arrays.js
-java/util/Collection.js
-java/util/Collections.js
-java/util/Comparator.js
-java/util/Deque.js
-java/util/Dictionary.js
-java/util/Enumeration.js
-java/util/EventListener.js
-java/util/EventObject.js
-java/util/HashMap.js
-java/util/HashSet.js
-java/util/Hashtable.js
-java/util/IdentityHashMap.js
-java/util/Iterator.js
-java/util/LinkedHashMap.js
-java/util/LinkedList.js
-java/util/List.js
-java/util/ListResourceBundle.js
-java/util/Locale.js
-java/util/Map.js
-java/util/Objects.js
-java/util/Queue.js
-java/util/Random.js
-java/util/RandomAccess.js
-java/util/ResourceBundle.js
-java/util/Set.js
-java/util/TimSort.js
-java/util/Vector.js
-javajs/api/JSFunction.js
-javajs/util/AjaxURLConnection.js
-javajs/util/AjaxURLStreamHandlerFactory.js
-javajs/util/AU.js
-javajs/util/JSThread.js
-javajs/util/Lst.js
-javajs/util/PT.js
-javajs/util/Rdr.js
-javajs/util/SB.js
-javax/swing/AbstractAction.js
-javax/swing/AbstractButton.js
-javax/swing/AbstractListModel.js
-javax/swing/Action.js
-javax/swing/ActionMap.js
-javax/swing/AncestorNotifier.js
-javax/swing/ArrayTable.js
-javax/swing/border/AbstractBorder.js
-javax/swing/border/BevelBorder.js
-javax/swing/border/Border.js
-javax/swing/border/CompoundBorder.js
-javax/swing/border/EmptyBorder.js
-javax/swing/border/EtchedBorder.js
-javax/swing/border/LineBorder.js
-javax/swing/border/TitledBorder.js
-javax/swing/BorderFactory.js
-javax/swing/BoundedRangeModel.js
-javax/swing/BoxLayout.js
-javax/swing/ButtonGroup.js
-javax/swing/ButtonModel.js
-javax/swing/ClientPropertyKey.js
-javax/swing/ComboBoxModel.js
-javax/swing/DefaultBoundedRangeModel.js
-javax/swing/DefaultButtonModel.js
-javax/swing/DefaultComboBoxModel.js
-javax/swing/DefaultSingleSelectionModel.js
-javax/swing/DropMode.js
-javax/swing/event/AncestorEvent.js
-javax/swing/event/AncestorListener.js
-javax/swing/event/CaretEvent.js
-javax/swing/event/CaretListener.js
-javax/swing/event/ChangeEvent.js
-javax/swing/event/ChangeListener.js
-javax/swing/event/DocumentEvent.js
-javax/swing/event/DocumentListener.js
-javax/swing/event/EventListenerList.js
-javax/swing/event/ListDataEvent.js
-javax/swing/event/ListDataListener.js
-javax/swing/event/UndoableEditEvent.js
-javax/swing/event/UndoableEditListener.js
-javax/swing/FocusManager.js
-javax/swing/InternalFrameFocusTraversalPolicy.js
-javax/swing/LayoutComparator.js
-javax/swing/LayoutFocusTraversalPolicy.js
-javax/swing/SortingFocusTraversalPolicy.js
-javax/swing/SwingContainerOrderFocusTraversalPolicy.js
-javax/swing/SwingDefaultFocusTraversalPolicy.js
-javax/swing/Icon.js
-javax/swing/ImageIcon.js
-javax/swing/InputMap.js
-javax/swing/JApplet.js
-javax/swing/JButton.js
-javax/swing/JCheckBox.js
-javax/swing/JCheckBoxMenuItem.js
-javax/swing/JComboBox.js
-javax/swing/JComponent.js
-javax/swing/JFrame.js
-javax/swing/JLabel.js
-javax/swing/JLayeredPane.js
-javax/swing/JMenu.js
-javax/swing/JMenuBar.js
-javax/swing/JMenuItem.js
-javax/swing/JPanel.js
-javax/swing/JPopupMenu.js
-javax/swing/JRadioButtonMenuItem.js
-javax/swing/JRootPane.js
-javax/swing/JScrollBar.js
-javax/swing/JScrollPane.js
-javax/swing/JSeparator.js
-javax/swing/JTextArea.js
-javax/swing/JTextField.js
-javax/swing/JToggleButton.js
-javax/swing/JViewport.js
-javax/swing/KeyboardManager.js
-javax/swing/KeyStroke.js
-javax/swing/ListModel.js
-javax/swing/LookAndFeel.js
-javax/swing/MenuElement.js
-javax/swing/MutableComboBoxModel.js
-javax/swing/plaf/ActionMapUIResource.js
-javax/swing/plaf/basic/BasicBorders.js
-javax/swing/plaf/BorderUIResource.js
-javax/swing/plaf/ColorUIResource.js
-javax/swing/plaf/ComponentUI.js
-javax/swing/plaf/DimensionUIResource.js
-javax/swing/plaf/FontUIResource.js
-javax/swing/plaf/InputMapUIResource.js
-javax/swing/plaf/InsetsUIResource.js
-javax/swing/plaf/UIResource.js
-javax/swing/RepaintManager.js
-javax/swing/RootPaneContainer.js
-javax/swing/Scrollable.js
-javax/swing/ScrollPaneConstants.js
-javax/swing/ScrollPaneLayout.js
-javax/swing/SingleSelectionModel.js
-javax/swing/SizeRequirements.js
-javax/swing/SwingConstants.js
-javax/swing/SwingPaintEventDispatcher.js
-javax/swing/SwingUtilities.js
-javax/swing/text/AbstractDocument.js
-javax/swing/text/AttributeSet.js
-javax/swing/text/Caret.js
-javax/swing/text/DefaultCaret.js
-javax/swing/text/DefaultEditorKit.js
-javax/swing/text/Document.js
-javax/swing/text/EditorKit.js
-javax/swing/text/Element.js
-javax/swing/text/GapContent.js
-javax/swing/text/GapVector.js
-javax/swing/text/JTextComponent.js
-javax/swing/text/MutableAttributeSet.js
-javax/swing/text/PlainDocument.js
-javax/swing/text/PlainView.js
-javax/swing/text/Position.js
-javax/swing/text/Segment.js
-javax/swing/text/SegmentCache.js
-javax/swing/text/SimpleAttributeSet.js
-javax/swing/text/Style.js
-javax/swing/text/StyleConstants.js
-javax/swing/text/StyleContext.js
-javax/swing/text/TabExpander.js
-javax/swing/text/TextAction.js
-javax/swing/text/Utilities.js
-javax/swing/text/View.js
-javax/swing/tree/TreeNode.js
-javax/swing/UIDefaults.js
-javax/swing/UIManager.js
-javax/swing/undo/AbstractUndoableEdit.js
-javax/swing/undo/CompoundEdit.js
-javax/swing/undo/UndoableEdit.js
-javax/swing/ViewportLayout.js
-javax/swing/WindowConstants.js
-sun/awt/AppContext.js
-sun/awt/AWTAutoShutdown.js
-sun/awt/CausedFocusEvent.js
-sun/awt/ComponentFactory.js
-sun/awt/KeyboardFocusManagerPeerProvider.js
-sun/awt/MostRecentKeyValue.js
-sun/awt/MostRecentThreadAppContext.js
-sun/awt/PaintEventDispatcher.js
-sun/awt/PostEventQueue.js
-sun/awt/RequestFocusController.js
-sun/awt/SunToolkit.js
-sun/awt/WindowClosingListener.js
-sun/awt/WindowClosingSupport.js
-sun/awt/image/DataStealer.js
-sun/awt/image/IntegerComponentRaster.js
-sun/awt/image/IntegerInterleavedRaster.js
-sun/awt/image/SunWritableRaster.js
-sun/font/FontDesignMetrics.js
-sun/swing/DefaultLookup.js
-sun/swing/SwingLazyValue.js
-sun/text/resources/FormatData.js
-sun/text/resources/FormatData_en.js
-sun/util/resources/LocaleData.js
-swingjs/a2s/A2SContainer.js
-swingjs/a2s/A2SEvent.js
-swingjs/a2s/A2SListener.js
-swingjs/a2s/Applet.js
-swingjs/a2s/Button.js
-swingjs/a2s/Label.js
-swingjs/a2s/Panel.js
-swingjs/a2s/Scrollbar.js
-swingjs/a2s/ScrollPane.js
-swingjs/a2s/TextArea.js
-swingjs/a2s/TextField.js
-swingjs/api/Interface.js
-swingjs/api/js/DOMNode.js
-swingjs/api/js/HTML5CanvasContext2D.js
-swingjs/api/js/JSInterface.js
-swingjs/jquery/JQueryUI.js
-swingjs/JSApp.js
-swingjs/JSAppletThread.js
-swingjs/JSAppletViewer.js
-swingjs/JSFocusPeer.js
-swingjs/JSFontMetrics.js
-swingjs/JSFrameViewer.js
-swingjs/JSGraphics2D.js
-swingjs/JSGraphicsConfiguration.js
-swingjs/JSGraphicsEnvironment.js
-swingjs/JSImage.js
-swingjs/JSImagekit.js
-swingjs/JSMouse.js
-swingjs/JSNullComponentPeer.js
-swingjs/JSScreenDevice.js
-swingjs/JSThreadGroup.js
-swingjs/JSToolkit.js
-swingjs/JSUtil.js
-swingjs/plaf/ButtonListener.js
-swingjs/plaf/DefaultMenuLayout.js
-swingjs/plaf/HTML5LookAndFeel.js
-swingjs/plaf/JSAppletUI.js
-swingjs/plaf/JSButtonUI.js
-swingjs/plaf/JSCheckBoxMenuItemUI.js
-swingjs/plaf/JSCheckBoxUI.js
-swingjs/plaf/JSComboBoxUI.js
-swingjs/plaf/JSComponentUI.js
-swingjs/plaf/JSEventHandler.js
-swingjs/plaf/JSFrameUI.js
-swingjs/plaf/JSGraphicsUtils.js
-swingjs/plaf/JSLabelUI.js
-swingjs/plaf/JSLayeredPaneUI.js
-swingjs/plaf/JSLightweightUI.js
-swingjs/plaf/JSMenuBarUI.js
-swingjs/plaf/JSMenuItemUI.js
-swingjs/plaf/JSMenuUI.js
-swingjs/plaf/JSPanelUI.js
-swingjs/plaf/JSPopupMenuSeparatorUI.js
-swingjs/plaf/JSPopupMenuUI.js
-swingjs/plaf/JSRadioButtonMenuItemUI.js
-swingjs/plaf/JSRadioButtonUI.js
-swingjs/plaf/JSRootPaneUI.js
-swingjs/plaf/JSScrollBarUI.js
-swingjs/plaf/JSScrollPaneUI.js
-swingjs/plaf/JSSeparatorUI.js
-swingjs/plaf/JSSliderUI.js
-swingjs/plaf/JSTextAreaUI.js
-swingjs/plaf/JSTextFieldUI.js
-swingjs/plaf/JSTextUI.js
-swingjs/plaf/JSTextViewUI.js
-swingjs/plaf/JSViewportUI.js
-swingjs/plaf/JSWindowUI.js
-swingjs/plaf/LazyActionMap.js
-swingjs/plaf/Resizer.js
-swingjs/plaf/TextListener.js
-
-
+++ /dev/null
-20200205074936
+++ /dev/null
-This is sources/net.sf.j2s.java.core/dist/DEV_NOTES.txt
-
-_j2sclasslist.txt
-
-the list of .js files concatenated into coreswingjs.js and minified to coreswingjs.z.js
-
-
-SwingJS-site.zip
-
-the full site directory for SwingJS including all files not in the test/ directory.
+++ /dev/null
-Unexpected error. File contents could not be restored from local history during undo/redo.
\ No newline at end of file
+++ /dev/null
-java/applet/Applet.js
-java/applet/AppletContext.js
-java/applet/AppletStub.js
-java/applet/JSApplet.js
-java/awt/ActiveEvent.js
-java/awt/Adjustable.js
-java/awt/AWTEvent.js
-java/awt/AWTEventMulticaster.js
-java/awt/AWTKeyStroke.js
-java/awt/BasicStroke.js
-java/awt/BorderLayout.js
-java/awt/Button.js
-java/awt/Color.js
-java/awt/color/ColorSpace.js
-java/awt/Component.js
-java/awt/ComponentOrientation.js
-java/awt/ContainerOrderFocusTraversalPolicy.js
-java/awt/Container.js
-java/awt/Cursor.js
-java/awt/DefaultFocusTraversalPolicy.js
-java/awt/DefaultKeyboardFocusManager.js
-java/awt/Dialog.js
-java/awt/Dimension.js
-java/awt/dnd/peer/DropTargetPeer.js
-java/awt/event/ActionListener.js
-java/awt/event/AdjustmentEvent.js
-java/awt/event/AdjustmentListener.js
-java/awt/event/AWTEventListener.js
-java/awt/event/ComponentAdapter.js
-java/awt/event/ComponentEvent.js
-java/awt/event/ComponentListener.js
-java/awt/event/ContainerListener.js
-java/awt/event/FocusEvent.js
-java/awt/event/FocusListener.js
-java/awt/event/HierarchyBoundsListener.js
-java/awt/event/HierarchyListener.js
-java/awt/event/InputEvent.js
-java/awt/event/InputMethodListener.js
-java/awt/event/InvocationEvent.js
-java/awt/event/ItemEvent.js
-java/awt/event/ItemListener.js
-java/awt/event/KeyListener.js
-java/awt/event/MouseEvent.js
-java/awt/event/MouseListener.js
-java/awt/event/MouseMotionListener.js
-java/awt/event/MouseWheelListener.js
-java/awt/event/TextListener.js
-java/awt/event/WindowAdapter.js
-java/awt/event/WindowEvent.js
-java/awt/event/WindowFocusListener.js
-java/awt/event/WindowListener.js
-java/awt/event/WindowStateListener.js
-java/awt/EventDispatchThread.js
-java/awt/EventFilter.js
-java/awt/EventQueue.js
-java/awt/EventQueueItem.js
-java/awt/FlowLayout.js
-java/awt/FocusTraversalPolicy.js
-java/awt/Font.js
-java/awt/font/FontRenderContext.js
-java/awt/FontMetrics.js
-java/awt/Frame.js
-java/awt/geom/AffineTransform.js
-java/awt/geom/Dimension2D.js
-java/awt/geom/Path2D.js
-java/awt/geom/PathIterator.js
-java/awt/geom/Point2D.js
-java/awt/geom/Rectangle2D.js
-java/awt/geom/RectangularShape.js
-java/awt/geom/RectIterator.js
-java/awt/GraphicsCallback.js
-java/awt/GraphicsConfiguration.js
-java/awt/GraphicsDevice.js
-java/awt/GraphicsEnvironment.js
-java/awt/Image.js
-java/awt/image/ImageObserver.js
-java/awt/Insets.js
-java/awt/ItemSelectable.js
-java/awt/JSComponent.js
-java/awt/JSDialog.js
-java/awt/JSFrame.js
-java/awt/JSPanel.js
-java/awt/KeyboardFocusManager.js
-java/awt/KeyEventDispatcher.js
-java/awt/KeyEventPostProcessor.js
-java/awt/Label.js
-java/awt/LayoutManager.js
-java/awt/LayoutManager2.js
-java/awt/LightweightDispatcher.js
-java/awt/Paint.js
-java/awt/Panel.js
-java/awt/peer/ComponentPeer.js
-java/awt/peer/ContainerPeer.js
-java/awt/peer/FramePeer.js
-java/awt/peer/KeyboardFocusManagerPeer.js
-java/awt/peer/LightweightPeer.js
-java/awt/peer/WindowPeer.js
-java/awt/Point.js
-java/awt/Queue.js
-java/awt/Rectangle.js
-java/awt/RenderingHints.js
-java/awt/Scrollbar.js
-java/awt/ScrollPane.js
-java/awt/Shape.js
-java/awt/Stroke.js
-java/awt/TextArea.js
-java/awt/TextComponent.js
-java/awt/TextField.js
-java/awt/Toolkit.js
-java/awt/Transparency.js
-java/awt/Window.js
-java/beans/ChangeListenerMap.js
-java/beans/PropertyChangeEvent.js
-java/beans/PropertyChangeListener.js
-java/beans/PropertyChangeSupport.js
-java/lang/AbstractStringBuilder.js
-java/lang/Class.js
-java/lang/Enum.js
-java/lang/Iterable.js
-java/lang/reflect/Constructor.js
-java/lang/reflect/Method.js
-java/lang/StringBuffer.js
-java/lang/StringBuilder.js
-java/lang/Thread.js
-java/lang/ThreadGroup.js
-java/math/RoundingMode.js
-java/net/URL.js
-java/net/URLStreamHandlerFactory.js
-java/net/HttpURLConnection.js
-java/net/URLStreamHandler.js
-javax/net/ssl/HttpsUrlConnection.js
-java/text/CharacterIterator.js
-java/text/DecimalFormat.js
-java/text/DecimalFormatSymbols.js
-java/text/DigitList.js
-java/text/FieldPosition.js
-java/text/Format.js
-java/text/NumberFormat.js
-java/util/AbstractCollection.js
-java/util/AbstractList.js
-java/util/AbstractMap.js
-java/util/AbstractSequentialList.js
-java/util/AbstractSet.js
-java/util/ArrayList.js
-java/util/Arrays.js
-java/util/Collection.js
-java/util/Collections.js
-java/util/Comparator.js
-java/util/Deque.js
-java/util/Dictionary.js
-java/util/Enumeration.js
-java/util/EventListener.js
-java/util/EventObject.js
-java/util/HashMap.js
-java/util/HashSet.js
-java/util/Hashtable.js
-java/util/IdentityHashMap.js
-java/util/Iterator.js
-java/util/LinkedHashMap.js
-java/util/LinkedList.js
-java/util/List.js
-java/util/ListResourceBundle.js
-java/util/Locale.js
-java/util/Map.js
-java/util/Objects.js
-java/util/Queue.js
-java/util/Random.js
-java/util/RandomAccess.js
-java/util/ResourceBundle.js
-java/util/Set.js
-java/util/TimSort.js
-java/util/Vector.js
-javajs/api/JSFunction.js
-javajs/util/AjaxURLConnection.js
-javajs/util/AjaxURLStreamHandlerFactory.js
-javajs/util/AU.js
-javajs/util/JSThread.js
-javajs/util/Lst.js
-javajs/util/PT.js
-javajs/util/Rdr.js
-javajs/util/SB.js
-javax/swing/AbstractAction.js
-javax/swing/AbstractButton.js
-javax/swing/AbstractListModel.js
-javax/swing/Action.js
-javax/swing/ActionMap.js
-javax/swing/AncestorNotifier.js
-javax/swing/ArrayTable.js
-javax/swing/border/AbstractBorder.js
-javax/swing/border/BevelBorder.js
-javax/swing/border/Border.js
-javax/swing/border/CompoundBorder.js
-javax/swing/border/EmptyBorder.js
-javax/swing/border/EtchedBorder.js
-javax/swing/border/LineBorder.js
-javax/swing/border/TitledBorder.js
-javax/swing/BorderFactory.js
-javax/swing/BoundedRangeModel.js
-javax/swing/BoxLayout.js
-javax/swing/ButtonGroup.js
-javax/swing/ButtonModel.js
-javax/swing/ClientPropertyKey.js
-javax/swing/ComboBoxModel.js
-javax/swing/DefaultBoundedRangeModel.js
-javax/swing/DefaultButtonModel.js
-javax/swing/DefaultComboBoxModel.js
-javax/swing/DefaultSingleSelectionModel.js
-javax/swing/DropMode.js
-javax/swing/event/AncestorEvent.js
-javax/swing/event/AncestorListener.js
-javax/swing/event/CaretEvent.js
-javax/swing/event/CaretListener.js
-javax/swing/event/ChangeEvent.js
-javax/swing/event/ChangeListener.js
-javax/swing/event/DocumentEvent.js
-javax/swing/event/DocumentListener.js
-javax/swing/event/EventListenerList.js
-javax/swing/event/ListDataEvent.js
-javax/swing/event/ListDataListener.js
-javax/swing/event/UndoableEditEvent.js
-javax/swing/event/UndoableEditListener.js
-javax/swing/FocusManager.js
-javax/swing/InternalFrameFocusTraversalPolicy.js
-javax/swing/LayoutComparator.js
-javax/swing/LayoutFocusTraversalPolicy.js
-javax/swing/SortingFocusTraversalPolicy.js
-javax/swing/SwingContainerOrderFocusTraversalPolicy.js
-javax/swing/SwingDefaultFocusTraversalPolicy.js
-javax/swing/Icon.js
-javax/swing/ImageIcon.js
-javax/swing/InputMap.js
-javax/swing/JApplet.js
-javax/swing/JButton.js
-javax/swing/JCheckBox.js
-javax/swing/JCheckBoxMenuItem.js
-javax/swing/JComboBox.js
-javax/swing/JComponent.js
-javax/swing/JFrame.js
-javax/swing/JLabel.js
-javax/swing/JLayeredPane.js
-javax/swing/JMenu.js
-javax/swing/JMenuBar.js
-javax/swing/JMenuItem.js
-javax/swing/JPanel.js
-javax/swing/JPopupMenu.js
-javax/swing/JRadioButtonMenuItem.js
-javax/swing/JRootPane.js
-javax/swing/JScrollBar.js
-javax/swing/JScrollPane.js
-javax/swing/JSeparator.js
-javax/swing/JTextArea.js
-javax/swing/JTextField.js
-javax/swing/JToggleButton.js
-javax/swing/JViewport.js
-javax/swing/KeyboardManager.js
-javax/swing/KeyStroke.js
-javax/swing/ListModel.js
-javax/swing/LookAndFeel.js
-javax/swing/MenuElement.js
-javax/swing/MutableComboBoxModel.js
-javax/swing/plaf/ActionMapUIResource.js
-javax/swing/plaf/basic/BasicBorders.js
-javax/swing/plaf/BorderUIResource.js
-javax/swing/plaf/ColorUIResource.js
-javax/swing/plaf/ComponentUI.js
-javax/swing/plaf/DimensionUIResource.js
-javax/swing/plaf/FontUIResource.js
-javax/swing/plaf/InputMapUIResource.js
-javax/swing/plaf/InsetsUIResource.js
-javax/swing/plaf/UIResource.js
-javax/swing/RepaintManager.js
-javax/swing/RootPaneContainer.js
-javax/swing/Scrollable.js
-javax/swing/ScrollPaneConstants.js
-javax/swing/ScrollPaneLayout.js
-javax/swing/SingleSelectionModel.js
-javax/swing/SizeRequirements.js
-javax/swing/SwingConstants.js
-javax/swing/SwingPaintEventDispatcher.js
-javax/swing/SwingUtilities.js
-javax/swing/text/AbstractDocument.js
-javax/swing/text/AttributeSet.js
-javax/swing/text/Caret.js
-javax/swing/text/DefaultCaret.js
-javax/swing/text/DefaultEditorKit.js
-javax/swing/text/Document.js
-javax/swing/text/EditorKit.js
-javax/swing/text/Element.js
-javax/swing/text/GapContent.js
-javax/swing/text/GapVector.js
-javax/swing/text/JTextComponent.js
-javax/swing/text/MutableAttributeSet.js
-javax/swing/text/PlainDocument.js
-javax/swing/text/PlainView.js
-javax/swing/text/Position.js
-javax/swing/text/Segment.js
-javax/swing/text/SegmentCache.js
-javax/swing/text/SimpleAttributeSet.js
-javax/swing/text/Style.js
-javax/swing/text/StyleConstants.js
-javax/swing/text/StyleContext.js
-javax/swing/text/TabExpander.js
-javax/swing/text/TextAction.js
-javax/swing/text/Utilities.js
-javax/swing/text/View.js
-javax/swing/tree/TreeNode.js
-javax/swing/UIDefaults.js
-javax/swing/UIManager.js
-javax/swing/undo/AbstractUndoableEdit.js
-javax/swing/undo/CompoundEdit.js
-javax/swing/undo/UndoableEdit.js
-javax/swing/ViewportLayout.js
-javax/swing/WindowConstants.js
-sun/awt/AppContext.js
-sun/awt/AWTAutoShutdown.js
-sun/awt/CausedFocusEvent.js
-sun/awt/ComponentFactory.js
-sun/awt/KeyboardFocusManagerPeerProvider.js
-sun/awt/MostRecentKeyValue.js
-sun/awt/MostRecentThreadAppContext.js
-sun/awt/PaintEventDispatcher.js
-sun/awt/PostEventQueue.js
-sun/awt/RequestFocusController.js
-sun/awt/SunToolkit.js
-sun/awt/WindowClosingListener.js
-sun/awt/WindowClosingSupport.js
-sun/awt/image/DataStealer.js
-sun/awt/image/IntegerComponentRaster.js
-sun/awt/image/IntegerInterleavedRaster.js
-sun/awt/image/SunWritableRaster.js
-sun/font/FontDesignMetrics.js
-sun/swing/DefaultLookup.js
-sun/swing/SwingLazyValue.js
-sun/text/resources/FormatData.js
-sun/text/resources/en/FormatData_en.js
-sun/util/resources/LocaleData.js
-sun/util/locale/BaseLocale.js
-sun/util/locale/LocaleUtils.js
-sun/util/locale/provider/LocaleProviderAdapter.js
-sun/util/locale/provider/LocaleDataMetaInfo.js
-swingjs/a2s/A2SContainer.js
-swingjs/a2s/A2SEvent.js
-swingjs/a2s/A2SListener.js
-swingjs/a2s/Applet.js
-swingjs/a2s/Button.js
-swingjs/a2s/Label.js
-swingjs/a2s/Panel.js
-swingjs/a2s/Scrollbar.js
-swingjs/a2s/ScrollPane.js
-swingjs/a2s/TextArea.js
-swingjs/a2s/TextField.js
-swingjs/api/Interface.js
-swingjs/api/js/DOMNode.js
-swingjs/api/js/HTML5CanvasContext2D.js
-swingjs/api/js/JSInterface.js
-swingjs/jquery/JQueryUI.js
-swingjs/JSApp.js
-swingjs/JSAppletThread.js
-swingjs/JSAppletViewer.js
-swingjs/JSFocusPeer.js
-swingjs/JSFontMetrics.js
-swingjs/JSFrameViewer.js
-swingjs/JSGraphics2D.js
-swingjs/JSGraphicsConfiguration.js
-swingjs/JSGraphicsEnvironment.js
-swingjs/JSImage.js
-swingjs/JSImagekit.js
-swingjs/JSMouse.js
-swingjs/JSNullComponentPeer.js
-swingjs/JSScreenDevice.js
-swingjs/JSThreadGroup.js
-swingjs/JSToolkit.js
-swingjs/JSUtil.js
-swingjs/plaf/ButtonListener.js
-swingjs/plaf/DefaultMenuLayout.js
-swingjs/plaf/HTML5LookAndFeel.js
-swingjs/plaf/JSAppletUI.js
-swingjs/plaf/JSButtonUI.js
-swingjs/plaf/JSCheckBoxMenuItemUI.js
-swingjs/plaf/JSCheckBoxUI.js
-swingjs/plaf/JSComboBoxUI.js
-swingjs/plaf/JSComponentUI.js
-swingjs/plaf/JSEventHandler.js
-swingjs/plaf/JSFrameUI.js
-swingjs/plaf/JSGraphicsUtils.js
-swingjs/plaf/JSLabelUI.js
-swingjs/plaf/JSLayeredPaneUI.js
-swingjs/plaf/JSLightweightUI.js
-swingjs/plaf/JSMenuBarUI.js
-swingjs/plaf/JSMenuItemUI.js
-swingjs/plaf/JSMenuUI.js
-swingjs/plaf/JSPanelUI.js
-swingjs/plaf/JSPopupMenuSeparatorUI.js
-swingjs/plaf/JSPopupMenuUI.js
-swingjs/plaf/JSRadioButtonMenuItemUI.js
-swingjs/plaf/JSRadioButtonUI.js
-swingjs/plaf/JSRootPaneUI.js
-swingjs/plaf/JSScrollBarUI.js
-swingjs/plaf/JSScrollPaneUI.js
-swingjs/plaf/JSSeparatorUI.js
-swingjs/plaf/JSSliderUI.js
-swingjs/plaf/JSTextAreaUI.js
-swingjs/plaf/JSTextFieldUI.js
-swingjs/plaf/JSTextUI.js
-swingjs/plaf/JSTextViewUI.js
-swingjs/plaf/JSViewportUI.js
-swingjs/plaf/JSWindowUI.js
-swingjs/plaf/LazyActionMap.js
-swingjs/plaf/Resizer.js
-swingjs/plaf/TextListener.js
-
-
+++ /dev/null
-20200220124544
+++ /dev/null
-This is sources/net.sf.j2s.java.core/dist/DEV_NOTES.txt
-
-_j2sclasslist.txt
-
-the list of .js files concatenated into coreswingjs.js and minified to coreswingjs.z.js
-
-
-SwingJS-site.zip
-
-the full site directory for SwingJS including all files not in the test/ directory.
+++ /dev/null
-Unexpected error. File contents could not be restored from local history during undo/redo.
\ No newline at end of file
+++ /dev/null
-java/applet/Applet.js
-java/applet/AppletContext.js
-java/applet/AppletStub.js
-java/applet/JSApplet.js
-java/awt/ActiveEvent.js
-java/awt/Adjustable.js
-java/awt/AWTEvent.js
-java/awt/AWTEventMulticaster.js
-java/awt/AWTKeyStroke.js
-java/awt/BasicStroke.js
-java/awt/BorderLayout.js
-java/awt/Button.js
-java/awt/Color.js
-java/awt/color/ColorSpace.js
-java/awt/Component.js
-java/awt/ComponentOrientation.js
-java/awt/ContainerOrderFocusTraversalPolicy.js
-java/awt/Container.js
-java/awt/Cursor.js
-java/awt/DefaultFocusTraversalPolicy.js
-java/awt/DefaultKeyboardFocusManager.js
-java/awt/Dialog.js
-java/awt/Dimension.js
-java/awt/dnd/peer/DropTargetPeer.js
-java/awt/event/ActionListener.js
-java/awt/event/AdjustmentEvent.js
-java/awt/event/AdjustmentListener.js
-java/awt/event/AWTEventListener.js
-java/awt/event/ComponentAdapter.js
-java/awt/event/ComponentEvent.js
-java/awt/event/ComponentListener.js
-java/awt/event/ContainerListener.js
-java/awt/event/FocusEvent.js
-java/awt/event/FocusListener.js
-java/awt/event/HierarchyBoundsListener.js
-java/awt/event/HierarchyListener.js
-java/awt/event/InputEvent.js
-java/awt/event/InputMethodListener.js
-java/awt/event/InvocationEvent.js
-java/awt/event/ItemEvent.js
-java/awt/event/ItemListener.js
-java/awt/event/KeyListener.js
-java/awt/event/MouseEvent.js
-java/awt/event/MouseListener.js
-java/awt/event/MouseMotionListener.js
-java/awt/event/MouseWheelListener.js
-java/awt/event/TextListener.js
-java/awt/event/WindowAdapter.js
-java/awt/event/WindowEvent.js
-java/awt/event/WindowFocusListener.js
-java/awt/event/WindowListener.js
-java/awt/event/WindowStateListener.js
-java/awt/EventDispatchThread.js
-java/awt/EventFilter.js
-java/awt/EventQueue.js
-java/awt/EventQueueItem.js
-java/awt/FlowLayout.js
-java/awt/FocusTraversalPolicy.js
-java/awt/Font.js
-java/awt/font/FontRenderContext.js
-java/awt/FontMetrics.js
-java/awt/Frame.js
-java/awt/geom/AffineTransform.js
-java/awt/geom/Dimension2D.js
-java/awt/geom/Path2D.js
-java/awt/geom/PathIterator.js
-java/awt/geom/Point2D.js
-java/awt/geom/Rectangle2D.js
-java/awt/geom/RectangularShape.js
-java/awt/geom/RectIterator.js
-java/awt/GraphicsCallback.js
-java/awt/GraphicsConfiguration.js
-java/awt/GraphicsDevice.js
-java/awt/GraphicsEnvironment.js
-java/awt/Image.js
-java/awt/image/ImageObserver.js
-java/awt/Insets.js
-java/awt/ItemSelectable.js
-java/awt/JSComponent.js
-java/awt/JSDialog.js
-java/awt/JSFrame.js
-java/awt/JSPanel.js
-java/awt/KeyboardFocusManager.js
-java/awt/KeyEventDispatcher.js
-java/awt/KeyEventPostProcessor.js
-java/awt/Label.js
-java/awt/LayoutManager.js
-java/awt/LayoutManager2.js
-java/awt/LightweightDispatcher.js
-java/awt/Paint.js
-java/awt/Panel.js
-java/awt/peer/ComponentPeer.js
-java/awt/peer/ContainerPeer.js
-java/awt/peer/FramePeer.js
-java/awt/peer/KeyboardFocusManagerPeer.js
-java/awt/peer/LightweightPeer.js
-java/awt/peer/WindowPeer.js
-java/awt/Point.js
-java/awt/Queue.js
-java/awt/Rectangle.js
-java/awt/RenderingHints.js
-java/awt/Scrollbar.js
-java/awt/ScrollPane.js
-java/awt/Shape.js
-java/awt/Stroke.js
-java/awt/TextArea.js
-java/awt/TextComponent.js
-java/awt/TextField.js
-java/awt/Toolkit.js
-java/awt/Transparency.js
-java/awt/Window.js
-java/beans/ChangeListenerMap.js
-java/beans/PropertyChangeEvent.js
-java/beans/PropertyChangeListener.js
-java/beans/PropertyChangeSupport.js
-java/lang/AbstractStringBuilder.js
-java/lang/Class.js
-java/lang/Enum.js
-java/lang/Iterable.js
-java/lang/reflect/Constructor.js
-java/lang/reflect/Method.js
-java/lang/StringBuffer.js
-java/lang/StringBuilder.js
-java/lang/Thread.js
-java/lang/ThreadGroup.js
-java/math/RoundingMode.js
-java/net/URL.js
-java/net/URLStreamHandlerFactory.js
-java/net/HttpURLConnection.js
-java/net/URLStreamHandler.js
-javax/net/ssl/HttpsUrlConnection.js
-java/text/CharacterIterator.js
-java/text/DecimalFormat.js
-java/text/DecimalFormatSymbols.js
-java/text/DigitList.js
-java/text/FieldPosition.js
-java/text/Format.js
-java/text/NumberFormat.js
-java/util/AbstractCollection.js
-java/util/AbstractList.js
-java/util/AbstractMap.js
-java/util/AbstractSequentialList.js
-java/util/AbstractSet.js
-java/util/ArrayList.js
-java/util/Arrays.js
-java/util/Collection.js
-java/util/Collections.js
-java/util/Comparator.js
-java/util/Deque.js
-java/util/Dictionary.js
-java/util/Enumeration.js
-java/util/EventListener.js
-java/util/EventObject.js
-java/util/HashMap.js
-java/util/HashSet.js
-java/util/Hashtable.js
-java/util/IdentityHashMap.js
-java/util/Iterator.js
-java/util/LinkedHashMap.js
-java/util/LinkedList.js
-java/util/List.js
-java/util/ListResourceBundle.js
-java/util/Locale.js
-java/util/Map.js
-java/util/Objects.js
-java/util/Queue.js
-java/util/Random.js
-java/util/RandomAccess.js
-java/util/ResourceBundle.js
-java/util/Set.js
-java/util/TimSort.js
-java/util/Vector.js
-javajs/api/JSFunction.js
-javajs/util/AjaxURLConnection.js
-javajs/util/AjaxURLStreamHandlerFactory.js
-javajs/util/AU.js
-javajs/util/JSThread.js
-javajs/util/Lst.js
-javajs/util/PT.js
-javajs/util/Rdr.js
-javajs/util/SB.js
-javax/swing/AbstractAction.js
-javax/swing/AbstractButton.js
-javax/swing/AbstractListModel.js
-javax/swing/Action.js
-javax/swing/ActionMap.js
-javax/swing/AncestorNotifier.js
-javax/swing/ArrayTable.js
-javax/swing/border/AbstractBorder.js
-javax/swing/border/BevelBorder.js
-javax/swing/border/Border.js
-javax/swing/border/CompoundBorder.js
-javax/swing/border/EmptyBorder.js
-javax/swing/border/EtchedBorder.js
-javax/swing/border/LineBorder.js
-javax/swing/border/TitledBorder.js
-javax/swing/BorderFactory.js
-javax/swing/BoundedRangeModel.js
-javax/swing/BoxLayout.js
-javax/swing/ButtonGroup.js
-javax/swing/ButtonModel.js
-javax/swing/ClientPropertyKey.js
-javax/swing/ComboBoxModel.js
-javax/swing/DefaultBoundedRangeModel.js
-javax/swing/DefaultButtonModel.js
-javax/swing/DefaultComboBoxModel.js
-javax/swing/DefaultSingleSelectionModel.js
-javax/swing/DropMode.js
-javax/swing/event/AncestorEvent.js
-javax/swing/event/AncestorListener.js
-javax/swing/event/CaretEvent.js
-javax/swing/event/CaretListener.js
-javax/swing/event/ChangeEvent.js
-javax/swing/event/ChangeListener.js
-javax/swing/event/DocumentEvent.js
-javax/swing/event/DocumentListener.js
-javax/swing/event/EventListenerList.js
-javax/swing/event/ListDataEvent.js
-javax/swing/event/ListDataListener.js
-javax/swing/event/UndoableEditEvent.js
-javax/swing/event/UndoableEditListener.js
-javax/swing/FocusManager.js
-javax/swing/InternalFrameFocusTraversalPolicy.js
-javax/swing/LayoutComparator.js
-javax/swing/LayoutFocusTraversalPolicy.js
-javax/swing/SortingFocusTraversalPolicy.js
-javax/swing/SwingContainerOrderFocusTraversalPolicy.js
-javax/swing/SwingDefaultFocusTraversalPolicy.js
-javax/swing/Icon.js
-javax/swing/ImageIcon.js
-javax/swing/InputMap.js
-javax/swing/JApplet.js
-javax/swing/JButton.js
-javax/swing/JCheckBox.js
-javax/swing/JCheckBoxMenuItem.js
-javax/swing/JComboBox.js
-javax/swing/JComponent.js
-javax/swing/JFrame.js
-javax/swing/JLabel.js
-javax/swing/JLayeredPane.js
-javax/swing/JMenu.js
-javax/swing/JMenuBar.js
-javax/swing/JMenuItem.js
-javax/swing/JPanel.js
-javax/swing/JPopupMenu.js
-javax/swing/JRadioButtonMenuItem.js
-javax/swing/JRootPane.js
-javax/swing/JScrollBar.js
-javax/swing/JScrollPane.js
-javax/swing/JSeparator.js
-javax/swing/JTextArea.js
-javax/swing/JTextField.js
-javax/swing/JToggleButton.js
-javax/swing/JViewport.js
-javax/swing/KeyboardManager.js
-javax/swing/KeyStroke.js
-javax/swing/ListModel.js
-javax/swing/LookAndFeel.js
-javax/swing/MenuElement.js
-javax/swing/MutableComboBoxModel.js
-javax/swing/plaf/ActionMapUIResource.js
-javax/swing/plaf/basic/BasicBorders.js
-javax/swing/plaf/BorderUIResource.js
-javax/swing/plaf/ColorUIResource.js
-javax/swing/plaf/ComponentUI.js
-javax/swing/plaf/DimensionUIResource.js
-javax/swing/plaf/FontUIResource.js
-javax/swing/plaf/InputMapUIResource.js
-javax/swing/plaf/InsetsUIResource.js
-javax/swing/plaf/UIResource.js
-javax/swing/RepaintManager.js
-javax/swing/RootPaneContainer.js
-javax/swing/Scrollable.js
-javax/swing/ScrollPaneConstants.js
-javax/swing/ScrollPaneLayout.js
-javax/swing/SingleSelectionModel.js
-javax/swing/SizeRequirements.js
-javax/swing/SwingConstants.js
-javax/swing/SwingPaintEventDispatcher.js
-javax/swing/SwingUtilities.js
-javax/swing/text/AbstractDocument.js
-javax/swing/text/AttributeSet.js
-javax/swing/text/Caret.js
-javax/swing/text/DefaultCaret.js
-javax/swing/text/DefaultEditorKit.js
-javax/swing/text/Document.js
-javax/swing/text/EditorKit.js
-javax/swing/text/Element.js
-javax/swing/text/GapContent.js
-javax/swing/text/GapVector.js
-javax/swing/text/JTextComponent.js
-javax/swing/text/MutableAttributeSet.js
-javax/swing/text/PlainDocument.js
-javax/swing/text/PlainView.js
-javax/swing/text/Position.js
-javax/swing/text/Segment.js
-javax/swing/text/SegmentCache.js
-javax/swing/text/SimpleAttributeSet.js
-javax/swing/text/Style.js
-javax/swing/text/StyleConstants.js
-javax/swing/text/StyleContext.js
-javax/swing/text/TabExpander.js
-javax/swing/text/TextAction.js
-javax/swing/text/Utilities.js
-javax/swing/text/View.js
-javax/swing/tree/TreeNode.js
-javax/swing/UIDefaults.js
-javax/swing/UIManager.js
-javax/swing/undo/AbstractUndoableEdit.js
-javax/swing/undo/CompoundEdit.js
-javax/swing/undo/UndoableEdit.js
-javax/swing/ViewportLayout.js
-javax/swing/WindowConstants.js
-sun/awt/AppContext.js
-sun/awt/AWTAutoShutdown.js
-sun/awt/CausedFocusEvent.js
-sun/awt/ComponentFactory.js
-sun/awt/KeyboardFocusManagerPeerProvider.js
-sun/awt/MostRecentKeyValue.js
-sun/awt/MostRecentThreadAppContext.js
-sun/awt/PaintEventDispatcher.js
-sun/awt/PostEventQueue.js
-sun/awt/RequestFocusController.js
-sun/awt/SunToolkit.js
-sun/awt/WindowClosingListener.js
-sun/awt/WindowClosingSupport.js
-sun/awt/image/DataStealer.js
-sun/awt/image/IntegerComponentRaster.js
-sun/awt/image/IntegerInterleavedRaster.js
-sun/awt/image/SunWritableRaster.js
-sun/font/FontDesignMetrics.js
-sun/swing/DefaultLookup.js
-sun/swing/SwingLazyValue.js
-sun/text/resources/FormatData.js
-sun/text/resources/en/FormatData_en.js
-sun/util/resources/LocaleData.js
-sun/util/locale/BaseLocale.js
-sun/util/locale/LocaleUtils.js
-sun/util/locale/provider/LocaleProviderAdapter.js
-sun/util/locale/provider/LocaleDataMetaInfo.js
-swingjs/a2s/A2SContainer.js
-swingjs/a2s/A2SEvent.js
-swingjs/a2s/A2SListener.js
-swingjs/a2s/Applet.js
-swingjs/a2s/Button.js
-swingjs/a2s/Label.js
-swingjs/a2s/Panel.js
-swingjs/a2s/Scrollbar.js
-swingjs/a2s/ScrollPane.js
-swingjs/a2s/TextArea.js
-swingjs/a2s/TextField.js
-swingjs/api/Interface.js
-swingjs/api/js/DOMNode.js
-swingjs/api/js/HTML5CanvasContext2D.js
-swingjs/api/js/JSInterface.js
-swingjs/jquery/JQueryUI.js
-swingjs/JSApp.js
-swingjs/JSAppletThread.js
-swingjs/JSAppletViewer.js
-swingjs/JSFocusPeer.js
-swingjs/JSFontMetrics.js
-swingjs/JSFrameViewer.js
-swingjs/JSGraphics2D.js
-swingjs/JSGraphicsConfiguration.js
-swingjs/JSGraphicsEnvironment.js
-swingjs/JSImage.js
-swingjs/JSImagekit.js
-swingjs/JSMouse.js
-swingjs/JSNullComponentPeer.js
-swingjs/JSScreenDevice.js
-swingjs/JSThreadGroup.js
-swingjs/JSToolkit.js
-swingjs/JSUtil.js
-swingjs/plaf/ButtonListener.js
-swingjs/plaf/DefaultMenuLayout.js
-swingjs/plaf/HTML5LookAndFeel.js
-swingjs/plaf/JSAppletUI.js
-swingjs/plaf/JSButtonUI.js
-swingjs/plaf/JSCheckBoxMenuItemUI.js
-swingjs/plaf/JSCheckBoxUI.js
-swingjs/plaf/JSComboBoxUI.js
-swingjs/plaf/JSComponentUI.js
-swingjs/plaf/JSEventHandler.js
-swingjs/plaf/JSFrameUI.js
-swingjs/plaf/JSGraphicsUtils.js
-swingjs/plaf/JSLabelUI.js
-swingjs/plaf/JSLayeredPaneUI.js
-swingjs/plaf/JSLightweightUI.js
-swingjs/plaf/JSMenuBarUI.js
-swingjs/plaf/JSMenuItemUI.js
-swingjs/plaf/JSMenuUI.js
-swingjs/plaf/JSPanelUI.js
-swingjs/plaf/JSPopupMenuSeparatorUI.js
-swingjs/plaf/JSPopupMenuUI.js
-swingjs/plaf/JSRadioButtonMenuItemUI.js
-swingjs/plaf/JSRadioButtonUI.js
-swingjs/plaf/JSRootPaneUI.js
-swingjs/plaf/JSScrollBarUI.js
-swingjs/plaf/JSScrollPaneUI.js
-swingjs/plaf/JSSeparatorUI.js
-swingjs/plaf/JSSliderUI.js
-swingjs/plaf/JSTextAreaUI.js
-swingjs/plaf/JSTextFieldUI.js
-swingjs/plaf/JSTextUI.js
-swingjs/plaf/JSTextViewUI.js
-swingjs/plaf/JSViewportUI.js
-swingjs/plaf/JSWindowUI.js
-swingjs/plaf/LazyActionMap.js
-swingjs/plaf/Resizer.js
-swingjs/plaf/TextListener.js
-
-
+++ /dev/null
-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
-
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="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 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.
-
-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
-=====================================================================
-
-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<Object,PRESENT>:
-
- [HashSet] makes no guarantees as to the iteration order of the set.
-
-JavaScript's Map object is different. It is basically a LinkedHashMap, so it guarantees iteration
-in order of object addition.
-
-Starting with java2script 3.2.9.v1, these classes use the JavaScript Map object rather than hash codes
-whenever all keys are strictly of JavaScript typeof "string". If any key is introduced that is not a string, the
-implementation falls back to using hash codes, the same as Java.
-
-Note strings created using new String("xxxx") are NOT typeof "string"; they are typeof "object".
-
-The result is significantly faster performance (3-12 x faster) than originally, and up to 3 x faster
-performance in JavaScript than in Java itself. Right. Faster than Java.
-
-The JavaScript Map implementation is implemented UNLESS the constructor used is the one that
-specifies both initial capacity and load factor in their constructor. Thus,
-
-new Hashtable()
-new HashMap()
-new HashMap(16)
-new HashSet()
-
-all use the JavaScript Map. But
-
-new Hashtable(11, 0.75f)
-new HashMap(16, 0.75f)
-new HashSet(16, 0.75f)
-
-do not.
-
-This design allows for opting out of the JavaScript Map use in order to retain the exact behavior of
-iterators in JavaScript as in Java.
-
-
-interning, new String("xxx") vs "xxx"
--------------------------------------
-
-Note that the following are true in JavaScript:
-
-typeof new String("xxxx") == "object"
-typeof "xxxx" == "string"
-var s = "x";typeof ("xxx" + s) == "string"
-
-There is no equivalence to this behavior in Java, where a String is a String is a String.
-
-Be aware that SwingJS does not always create a JavaScript String object using JavaScript's
-new String(...) constructor. It only does this for Java new String("xxxx") or new String(new String()).
-
-In all other cases, new String(...) (in Java) results in a simple "xxxx" string in JavaScript.
-That is, it will be JavaScript typeof "string", not typeof "object".
-
-The reason for this design is that several classes in the Java core use toString()
-methods that return new String(), and those classes that do that would cause a JavaScript error
-if implicitly stringified if new String() returned a JavaScript String object.
-
-This is fine in JavaScript
-
-test1 = function() { return { toString:function(){ return "OK" } } }
-"testing" + new test1()
->> "testingOK"
-
-But for whatever reason in JavaScript:
-
-test2 = function() { return { toString:function(){ return new String("OK") } } }
-"testing" + new test2()
->> Uncaught TypeError: Cannot convert object to primitive value
-
-The lesson here is never to use
-
- return new String("...");
-
-in a Java toString() method. In Java it will be fine; in JavaScript it will also be fine as long as
-that method is never called in JavaScript implicitly in the context of string concatenation.
-
-A note about interning. Consider the following six Java constructions, where we have a == "x";
-
-"xxx"
-"xx" + "x"
-new String("xxx").intern()
-
-new String("xxx")
-"xx" + a.toString()
-"xx" + a
-
-All six of these will return java.lang.String for .getClass().getName().
-However, the first three are String literals, while the last three are String objects.
-Thus:
- "xxx" == "xxx"
- "xxx" == "xx" + "x"
- "xxx" == new String("xxx").intern()
-
-but none of the other three are equivalent to "xxx" or each other:
-
- "xxx" != new String("xxx")
- "xxx" != "xx" + a.toString()
- "xxx" != "xx" + a
- new String("xxx") != new String("xxx")
- "xx" + a != new String("xxx")
-
-etc.
-
-As in Java, in SwingJS, all of the following Java assertions pass as true:
-
- assert("xxx" == "xx" + "x");
- assert("xxx" == ("xx" + a).intern());
- assert("xxx" === new String("xxx").intern());
-
-and both of these do as well:
-
- assert(new String("xxx") != "xxx");
- assert(new String("xxx") != new String("xxx"));
-
-But the following two fail to assert true:
-
- assert("xxx" != "xx" + a);
- assert("xxx" != "xx" + a.toString());
-
-because in JavaScript, both of these right-side expressions evaluate to a simple "interned" string.
-
-In Java, however, these assertions are true because Java implicitly "boxes" String
-concatentaion as a String object, not a literal.
-
-Most of us know not to generally use == with Strings unless they are explicitly interned.
-Where this problem may arise, though, is in IdentityHashMap, which compares objects using
-System.identityHashCode(), which is not the same for different objects or their string literal equivalents.
-
-My recommendation, if you need to use IdentityHashMap with strings is to always use an explicit String.intern()
-for any keys -- unless you really want to keep every string as separate keys even if they are the same sequence,
-in which case, use new String(). This will work in Java and in JavaScript.
-
-Be aware when working with strings that come from SwingJS and are being used by other JavaScript modules
-that those that are String objects will return "object" for the JavaScript typeof operator, not "string".
-
-The easy way to ensure this is no problem is to concatenate strings with "" to force immediate interning:
-
- var x = aJavaObject.getString() + "";
-
-unless you are certain that the string is being returned is a raw JavaScript string.
-
-Names with "$" and "_"
-----------------------
-
-For the most part, this should be no problem.
-
-Note that the use of $ and _ in Java field names has always been discouraged:
-[https://docs.oracle.com/javase/tutorial/java/nutsandbolts/variables.html]
-
- You may find some situations where auto-generated names will contain the dollar sign,
- but your variable names should always avoid using it. A similar convention
- exists for the underscore character; while it's technically legal to begin your
- variable's name with "_", this practice is discouraged.
-
-Some impacts of transpiling method names with full qualification:
-
-1) SwingJS will introduce fields that start with $ or _. These will not conflict
- if the above convention is followed.
-
-2) Fields that have the same Java name as a method are not an issue.
-
-3) Fields that have a Java name with $ that matches a transpiled method name,
- such as toString$, will need to be refactored in Java to not have that name collision.
-
-4) Fields in a subclass that have the same name as private fields in a superclass
- represent a name collision, because the superclass method needs to call its private
- field even if invoked from a subclass. The solution was to modify the subclass field
- name using one or more prepended $.
-
-5) Use of Class.getDeclaredMethods() reflection will return Method objects having the transpiled
- name, not the Java name. This could require some j2sNative adjustment
- to strip the $... parameters from the name if that is needed.
-
-6) Use of Method.getParameterTypes() should work fine, provided class names
- do not contain "_". This is because the transpiler converts "." to "_" when
- creating the fully qualified JavaScript name.
-
-
-positive integers do not add to give negative numbers
------------------------------------------------------
-
-In Java, the following is true:
-
- 2000000000 + 2000000000 == -294967296
-
-But in SwingJS, that will be 4000000000. So, for example, the following
-strategy will fail in SwingJS:
-
- int newLength = lineBuf.length * 2;
- if (newLength < 0) {
- newLength = Integer.MAX_VALUE;
- }
-
-"-1" in JavaScript is not 0xFFFFFFFF.
-
-And one must take care to not compare a negative number with a 32-bit mask. So
-
-(b & 0xFF000000) == 0xFF000000
-
-is true in Java for (int) b = -1, but is false in JavaScript, because 0xFF000000 is 4278190080,
-while (-1 & 0xFF000000) is, strangely enough, -16777216, and, in fact,
-
-(0xFF000000 & 0xFF000000) != 0xFF000000
-
-because -16777216 is not 4278190080.
-
-The fix is that one must compare similar operations:
-
-if ((b & 0xFF000000) == (0xFF000000 & 0xFF000000)) .....
-
-Importantly, the JavaScript Int32Array does behave properly. From
-the Firefox developer console:
-
->> x = new Int32Array(1)
-<- Int32Array(1) [ 0 ]
->> x[0] = 4000000000
-<- 4000000000
->> x[0]
-<- -294967296
-
-Notice that, perhaps unexpectedly, the following two constructs produce
-different results in JavaScript:
-
-x = new Int32Array(1);
-b = x[0] = 4000000000;
-
-(b will be 4000000000)
-
-and
-
-x = new Int32Array(1);
-x[0] = 4000000000;
-b = x[0];
-
-(b will be -294967296)
-
-
-SwingJS leverages array typing to handle all byte and short arithmetic so as
-to ensure that any byte or short operation in JavaScript does give the same
-result in Java. The design decision to not also do this with integer math was
-a trade-off between performance and handling edge cases.
-
-
-ArrayIndexOutOfBounds
----------------------
-
-You cannot implicitly throw an ArrayIndexOutOfBoundsException in JavaScript.
-JavaScript will simply return "undefined", not throw an Exception. So:
-
-boolean notAGoodIdeaIsOutOfBounds(String[] sa, int i) {
- try {
- return (sa[i] == sa[i]);
- } catch (ArrayIndexOutOfBoundsException e) {
- return false;
- }
-}
-
-will work in Java but not in JavaScript. Code should not depend upon this sort
-of trap anyway, if you ask me.
-
-Throwable vs Error vs Exception
--------------------------------
-
-True JavaScript errors are trapped as Throwable, whereas you can still trap
-Error and Exception as well. So if you want to be sure to catch any JavaScript
-error, use try{}catch (Throwable t){}, not try{}catch (Exception e){}.
-
-j
-ava.awt.Color
---------------
-
-ColorSpace: only "support" CS_sRGB.
-
- TODO -- any volunteers??
-
-
-javax.swing.JFileDialog
------------------------
-
-HTML5 cannot expose a file reading directory structure. But you certainly
-can still do file reading and writing. It just works a little differently.
-It's a simple modification:
-
- b = new JButton("FileOpenDialog");
- b.addActionListener(new ActionListener() {
-
- @Override
- public void actionPerformed(ActionEvent e) {
- JFileChooser fc = new JFileChooser();
- Test_Dialog.this.onDialogReturn(fc.showOpenDialog(Test_Dialog.this));
- // Java will wait until the dialog is closed, then enter the onDialogReturn method.
- // JavaScript will exit with NaN immediately, and then call back with its actual value
- // asynchronously.
- }
-
- });
-
- public void onDialogReturn(int value) {
- if (value != Math.floor(value))
- return; // in JavaScript, this will be NaN, indicating the dialog has been opened
- // If we are here, the dialog has closed, in both Java and JavaScript.
- System.out.println("int value is " + value);
- }
-
-
- @Override
- public void propertyChange(PropertyChangeEvent event) {
- Object val = event.getNewValue();
- String name = event.getPropertyName();
- System.out.println(name);
- switch (event.getSource().getClass().getName()) {
- case "javax.swing.JOptionPane":
- switch (name) {
- case "inputValue":
- onDialogReturn(val);
- return;
- case "value":
- if (val instanceof Integer)
- onDialogReturn(((Integer) val).intValue());
- else
- onDialogReturn(val);
- return;
- }
- break;
- case "javax.swing.ColorChooserDialog":
- switch (name) {
- case "SelectedColor":
- onDialogReturn(val);
- return;
- }
- break;
- case "javax.swing.JFileChooser":
- switch (name) {
- case "SelectedFile":
- File file = (File) val;
- byte[] array = (val == null ? null : /** @j2sNative file.秘bytes || */
- null);
- onDialogReturn("fileName is '" + file.getName() + "'\n\n" + new String(array));
- return;
- }
- break;
- }
- System.out.println(
- event.getSource().getClass().getName() + " " + event.getPropertyName() + ": " + event.getNewValue());
- }
-
-
-Developers are encouraged to create a separate class that handles general calls to JFileDialog.
-An example class can be found in the SwingJS distribution as
-
-/sources/net.sf.j2s.java.core/src/javajs/async/AsyncFileChooser.java.
-
-
-javax.swing.JOptionPane dialogs
--------------------------------
-
-For this action to work, the parentComponent must implement
-propertyChangeListener, and any call to JOptionPanel should allow for
-an asynchronous response, meaning that there is no actionable code following the
-call to the dialog opening.
-
-In addition, for compatibility with the Java version, implementation should
-wrap the call to getConfirmDialog or getOptionDialog in a method call to
-handle the Java:
-
-onDialogReturn(JOptionPane.showConfirmDialog(parentFrame,
-messageOrMessagePanel, "title", JOptionPane.OK_CANCEL_OPTION));
-
-Then parentFrame.propertyChange(event) should also call onDialogReturn.
-
-This will then work in both Java and JavaScript.
-
-Note that there is an int and an Object version of onDialogReturn().
-
-
-In JavaScript:
-
-The initial return from JOptionPane.showConfirmDialog and showMessageDialog
-will be (SwingJS) JDialog.ASYNCHRONOUS_INTEGER (NaN), testable as an impossible
-Java int value using ret != -(-ret) if the parent implements PropertyChangeListener, or -1
-(CLOSE_OPTION) if not.
-
-For showOptionDialog (which returns Object) or showInputDialog (which returns
-String), the initial return will be (SwingJS) JDialog.ASYNCHRONOUS_OBJECT, testable as
-((Object) ret) instanceof javax.swing.plaf.UIResource if the parent implements
-PropertyChangeListeneer, or null if not.
-
-The second return will be the desired return.
-
-In Java:
-
-The initial return will be the one and only modal final return.
-
-
-
-For full compatibility, The calling method must not continue beyond this
-call.
-
-All of the standard Java events associated with Components are also
-available.
-
-Certain fall back mechanisms are possible, where onReturn does not exist, but
-only for the following cases:
-
-
-For showMessageDialog, for WARNING_MESSAGE and ERROR_MESSAGE, a simple
-JavaScript alert() is used, returning 0 (OK_OPTION) or -1 (CLOSED_OPTION).
-
-For showInputDialog, if the message is a string, a simple JavaScript prompt()
-with input box is used, returning the entered string or null.
-
-For showConfirmDialog, a simple JavaScript confirm() is used, in which case:
-
-for YES_NO_OPTION: YES_OPTION or NO_OPTION
-
-for YES_NO_CANCEL_OPTION: YES_OPTION or CANCEL_OPTION
-
-for OK_CANCEL_OPTION or any other: OK_OPTION or CANCEL_OPTION
-
-Note that you should implement a response for CLOSED_OPTION for
-showConfirmDialog. For other dialogs, a null return indicates the dialog was
-closed, just as for Java.
-
-Developers are encouraged to create a separate class that handles general calls.
-An example class can be found in the SwingJS distribution as src/javajs/async/AsyncDialog.java.
-Very simple modifications to the Java allows asynchronous operation using AsyncDialog. Here
-is a simple "do you want to close this frame" example, where you can see that what we have
-done is to set the reply into an ActionListener that is defined in the constructor of
-the AsyncDisplay object:
-
-// Original:
-//
-// private void promptQuit() {
-// int sel = JOptionPane.showConfirmDialog(null, PROMPT_EXIT, NAME, JOptionPane.YES_NO_OPTION);
-// switch (sel) {
-// case JOptionPane.YES_OPTION:
-// resultsTab.clean();
-// seqs.dispose();
-// if (fromMain) {
-// System.exit(0);
-// }
-// break;
-// }
-// }
-
- private void promptQuitAsync() {
- new AsyncDialog(new ActionListener() {
-
- @Override
- public void actionPerformed(ActionEvent e) {
- int sel = ((AsyncDialog)e.getSource()).getOption();
- switch (sel) {
- case JOptionPane.YES_OPTION:
- resultsTab.clean();
- seqs.dispose();
- if (fromMain) {
- System.exit(0);
- }
- break;
- }
- }}).showConfirmDialog(null, PROMPT_EXIT, NAME, JOptionPane.YES_NO_OPTION);
- }
-
-Very simple!
-
-
-native methods
---------------
-
-The J2S compiler ignores all static native method declarations.
-Anything of this nature needs to be implemented in JavaScript if it is needed,
-using j2sNative blocks:
-
-/**
- * @j2sNative
- *
- * var putYourJavaScriptCodeHere
- *
- */
-
- Note that if you follow that directly with a {...} block, then
- the javadoc code will run in JavaScript, and the {...} code will run in Java.
-
-
-key Focus
----------
-
-As of June, 2019, the keyboard focus manager is fully implemented.
-The one catch is that JTextPane and JTextArea, which already consume
-VK_TAB in Java, cannot use CTRL-TAB to continue a tabbing cycle around
-the components in a window. Instead, CTRL-TAB is absorbed by the browser.
-
-
-LookAndFeel and UI Classes
---------------------------
-
-SwingJS implements the native browser look and feel as swingjs.plaf.HTML5LookAndFeel.
-There are small differences between all look and feels -- MacOS, Windows, SwingJS.
-
-Expert developers know how to coerce changes in the UI by subclassing the UI for a
-component. This probably will not work in SwingJS.
-
-Note that LookAndFeel in Java usually determines canvas size in a Frame because
-different operating systems (Mac OS vs Windows vs HTML5) will have
-different edge sizes on their frames. If you want to ensure a component size,
-use getContentPane().setPreferredSize().
-
-
-System.exit(0) does not stop all processes
-------------------------------------------
-
-Although System.ext(int) has been implemented in JavaScript, it just closes the
-frames, stops all pending javax.swing.Timer objects in the queue, and runs any
-threads added using Runtime.getRuntime().addShutdownHook(Thread).
-It may not stop all "threads." So don't rely on that.
-Applications are responsible for shutting down prior to executing System.exit(0).
-
-
-myClass.getField not implemented
---------------------------------
-
-java.lang.reflect.Field is implemented minimally. It is not
-certain that Field.getDeclaringClass() will work. If you just want a
-value of a field, you can do this:
-
-/**
- *@j2sNative
- *
- * return myClass[name]
- */
-
-But that is not a java.lang.reflection.Field object.
-
-
-"window" and other reserved JavaScript names
---------------------------------------------
-
-No reserved top-level JavaScript name is allowed for a package name. So, for example,
-one must rename packages such as "window" or "document" to names such as "win" or "doc".
-
-reserved field and method names
--------------------------------
-
-In order to minimize the chance of added SwingJS field and method names colliding with ones
-developers might use in subclassing Java classes, we have added U+79D8 (first character of Mandarin
-"secret") to the characters already disrecommended by Java documentation ("$" and "_"). The only problem
-would be if you use that character followed by certain English words in certain classes. For example
-\u79D8canvas for JComponents (in java.awt.JSComponent) and \u79D8byte (in java.io.File).
-
-qualified field and method names
---------------------------------
-
-Method names in SwingJS are fully qualified, meaning two methods with the same Java name but different
-parameters, such as write(int) and write(double), must not have the same name in JavaScript. (In this
-case, we will have write$I and write$D.) However, in certain cases it may be desirable to leave the
-method names unqualified. In particular, when an interface actually represents a JavaScript object,
-the transpiler can leave a method name unqualified. The default situation for this is a class name
-includes ".api.js" (case-sensitive). This means that any method in any class in a package js within
-a package api, or any private interface js that has an outer interface api, will have all-unqualified
-methods. An example of this is swingjs.plaf.JSComboPopupList, which needs to communicate with a jQuery
-object directly using the following interface:
-
- private interface api {
-
- interface js extends JQueryObject {
-
- abstract js j2sCB(Object options);
-
- abstract Object[] j2sCB(String method);
-
- abstract Object[] j2sCB(String method, Object o);
-
- abstract Object[] j2sCB(String method, int i);
-
- abstract int j2sCB(String OPTION, String name);
-
- }
- }
-
-Notice that all these variants of j2sCB() will call the same method in JavaScript by design.
-
-
-missing Math methods
---------------------
-
-java.lang.Math is worked out, but some methods are missing, either because they
-involve long integer value that are inaccessible in JavaScript, or because I just
-didn't implement them. This is a result of continued Java development.
-It is easy enough to add these methods if you have the source. They go into j2sClazz.js,
-which is combined with other initial libraries into swingjs2.js by build_site.xml
-
-
-Component.getGraphics(), Graphics.dispose()
--------------------------------------------
-
-Use of component.getGraphics() is discouraged in Java and in SwingJS.
-Specifically in SwingJS, any call to component.getGraphics() or
-BufferedImage.createGraphics() or Graphics.create(...) should be matched with graphics.dispose(),
-particularly when it is called outside the context of a paint(Graphics)
-call from the system.
-
-If you see your graphics scrolling down the page with each repaint,
-look for where you have used Component.getGraphics() and not Graphics.dispose().
-For example, this will definitely NOT work in SwingJS:
-
- this.paint(getGraphics())
-
-and really should not work in Java, either, as it is technically a resource memory leak.
-
-Instead, if you really do not want to use repaint(), use this:
-
- Graphics g = getGraphics();
- paint(g);
- g.dispose();
-
-
-
-Graphics.setClip()
-------------------
-
-The HTML5 canvas.clip() method is permanent. You can only reset the clip using
-save/restore. This is different from Java, where you can temporarily change it using
-
- Shape oldClip = Graphics.getClip();
- Graphics.setClip(newClip);
- ...
- Graphics.setClip(oldClip);
-
-If you need to do something like this, you must schedule the paints
-to not have overlapping clip needs.
-
-
-MAJOR ISSUES--for Bob and Udo within SwingJS
-============================================
-
-fonts
------
-
-Fonts and FontMetrics will all be handled in JavaScript. Font matching will
-not be exact, and composite (drawn) fonts will not be supported.
-
-SwingJS handles calls such as font.getFontMetrics(g).stringWidth("xxx") by
-creating a <div> containing that text, placing it in an obscure location on
-the page, and reading div.getBoundingClientRect(). This is a VERY precise
-value, but can be a pixel or two off from what Java reports for the same font.
-
-
-OS-dependent classes
---------------------
-
-Static classes such as:
-
- java.awt.Toolkit
- java.awt.GraphicsEnvironment
-
-
-which are created using Class.forName are implemented using classes in the swingjs package.
-
-AWTAccessor is not implemented.
-
-
-AWT component peers and component "ui" user interfaces
-------------------------------------------------------
-
-ComponentPeer is a class that represents a native AWT component.
-Components with such peers are called "heavy-weight" components.
-They are expected to do the dirty work of graphics drawing.
-
-Java Swing implements peers only for JApplet, JDialog, JFrame, and JWindow.
-References to such objects have been removed, but clearly there must be
-some connection to similar DOM objects, even for "light-weight" components.
-
-
-
-MAJOR ISSUES--to be resolved by implementers
-============================================
-
-fonts
------
-
-Glyph/composite/outline fonts are not supported.
-
-
-
-threads
--------
-
-Thread locking and synchronization are not relevant to JavaScript.
-Thus, anything requiring "notify.." or "waitFor.." could be a serious issue.
-
-All threading must be "faked" in JavaScript. Specifically not available is:
-
- Thread.sleep()
-
-javax.swing.AbstractButton#doClick(pressTime) will not work, as it requires Thread.sleep();
-
-However, java.lang.Thread itself is implemented and used extensively.
-
-Methods thread.start() and thread.run() both work fine.
-
-For simple applications that use Thread.sleep() just to have a delay, as in a frame rate, for
-example, one can use javax.swing.Timer instead. That is fully implemented.
-
-Likewise, java.util.Timer can be replaced with no loss of performance with javax.Swing.Timer.
-Note that java.util.TimerTask is implemented, but it can also be replaced by an implementation of Runnable.
-
-task = new TimerTask(){....};
-t = new java.util.Timer();
-t.schedule(task, 0, 1);
-
-becomes
-
-task = new TimerTask(){....}; // or task = new Runnable() {...}
-t = new javax.swing.Timer(1, new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- task.run();
- }
-};
-t.setInitialDelay(0); // not particularly necessary
-t.start();
-
-In addition, SwingJS provides swingjs.JSThread, which can be subclassed
-if desired. This class allows simple
-
- while(!interrupted()){
- wait()
- ...
- }
-
-action through an asynchronous function run1(mode). For example:
-
- protected void run1(int mode) {
- try {
- while (true)
- switch (mode) {
- case INIT:
- // once-through stuff here
- mode = LOOP;
- break;
- case LOOP:
- if (!doDispatch || isInterrupted()) {
- mode = DONE;
- } else {
- Runnable r = new Runnable() {
- public void run() {
- // put the loop code here
- }
- };
- dispatchAndReturn(r);
- if (isJS)
- return;
- }
- break;
- // add more cases as needed
- case DONE:
- // finish up here
- if (isInterrupted())
- return;
- // or here
- break;
- }
- } finally {
- // stuff here to be executed after each loop in JS or at the end in Java
- }
- }
-
-image loading
--------------
-- All image loading in SwingJS is synchronous. A MediaTracker call will immediately return "complete".
- However, it still may take one system clock tick to fully load images. Thus, it is recommended that
- images be preloaded in the static block of the applet if it is necessary that they be available in init().
- This is only an issue if you are trying to access the pixel buffer of the image in JavaScript.
-
-- Applet.getImage(path, name) will return null if the image does not exist.
-
-- BufferedImage: only "support" imageType RGB and ARGB
-
- -BH: This is a temporary edit, just to get us started. Certainly GRAY will be needed
-
-
-BigInteger and BigDecimal
--------------------------
-
-java.math.BigInteger is fully supported; java.math.BigDecimal is roughed
-in and not fully tested (07/2019).
-
-Both classes present significant issues for JavaScript, as they are based in
-Java's 64-bit long for all their operations. Here is the JavaDoc note I added
-to BigInteger:
-
- * SwingJS note: Because of the limitations of JavaScript with regard
- * to long-integer bit storage as a double, this implementation drops
- * the integer storage bit length to 24, giving 48 for long and leaving
- * the last 16 bits clear for the exponent of the double number. This should
- * not affect performance significantly. It does increase the storage
- * size by about 33%. By bringing an "int" to 3 bytes, we can easily construct
- * and use byte[] data intended for the original BitSet.
-
-"Easily" may be a bit strong there. This was a serious challenge.
-
-BigDecimal seems to run normally, but in order to do that, my hack involves
-reducing the size of an integer that is allowed to be stored as such and not
-in byte[] as a BigInteger. I'm sure there is a performance hit, but it does work.
-
-no format internationalization
-------------------------------
-
-For now, just en for number and date formatters
-
-no winding rules
-----------------
-
- When filling a graphic, only nonzero winding rule is implemented in HTML5 Canvas2D.
-
-
-
-text-related field implementation
----------------------------------
-
-Text fields are:
-
-JTextField (JavaScript <input type="text">)
-JTextArea (JavaScript <textarea>)
-JTextPane (JavaScript <div>)
-JEditorPane (JavaScript <div>)
-
-For the initial implementation, we don't implement infinite undo/redo, and the abstract
-document model is much less elaborate. Only PlainDocument (in the form of JSPlainDocument)
-is implemented. The Document returned by JTextField.getDocument() is a javax.swing.text.Document.
-
-All scrolling is handled by HTML5. javax.swing.AutoScroller is not implemented.
-public static methods .stop, .isRunning, .processMouseDragged require true Java threading
-and so are not implmented. javax.swing.text.View and its subclasses are not implemented.
-
-The JS document model does not allow two text fields to address the same underlying document.
-
-JavaScript is slightly different from Java in that the field value is changed asynchronously after
-the keypressed event, so Java actions that are keyed to KEY_PRESSED may not pick up the new
-key value even after SwingUtilities.invokeLater() is called. Thus, key pressed actions may need
-to be recorded after a key released event instead.
-
-Formatter/Regex limitations
----------------------------
-
-Some browsers cannot process Regex "look-behind" process such as (?<=\W)
-java.util.regex.Matcher and Pattern use JavaScript's RegExp object rather than
-the native Java object. These are not identical. Only flags /igm are supported.
-Matcher.start(groupID) is not supported.
-
-java.util.Formatter will function correctly for all standard %... patterns.
-
-integer 1/0 == Infinity
------------------------
-
-1/0 in Java throws "java.lang.ArithmeticException: / by zero", but in JavaScript is just Infinity.
-
-
-
-Summary
--------
-
-These are all the known limitations of SwingJS. We have not found any of these limitations
-to be show-stoppers. The primary issue for newcomers to SwingJS is having the source code.
-You must check that source code for all your library jar files is available or, if you
-choose, you will need to decompile those classes. We have used decompilation on some projects,
-and it works just fine. So, technically, all we really need are JAR/class files. But the
-source is by far superior. It's generally prettier, and it has the license information that
-may or may not be present with the JAR or class files. Use class files at your own risk.
-
-Bob Hanson
-2019.08.16
-
-
-Additional Issues
------------------
-
-Annotation is working for classes, methods, and fields (12/22/19). Method reflection, however,
-is limited. Interfaces do not expose their methods, as the transpiler does not actually transpile
-the interfaces themselves. And method reflection only includes annotated methods.
-
-java.util.concurrent is not fully elaborated. This package is rewritten to not actually use the
-memory handling capabilities of concurrency, which JavaScript does not have access to.
-
-System.getProperties() just returns a minimal set of properties.
-
-
+++ /dev/null
-20201127032339
+++ /dev/null
-This is sources/net.sf.j2s.java.core/dist/DEV_NOTES.txt
-
-_j2sclasslist.txt
-
-the list of .js files concatenated into coreswingjs.js and minified to coreswingjs.z.js
-
-
-SwingJS-site.zip
-
-the full site directory for SwingJS including all files not in the test/ directory.
+++ /dev/null
-java/applet/Applet.js
-java/applet/AppletContext.js
-java/applet/AppletStub.js
-java/applet/JSApplet.js
-java/awt/ActiveEvent.js
-java/awt/Adjustable.js
-java/awt/AWTEvent.js
-java/awt/AWTEventMulticaster.js
-java/awt/AWTKeyStroke.js
-java/awt/BasicStroke.js
-java/awt/BorderLayout.js
-java/awt/Button.js
-java/awt/Color.js
-java/awt/color/ColorSpace.js
-java/awt/Component.js
-java/awt/ComponentOrientation.js
-java/awt/ContainerOrderFocusTraversalPolicy.js
-java/awt/Container.js
-java/awt/Cursor.js
-java/awt/DefaultFocusTraversalPolicy.js
-java/awt/DefaultKeyboardFocusManager.js
-java/awt/Dialog.js
-java/awt/Dimension.js
-java/awt/dnd/peer/DropTargetPeer.js
-java/awt/event/ActionListener.js
-java/awt/event/AdjustmentEvent.js
-java/awt/event/AdjustmentListener.js
-java/awt/event/AWTEventListener.js
-java/awt/event/ComponentAdapter.js
-java/awt/event/ComponentEvent.js
-java/awt/event/ComponentListener.js
-java/awt/event/ContainerListener.js
-java/awt/event/FocusEvent.js
-java/awt/event/FocusListener.js
-java/awt/event/HierarchyBoundsListener.js
-java/awt/event/HierarchyListener.js
-java/awt/event/InputEvent.js
-java/awt/event/InputMethodListener.js
-java/awt/event/InvocationEvent.js
-java/awt/event/ItemEvent.js
-java/awt/event/ItemListener.js
-java/awt/event/KeyListener.js
-java/awt/event/MouseEvent.js
-java/awt/event/MouseListener.js
-java/awt/event/MouseMotionListener.js
-java/awt/event/MouseWheelListener.js
-java/awt/event/TextListener.js
-java/awt/event/WindowAdapter.js
-java/awt/event/WindowEvent.js
-java/awt/event/WindowFocusListener.js
-java/awt/event/WindowListener.js
-java/awt/event/WindowStateListener.js
-java/awt/EventDispatchThread.js
-java/awt/EventFilter.js
-java/awt/EventQueue.js
-java/awt/EventQueueItem.js
-java/awt/FlowLayout.js
-java/awt/FocusTraversalPolicy.js
-java/awt/Font.js
-java/awt/font/FontRenderContext.js
-java/awt/FontMetrics.js
-java/awt/Frame.js
-java/awt/geom/AffineTransform.js
-java/awt/geom/Dimension2D.js
-java/awt/geom/Path2D.js
-java/awt/geom/PathIterator.js
-java/awt/geom/Point2D.js
-java/awt/geom/Rectangle2D.js
-java/awt/geom/RectangularShape.js
-java/awt/geom/RectIterator.js
-java/awt/GraphicsCallback.js
-java/awt/GraphicsConfiguration.js
-java/awt/GraphicsDevice.js
-java/awt/GraphicsEnvironment.js
-java/awt/Image.js
-java/awt/image/ImageObserver.js
-java/awt/Insets.js
-java/awt/ItemSelectable.js
-java/awt/JSComponent.js
-java/awt/JSDialog.js
-java/awt/JSFrame.js
-java/awt/JSPanel.js
-java/awt/KeyboardFocusManager.js
-java/awt/KeyEventDispatcher.js
-java/awt/KeyEventPostProcessor.js
-java/awt/Label.js
-java/awt/LayoutManager.js
-java/awt/LayoutManager2.js
-java/awt/LightweightDispatcher.js
-java/awt/Paint.js
-java/awt/Panel.js
-java/awt/peer/ComponentPeer.js
-java/awt/peer/ContainerPeer.js
-java/awt/peer/FramePeer.js
-java/awt/peer/KeyboardFocusManagerPeer.js
-java/awt/peer/LightweightPeer.js
-java/awt/peer/WindowPeer.js
-java/awt/Point.js
-java/awt/Queue.js
-java/awt/Rectangle.js
-java/awt/RenderingHints.js
-java/awt/Scrollbar.js
-java/awt/ScrollPane.js
-java/awt/Shape.js
-java/awt/Stroke.js
-java/awt/TextArea.js
-java/awt/TextComponent.js
-java/awt/TextField.js
-java/awt/Toolkit.js
-java/awt/Transparency.js
-java/awt/Window.js
-java/beans/ChangeListenerMap.js
-java/beans/PropertyChangeEvent.js
-java/beans/PropertyChangeListener.js
-java/beans/PropertyChangeSupport.js
-java/lang/AbstractStringBuilder.js
-java/lang/Class.js
-java/lang/Enum.js
-java/lang/Iterable.js
-java/lang/reflect/Constructor.js
-java/lang/reflect/Method.js
-java/lang/StringBuffer.js
-java/lang/StringBuilder.js
-java/lang/Thread.js
-java/lang/ThreadGroup.js
-java/math/RoundingMode.js
-java/net/URL.js
-java/net/URLStreamHandlerFactory.js
-java/net/HttpURLConnection.js
-java/net/URLStreamHandler.js
-javax/net/ssl/HttpsUrlConnection.js
-java/text/CharacterIterator.js
-java/text/DecimalFormat.js
-java/text/DecimalFormatSymbols.js
-java/text/DigitList.js
-java/text/FieldPosition.js
-java/text/Format.js
-java/text/NumberFormat.js
-java/util/AbstractCollection.js
-java/util/AbstractList.js
-java/util/AbstractMap.js
-java/util/AbstractSequentialList.js
-java/util/AbstractSet.js
-java/util/ArrayList.js
-java/util/Arrays.js
-java/util/Collection.js
-java/util/Collections.js
-java/util/Comparator.js
-java/util/Deque.js
-java/util/Dictionary.js
-java/util/Enumeration.js
-java/util/EventListener.js
-java/util/EventObject.js
-java/util/HashMap.js
-java/util/HashSet.js
-java/util/Hashtable.js
-java/util/IdentityHashMap.js
-java/util/Iterator.js
-java/util/LinkedHashMap.js
-java/util/LinkedList.js
-java/util/List.js
-java/util/ListResourceBundle.js
-java/util/Locale.js
-java/util/Map.js
-java/util/Objects.js
-java/util/Queue.js
-java/util/Random.js
-java/util/RandomAccess.js
-java/util/ResourceBundle.js
-java/util/Set.js
-java/util/TimSort.js
-java/util/Vector.js
-javajs/api/JSFunction.js
-javajs/util/AjaxURLConnection.js
-javajs/util/AjaxURLStreamHandlerFactory.js
-javajs/util/AU.js
-javajs/util/JSThread.js
-javajs/util/Lst.js
-javajs/util/PT.js
-javajs/util/Rdr.js
-javajs/util/SB.js
-javax/swing/AbstractAction.js
-javax/swing/AbstractButton.js
-javax/swing/AbstractListModel.js
-javax/swing/Action.js
-javax/swing/ActionMap.js
-javax/swing/AncestorNotifier.js
-javax/swing/ArrayTable.js
-javax/swing/border/AbstractBorder.js
-javax/swing/border/BevelBorder.js
-javax/swing/border/Border.js
-javax/swing/border/CompoundBorder.js
-javax/swing/border/EmptyBorder.js
-javax/swing/border/EtchedBorder.js
-javax/swing/border/LineBorder.js
-javax/swing/border/TitledBorder.js
-javax/swing/BorderFactory.js
-javax/swing/BoundedRangeModel.js
-javax/swing/BoxLayout.js
-javax/swing/ButtonGroup.js
-javax/swing/ButtonModel.js
-javax/swing/ClientPropertyKey.js
-javax/swing/ComboBoxModel.js
-javax/swing/DefaultBoundedRangeModel.js
-javax/swing/DefaultButtonModel.js
-javax/swing/DefaultComboBoxModel.js
-javax/swing/DefaultSingleSelectionModel.js
-javax/swing/DropMode.js
-javax/swing/event/AncestorEvent.js
-javax/swing/event/AncestorListener.js
-javax/swing/event/CaretEvent.js
-javax/swing/event/CaretListener.js
-javax/swing/event/ChangeEvent.js
-javax/swing/event/ChangeListener.js
-javax/swing/event/DocumentEvent.js
-javax/swing/event/DocumentListener.js
-javax/swing/event/EventListenerList.js
-javax/swing/event/ListDataEvent.js
-javax/swing/event/ListDataListener.js
-javax/swing/event/UndoableEditEvent.js
-javax/swing/event/UndoableEditListener.js
-javax/swing/FocusManager.js
-javax/swing/InternalFrameFocusTraversalPolicy.js
-javax/swing/LayoutComparator.js
-javax/swing/LayoutFocusTraversalPolicy.js
-javax/swing/SortingFocusTraversalPolicy.js
-javax/swing/SwingContainerOrderFocusTraversalPolicy.js
-javax/swing/SwingDefaultFocusTraversalPolicy.js
-javax/swing/Icon.js
-javax/swing/ImageIcon.js
-javax/swing/InputMap.js
-javax/swing/JApplet.js
-javax/swing/JButton.js
-javax/swing/JCheckBox.js
-javax/swing/JCheckBoxMenuItem.js
-javax/swing/JComboBox.js
-javax/swing/JComponent.js
-javax/swing/JFrame.js
-javax/swing/JLabel.js
-javax/swing/JLayeredPane.js
-javax/swing/JMenu.js
-javax/swing/JMenuBar.js
-javax/swing/JMenuItem.js
-javax/swing/JPanel.js
-javax/swing/JPopupMenu.js
-javax/swing/JRadioButtonMenuItem.js
-javax/swing/JRootPane.js
-javax/swing/JScrollBar.js
-javax/swing/JScrollPane.js
-javax/swing/JSeparator.js
-javax/swing/JTextArea.js
-javax/swing/JTextField.js
-javax/swing/JToggleButton.js
-javax/swing/JViewport.js
-javax/swing/KeyboardManager.js
-javax/swing/KeyStroke.js
-javax/swing/ListModel.js
-javax/swing/LookAndFeel.js
-javax/swing/MenuElement.js
-javax/swing/MutableComboBoxModel.js
-javax/swing/plaf/ActionMapUIResource.js
-javax/swing/plaf/basic/BasicBorders.js
-javax/swing/plaf/BorderUIResource.js
-javax/swing/plaf/ColorUIResource.js
-javax/swing/plaf/ComponentUI.js
-javax/swing/plaf/DimensionUIResource.js
-javax/swing/plaf/FontUIResource.js
-javax/swing/plaf/InputMapUIResource.js
-javax/swing/plaf/InsetsUIResource.js
-javax/swing/plaf/UIResource.js
-javax/swing/RepaintManager.js
-javax/swing/RootPaneContainer.js
-javax/swing/Scrollable.js
-javax/swing/ScrollPaneConstants.js
-javax/swing/ScrollPaneLayout.js
-javax/swing/SingleSelectionModel.js
-javax/swing/SizeRequirements.js
-javax/swing/SwingConstants.js
-javax/swing/SwingPaintEventDispatcher.js
-javax/swing/SwingUtilities.js
-javax/swing/text/AbstractDocument.js
-javax/swing/text/AttributeSet.js
-javax/swing/text/Caret.js
-javax/swing/text/DefaultCaret.js
-javax/swing/text/DefaultEditorKit.js
-javax/swing/text/Document.js
-javax/swing/text/EditorKit.js
-javax/swing/text/Element.js
-javax/swing/text/GapContent.js
-javax/swing/text/GapVector.js
-javax/swing/text/JTextComponent.js
-javax/swing/text/MutableAttributeSet.js
-javax/swing/text/PlainDocument.js
-javax/swing/text/PlainView.js
-javax/swing/text/Position.js
-javax/swing/text/Segment.js
-javax/swing/text/SegmentCache.js
-javax/swing/text/SimpleAttributeSet.js
-javax/swing/text/Style.js
-javax/swing/text/StyleConstants.js
-javax/swing/text/StyleContext.js
-javax/swing/text/TabExpander.js
-javax/swing/text/TextAction.js
-javax/swing/text/Utilities.js
-javax/swing/text/View.js
-javax/swing/tree/TreeNode.js
-javax/swing/UIDefaults.js
-javax/swing/UIManager.js
-javax/swing/undo/AbstractUndoableEdit.js
-javax/swing/undo/CompoundEdit.js
-javax/swing/undo/UndoableEdit.js
-javax/swing/ViewportLayout.js
-javax/swing/WindowConstants.js
-sun/awt/AppContext.js
-sun/awt/AWTAutoShutdown.js
-sun/awt/CausedFocusEvent.js
-sun/awt/ComponentFactory.js
-sun/awt/KeyboardFocusManagerPeerProvider.js
-sun/awt/MostRecentKeyValue.js
-sun/awt/MostRecentThreadAppContext.js
-sun/awt/PaintEventDispatcher.js
-sun/awt/PostEventQueue.js
-sun/awt/RequestFocusController.js
-sun/awt/SunToolkit.js
-sun/awt/WindowClosingListener.js
-sun/awt/WindowClosingSupport.js
-sun/awt/image/DataStealer.js
-sun/awt/image/IntegerComponentRaster.js
-sun/awt/image/IntegerInterleavedRaster.js
-sun/awt/image/SunWritableRaster.js
-sun/font/FontDesignMetrics.js
-sun/swing/DefaultLookup.js
-sun/swing/SwingLazyValue.js
-sun/text/resources/FormatData.js
-sun/text/resources/en/FormatData_en.js
-sun/util/resources/LocaleData.js
-sun/util/locale/BaseLocale.js
-sun/util/locale/LocaleUtils.js
-sun/util/locale/provider/LocaleProviderAdapter.js
-sun/util/locale/provider/LocaleDataMetaInfo.js
-swingjs/a2s/A2SContainer.js
-swingjs/a2s/A2SEvent.js
-swingjs/a2s/A2SListener.js
-swingjs/a2s/Applet.js
-swingjs/a2s/Button.js
-swingjs/a2s/Label.js
-swingjs/a2s/Panel.js
-swingjs/a2s/Scrollbar.js
-swingjs/a2s/ScrollPane.js
-swingjs/a2s/TextArea.js
-swingjs/a2s/TextField.js
-swingjs/api/Interface.js
-swingjs/api/js/DOMNode.js
-swingjs/api/js/HTML5CanvasContext2D.js
-swingjs/api/js/JSInterface.js
-swingjs/jquery/JQueryUI.js
-swingjs/JSApp.js
-swingjs/JSAppletThread.js
-swingjs/JSAppletViewer.js
-swingjs/JSFocusPeer.js
-swingjs/JSFontMetrics.js
-swingjs/JSFrameViewer.js
-swingjs/JSGraphics2D.js
-swingjs/JSGraphicsConfiguration.js
-swingjs/JSGraphicsEnvironment.js
-swingjs/JSImage.js
-swingjs/JSImagekit.js
-swingjs/JSMouse.js
-swingjs/JSNullComponentPeer.js
-swingjs/JSScreenDevice.js
-swingjs/JSThreadGroup.js
-swingjs/JSToolkit.js
-swingjs/JSUtil.js
-swingjs/plaf/ButtonListener.js
-swingjs/plaf/DefaultMenuLayout.js
-swingjs/plaf/HTML5LookAndFeel.js
-swingjs/plaf/JSAppletUI.js
-swingjs/plaf/JSButtonUI.js
-swingjs/plaf/JSCheckBoxMenuItemUI.js
-swingjs/plaf/JSCheckBoxUI.js
-swingjs/plaf/JSComboBoxUI.js
-swingjs/plaf/JSComponentUI.js
-swingjs/plaf/JSEventHandler.js
-swingjs/plaf/JSFrameUI.js
-swingjs/plaf/JSGraphicsUtils.js
-swingjs/plaf/JSLabelUI.js
-swingjs/plaf/JSLayeredPaneUI.js
-swingjs/plaf/JSLightweightUI.js
-swingjs/plaf/JSMenuBarUI.js
-swingjs/plaf/JSMenuItemUI.js
-swingjs/plaf/JSMenuUI.js
-swingjs/plaf/JSPanelUI.js
-swingjs/plaf/JSPopupMenuSeparatorUI.js
-swingjs/plaf/JSPopupMenuUI.js
-swingjs/plaf/JSRadioButtonMenuItemUI.js
-swingjs/plaf/JSRadioButtonUI.js
-swingjs/plaf/JSRootPaneUI.js
-swingjs/plaf/JSScrollBarUI.js
-swingjs/plaf/JSScrollPaneUI.js
-swingjs/plaf/JSSeparatorUI.js
-swingjs/plaf/JSSliderUI.js
-swingjs/plaf/JSTextAreaUI.js
-swingjs/plaf/JSTextFieldUI.js
-swingjs/plaf/JSTextUI.js
-swingjs/plaf/JSTextViewUI.js
-swingjs/plaf/JSViewportUI.js
-swingjs/plaf/JSWindowUI.js
-swingjs/plaf/LazyActionMap.js
-swingjs/plaf/Resizer.js
-swingjs/plaf/TextListener.js
-
-
+++ /dev/null
-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
-
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="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<Object,PRESENT>:
-
- [HashSet] makes no guarantees as to the iteration order of the set.
-
-JavaScript's Map object is different. It is basically a LinkedHashMap, so it guarantees iteration
-in order of object addition.
-
-Starting with java2script 3.2.9.v1, these classes use the JavaScript Map object rather than hash codes
-whenever all keys are strictly of JavaScript typeof "string". If any key is introduced that is not a string, the
-implementation falls back to using hash codes, the same as Java.
-
-Note strings created using new String("xxxx") are NOT typeof "string"; they are typeof "object".
-
-The result is significantly faster performance (3-12 x faster) than originally, and up to 3 x faster
-performance in JavaScript than in Java itself. Right. Faster than Java.
-
-The JavaScript Map implementation is implemented UNLESS the constructor used is the one that
-specifies both initial capacity and load factor in their constructor. Thus,
-
-new Hashtable()
-new HashMap()
-new HashMap(16)
-new HashSet()
-
-all use the JavaScript Map. But
-
-new Hashtable(11, 0.75f)
-new HashMap(16, 0.75f)
-new HashSet(16, 0.75f)
-
-do not.
-
-This design allows for opting out of the JavaScript Map use in order to retain the exact behavior of
-iterators in JavaScript as in Java.
-
-
-interning, new String("xxx") vs "xxx"
--------------------------------------
-
-Note that the following are true in JavaScript:
-
-typeof new String("xxxx") == "object"
-typeof "xxxx" == "string"
-var s = "x";typeof ("xxx" + s) == "string"
-
-There is no equivalence to this behavior in Java, where a String is a String is a String.
-
-Be aware that SwingJS does not always create a JavaScript String object using JavaScript's
-new String(...) constructor. It only does this for Java new String("xxxx") or new String(new String()).
-
-In all other cases, new String(...) (in Java) results in a simple "xxxx" string in JavaScript.
-That is, it will be JavaScript typeof "string", not typeof "object".
-
-The reason for this design is that several classes in the Java core use toString()
-methods that return new String(), and those classes that do that would cause a JavaScript error
-if implicitly stringified if new String() returned a JavaScript String object.
-
-This is fine in JavaScript
-
-test1 = function() { return { toString:function(){ return "OK" } } }
-"testing" + new test1()
->> "testingOK"
-
-But for whatever reason in JavaScript:
-
-test2 = function() { return { toString:function(){ return new String("OK") } } }
-"testing" + new test2()
->> Uncaught TypeError: Cannot convert object to primitive value
-
-The lesson here is never to use
-
- return new String("...");
-
-in a Java toString() method. In Java it will be fine; in JavaScript it will also be fine as long as
-that method is never called in JavaScript implicitly in the context of string concatenation.
-
-A note about interning. Consider the following six Java constructions, where we have a == "x";
-
-"xxx"
-"xx" + "x"
-new String("xxx").intern()
-
-new String("xxx")
-"xx" + a.toString()
-"xx" + a
-
-All six of these will return java.lang.String for .getClass().getName().
-However, the first three are String literals, while the last three are String objects.
-Thus:
- "xxx" == "xxx"
- "xxx" == "xx" + "x"
- "xxx" == new String("xxx").intern()
-
-but none of the other three are equivalent to "xxx" or each other:
-
- "xxx" != new String("xxx")
- "xxx" != "xx" + a.toString()
- "xxx" != "xx" + a
- new String("xxx") != new String("xxx")
- "xx" + a != new String("xxx")
-
-etc.
-
-As in Java, in SwingJS, all of the following Java assertions pass as true:
-
- assert("xxx" == "xx" + "x");
- assert("xxx" == ("xx" + a).intern());
- assert("xxx" === new String("xxx").intern());
-
-and both of these do as well:
-
- assert(new String("xxx") != "xxx");
- assert(new String("xxx") != new String("xxx"));
-
-But the following two fail to assert true:
-
- assert("xxx" != "xx" + a);
- assert("xxx" != "xx" + a.toString());
-
-because in JavaScript, both of these right-side expressions evaluate to a simple "interned" string.
-
-In Java, however, these assertions are true because Java implicitly "boxes" String
-concatentaion as a String object, not a literal.
-
-Most of us know not to generally use == with Strings unless they are explicitly interned.
-Where this problem may arise, though, is in IdentityHashMap, which compares objects using
-System.identityHashCode(), which is not the same for different objects or their string literal equivalents.
-
-My recommendation, if you need to use IdentityHashMap with strings is to always use an explicit String.intern()
-for any keys -- unless you really want to keep every string as separate keys even if they are the same sequence,
-in which case, use new String(). This will work in Java and in JavaScript.
-
-Be aware when working with strings that come from SwingJS and are being used by other JavaScript modules
-that those that are String objects will return "object" for the JavaScript typeof operator, not "string".
-
-The easy way to ensure this is no problem is to concatenate strings with "" to force immediate interning:
-
- var x = aJavaObject.getString() + "";
-
-unless you are certain that the string is being returned is a raw JavaScript string.
-
-Names with "$" and "_"
-----------------------
-
-For the most part, this should be no problem.
-
-Note that the use of $ and _ in Java field names has always been discouraged:
-[https://docs.oracle.com/javase/tutorial/java/nutsandbolts/variables.html]
-
- You may find some situations where auto-generated names will contain the dollar sign,
- but your variable names should always avoid using it. A similar convention
- exists for the underscore character; while it's technically legal to begin your
- variable's name with "_", this practice is discouraged.
-
-Some impacts of transpiling method names with full qualification:
-
-1) SwingJS will introduce fields that start with $ or _. These will not conflict
- if the above convention is followed.
-
-2) Fields that have the same Java name as a method are not an issue.
-
-3) Fields that have a Java name with $ that matches a transpiled method name,
- such as toString$, will need to be refactored in Java to not have that name collision.
-
-4) Fields in a subclass that have the same name as private fields in a superclass
- represent a name collision, because the superclass method needs to call its private
- field even if invoked from a subclass. The solution was to modify the subclass field
- name using one or more prepended $.
-
-5) Use of Class.getDeclaredMethods() reflection will return Method objects having the transpiled
- name, not the Java name. This could require some j2sNative adjustment
- to strip the $... parameters from the name if that is needed.
-
-6) Use of Method.getParameterTypes() should work fine, provided class names
- do not contain "_". This is because the transpiler converts "." to "_" when
- creating the fully qualified JavaScript name.
-
-
-positive integers do not add to give negative numbers
------------------------------------------------------
-
-In Java, the following is true:
-
- 2000000000 + 2000000000 == -294967296
-
-But in SwingJS, that will be 4000000000. So, for example, the following
-strategy will fail in SwingJS:
-
- int newLength = lineBuf.length * 2;
- if (newLength < 0) {
- newLength = Integer.MAX_VALUE;
- }
-
-"-1" in JavaScript is not 0xFFFFFFFF.
-
-And one must take care to not compare a negative number with a 32-bit mask. So
-
-(b & 0xFF000000) == 0xFF000000
-
-is true in Java for (int) b = -1, but is false in JavaScript, because 0xFF000000 is 4278190080,
-while (-1 & 0xFF000000) is, strangely enough, -16777216, and, in fact,
-
-(0xFF000000 & 0xFF000000) != 0xFF000000
-
-because -16777216 is not 4278190080.
-
-The fix is that one must compare similar operations:
-
-if ((b & 0xFF000000) == (0xFF000000 & 0xFF000000)) .....
-
-Importantly, the JavaScript Int32Array does behave properly. From
-the Firefox developer console:
-
->> x = new Int32Array(1)
-<- Int32Array(1) [ 0 ]
->> x[0] = 4000000000
-<- 4000000000
->> x[0]
-<- -294967296
-
-Notice that, perhaps unexpectedly, the following two constructs produce
-different results in JavaScript:
-
-x = new Int32Array(1);
-b = x[0] = 4000000000;
-
-(b will be 4000000000)
-
-and
-
-x = new Int32Array(1);
-x[0] = 4000000000;
-b = x[0];
-
-(b will be -294967296)
-
-
-SwingJS leverages array typing to handle all byte and short arithmetic so as
-to ensure that any byte or short operation in JavaScript does give the same
-result in Java. The design decision to not also do this with integer math was
-a trade-off between performance and handling edge cases.
-
-
-ArrayIndexOutOfBounds
----------------------
-
-You cannot implicitly throw an ArrayIndexOutOfBoundsException in JavaScript.
-JavaScript will simply return "undefined", not throw an Exception. So:
-
-boolean notAGoodIdeaIsOutOfBounds(String[] sa, int i) {
- try {
- return (sa[i] == sa[i]);
- } catch (ArrayIndexOutOfBoundsException e) {
- return false;
- }
-}
-
-will work in Java but not in JavaScript. Code should not depend upon this sort
-of trap anyway, if you ask me.
-
-Throwable vs Error vs Exception
--------------------------------
-
-True JavaScript errors are trapped as Throwable, whereas you can still trap
-Error and Exception as well. So if you want to be sure to catch any JavaScript
-error, use try{}catch (Throwable t){}, not try{}catch (Exception e){}.
-
-j
-ava.awt.Color
---------------
-
-ColorSpace: only "support" CS_sRGB.
-
- TODO -- any volunteers??
-
-
-javax.swing.JFileDialog
------------------------
-
-HTML5 cannot expose a file reading directory structure. But you certainly
-can still do file reading and writing. It just works a little differently.
-It's a simple modification:
-
- b = new JButton("FileOpenDialog");
- b.addActionListener(new ActionListener() {
-
- @Override
- public void actionPerformed(ActionEvent e) {
- JFileChooser fc = new JFileChooser();
- Test_Dialog.this.onDialogReturn(fc.showOpenDialog(Test_Dialog.this));
- // Java will wait until the dialog is closed, then enter the onDialogReturn method.
- // JavaScript will exit with NaN immediately, and then call back with its actual value
- // asynchronously.
- }
-
- });
-
- public void onDialogReturn(int value) {
- if (value != Math.floor(value))
- return; // in JavaScript, this will be NaN, indicating the dialog has been opened
- // If we are here, the dialog has closed, in both Java and JavaScript.
- System.out.println("int value is " + value);
- }
-
-
- @Override
- public void propertyChange(PropertyChangeEvent event) {
- Object val = event.getNewValue();
- String name = event.getPropertyName();
- System.out.println(name);
- switch (event.getSource().getClass().getName()) {
- case "javax.swing.JOptionPane":
- switch (name) {
- case "inputValue":
- onDialogReturn(val);
- return;
- case "value":
- if (val instanceof Integer)
- onDialogReturn(((Integer) val).intValue());
- else
- onDialogReturn(val);
- return;
- }
- break;
- case "javax.swing.ColorChooserDialog":
- switch (name) {
- case "SelectedColor":
- onDialogReturn(val);
- return;
- }
- break;
- case "javax.swing.JFileChooser":
- switch (name) {
- case "SelectedFile":
- File file = (File) val;
- byte[] array = (val == null ? null : /** @j2sNative file.秘bytes || */
- null);
- onDialogReturn("fileName is '" + file.getName() + "'\n\n" + new String(array));
- return;
- }
- break;
- }
- System.out.println(
- event.getSource().getClass().getName() + " " + event.getPropertyName() + ": " + event.getNewValue());
- }
-
-
-Developers are encouraged to create a separate class that handles general calls to JFileDialog.
-An example class can be found in the SwingJS distribution as
-
-/sources/net.sf.j2s.java.core/src/javajs/async/AsyncFileChooser.java.
-
-
-javax.swing.JOptionPane dialogs
--------------------------------
-
-For this action to work, the parentComponent must implement
-propertyChangeListener, and any call to JOptionPanel should allow for
-an asynchronous response, meaning that there is no actionable code following the
-call to the dialog opening.
-
-In addition, for compatibility with the Java version, implementation should
-wrap the call to getConfirmDialog or getOptionDialog in a method call to
-handle the Java:
-
-onDialogReturn(JOptionPane.showConfirmDialog(parentFrame,
-messageOrMessagePanel, "title", JOptionPane.OK_CANCEL_OPTION));
-
-Then parentFrame.propertyChange(event) should also call onDialogReturn.
-
-This will then work in both Java and JavaScript.
-
-Note that there is an int and an Object version of onDialogReturn().
-
-
-In JavaScript:
-
-The initial return from JOptionPane.showConfirmDialog and showMessageDialog
-will be (SwingJS) JDialog.ASYNCHRONOUS_INTEGER (NaN), testable as an impossible
-Java int value using ret != -(-ret) if the parent implements PropertyChangeListener, or -1
-(CLOSE_OPTION) if not.
-
-For showOptionDialog (which returns Object) or showInputDialog (which returns
-String), the initial return will be (SwingJS) JDialog.ASYNCHRONOUS_OBJECT, testable as
-((Object) ret) instanceof javax.swing.plaf.UIResource if the parent implements
-PropertyChangeListeneer, or null if not.
-
-The second return will be the desired return.
-
-In Java:
-
-The initial return will be the one and only modal final return.
-
-
-
-For full compatibility, The calling method must not continue beyond this
-call.
-
-All of the standard Java events associated with Components are also
-available.
-
-Certain fall back mechanisms are possible, where onReturn does not exist, but
-only for the following cases:
-
-
-For showMessageDialog, for WARNING_MESSAGE and ERROR_MESSAGE, a simple
-JavaScript alert() is used, returning 0 (OK_OPTION) or -1 (CLOSED_OPTION).
-
-For showInputDialog, if the message is a string, a simple JavaScript prompt()
-with input box is used, returning the entered string or null.
-
-For showConfirmDialog, a simple JavaScript confirm() is used, in which case:
-
-for YES_NO_OPTION: YES_OPTION or NO_OPTION
-
-for YES_NO_CANCEL_OPTION: YES_OPTION or CANCEL_OPTION
-
-for OK_CANCEL_OPTION or any other: OK_OPTION or CANCEL_OPTION
-
-Note that you should implement a response for CLOSED_OPTION for
-showConfirmDialog. For other dialogs, a null return indicates the dialog was
-closed, just as for Java.
-
-Developers are encouraged to create a separate class that handles general calls.
-An example class can be found in the SwingJS distribution as src/javajs/async/AsyncDialog.java.
-Very simple modifications to the Java allows asynchronous operation using AsyncDialog. Here
-is a simple "do you want to close this frame" example, where you can see that what we have
-done is to set the reply into an ActionListener that is defined in the constructor of
-the AsyncDisplay object:
-
-// Original:
-//
-// private void promptQuit() {
-// int sel = JOptionPane.showConfirmDialog(null, PROMPT_EXIT, NAME, JOptionPane.YES_NO_OPTION);
-// switch (sel) {
-// case JOptionPane.YES_OPTION:
-// resultsTab.clean();
-// seqs.dispose();
-// if (fromMain) {
-// System.exit(0);
-// }
-// break;
-// }
-// }
-
- private void promptQuitAsync() {
- new AsyncDialog(new ActionListener() {
-
- @Override
- public void actionPerformed(ActionEvent e) {
- int sel = ((AsyncDialog)e.getSource()).getOption();
- switch (sel) {
- case JOptionPane.YES_OPTION:
- resultsTab.clean();
- seqs.dispose();
- if (fromMain) {
- System.exit(0);
- }
- break;
- }
- }}).showConfirmDialog(null, PROMPT_EXIT, NAME, JOptionPane.YES_NO_OPTION);
- }
-
-Very simple!
-
-
-native methods
---------------
-
-The J2S compiler ignores all static native method declarations.
-Anything of this nature needs to be implemented in JavaScript if it is needed,
-using j2sNative blocks:
-
-/**
- * @j2sNative
- *
- * var putYourJavaScriptCodeHere
- *
- */
-
- Note that if you follow that directly with a {...} block, then
- the javadoc code will run in JavaScript, and the {...} code will run in Java.
-
-
-key Focus
----------
-
-As of June, 2019, the keyboard focus manager is fully implemented.
-The one catch is that JTextPane and JTextArea, which already consume
-VK_TAB in Java, cannot use CTRL-TAB to continue a tabbing cycle around
-the components in a window. Instead, CTRL-TAB is absorbed by the browser.
-
-
-LookAndFeel and UI Classes
---------------------------
-
-SwingJS implements the native browser look and feel as swingjs.plaf.HTML5LookAndFeel.
-There are small differences between all look and feels -- MacOS, Windows, SwingJS.
-
-Expert developers know how to coerce changes in the UI by subclassing the UI for a
-component. This probably will not work in SwingJS.
-
-Note that LookAndFeel in Java usually determines canvas size in a Frame because
-different operating systems (Mac OS vs Windows vs HTML5) will have
-different edge sizes on their frames. If you want to ensure a component size,
-use getContentPane().setPreferredSize().
-
-
-System.exit(0) does not stop all processes
-------------------------------------------
-
-Although System.ext(int) has been implemented in JavaScript, it just closes the
-frames, stops all pending javax.swing.Timer objects in the queue, and runs any
-threads added using Runtime.getRuntime().addShutdownHook(Thread).
-It may not stop all "threads." So don't rely on that.
-Applications are responsible for shutting down prior to executing System.exit(0).
-
-
-myClass.getField not implemented
---------------------------------
-
-java.lang.reflect.Field is implemented minimally. It is not
-certain that Field.getDeclaringClass() will work. If you just want a
-value of a field, you can do this:
-
-/**
- *@j2sNative
- *
- * return myClass[name]
- */
-
-But that is not a java.lang.reflection.Field object.
-
-
-"window" and other reserved JavaScript names
---------------------------------------------
-
-No reserved top-level JavaScript name is allowed for a package name. So, for example,
-one must rename packages such as "window" or "document" to names such as "win" or "doc".
-
-reserved field and method names
--------------------------------
-
-In order to minimize the chance of added SwingJS field and method names colliding with ones
-developers might use in subclassing Java classes, we have added U+79D8 (first character of Mandarin
-"secret") to the characters already disrecommended by Java documentation ("$" and "_"). The only problem
-would be if you use that character followed by certain English words in certain classes. For example
-\u79D8canvas for JComponents (in java.awt.JSComponent) and \u79D8byte (in java.io.File).
-
-qualified field and method names
---------------------------------
-
-Method names in SwingJS are fully qualified, meaning two methods with the same Java name but different
-parameters, such as write(int) and write(double), must not have the same name in JavaScript. (In this
-case, we will have write$I and write$D.) However, in certain cases it may be desirable to leave the
-method names unqualified. In particular, when an interface actually represents a JavaScript object,
-the transpiler can leave a method name unqualified. The default situation for this is a class name
-includes ".api.js" (case-sensitive). This means that any method in any class in a package js within
-a package api, or any private interface js that has an outer interface api, will have all-unqualified
-methods. An example of this is swingjs.plaf.JSComboPopupList, which needs to communicate with a jQuery
-object directly using the following interface:
-
- private interface api {
-
- interface js extends JQueryObject {
-
- abstract js j2sCB(Object options);
-
- abstract Object[] j2sCB(String method);
-
- abstract Object[] j2sCB(String method, Object o);
-
- abstract Object[] j2sCB(String method, int i);
-
- abstract int j2sCB(String OPTION, String name);
-
- }
- }
-
-Notice that all these variants of j2sCB() will call the same method in JavaScript by design.
-
-
-missing Math methods
---------------------
-
-java.lang.Math is worked out, but some methods are missing, either because they
-involve long integer value that are inaccessible in JavaScript, or because I just
-didn't implement them. This is a result of continued Java development.
-It is easy enough to add these methods if you have the source. They go into j2sClazz.js,
-which is combined with other initial libraries into swingjs2.js by build_site.xml
-
-
-Component.getGraphics(), Graphics.dispose()
--------------------------------------------
-
-Use of component.getGraphics() is discouraged in Java and in SwingJS.
-Specifically in SwingJS, any call to component.getGraphics() or
-BufferedImage.createGraphics() or Graphics.create(...) should be matched with graphics.dispose(),
-particularly when it is called outside the context of a paint(Graphics)
-call from the system.
-
-If you see your graphics scrolling down the page with each repaint,
-look for where you have used Component.getGraphics() and not Graphics.dispose().
-For example, this will definitely NOT work in SwingJS:
-
- this.paint(getGraphics())
-
-and really should not work in Java, either, as it is technically a resource memory leak.
-
-Instead, if you really do not want to use repaint(), use this:
-
- Graphics g = getGraphics();
- paint(g);
- g.dispose();
-
-
-
-Graphics.setClip()
-------------------
-
-The HTML5 canvas.clip() method is permanent. You can only reset the clip using
-save/restore. This is different from Java, where you can temporarily change it using
-
- Shape oldClip = Graphics.getClip();
- Graphics.setClip(newClip);
- ...
- Graphics.setClip(oldClip);
-
-If you need to do something like this, you must schedule the paints
-to not have overlapping clip needs.
-
-
-MAJOR ISSUES--for Bob and Udo within SwingJS
-============================================
-
-fonts
------
-
-Fonts and FontMetrics will all be handled in JavaScript. Font matching will
-not be exact, and composite (drawn) fonts will not be supported.
-
-SwingJS handles calls such as font.getFontMetrics(g).stringWidth("xxx") by
-creating a <div> containing that text, placing it in an obscure location on
-the page, and reading div.getBoundingClientRect(). This is a VERY precise
-value, but can be a pixel or two off from what Java reports for the same font.
-
-
-OS-dependent classes
---------------------
-
-Static classes such as:
-
- java.awt.Toolkit
- java.awt.GraphicsEnvironment
-
-
-which are created using Class.forName are implemented using classes in the swingjs package.
-
-AWTAccessor is not implemented.
-
-
-AWT component peers and component "ui" user interfaces
-------------------------------------------------------
-
-ComponentPeer is a class that represents a native AWT component.
-Components with such peers are called "heavy-weight" components.
-They are expected to do the dirty work of graphics drawing.
-
-Java Swing implements peers only for JApplet, JDialog, JFrame, and JWindow.
-References to such objects have been removed, but clearly there must be
-some connection to similar DOM objects, even for "light-weight" components.
-
-
-
-MAJOR ISSUES--to be resolved by implementers
-============================================
-
-fonts
------
-
-Glyph/composite/outline fonts are not supported.
-
-
-
-threads
--------
-
-Thread locking and synchronization are not relevant to JavaScript.
-Thus, anything requiring "notify.." or "waitFor.." could be a serious issue.
-
-All threading must be "faked" in JavaScript. Specifically not available is:
-
- Thread.sleep()
-
-javax.swing.AbstractButton#doClick(pressTime) will not work, as it requires Thread.sleep();
-
-However, java.lang.Thread itself is implemented and used extensively.
-
-Methods thread.start() and thread.run() both work fine.
-
-For simple applications that use Thread.sleep() just to have a delay, as in a frame rate, for
-example, one can use javax.swing.Timer instead. That is fully implemented.
-
-Likewise, java.util.Timer can be replaced with no loss of performance with javax.Swing.Timer.
-Note that java.util.TimerTask is implemented, but it can also be replaced by an implementation of Runnable.
-
-task = new TimerTask(){....};
-t = new java.util.Timer();
-t.schedule(task, 0, 1);
-
-becomes
-
-task = new TimerTask(){....}; // or task = new Runnable() {...}
-t = new javax.swing.Timer(1, new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- task.run();
- }
-};
-t.setInitialDelay(0); // not particularly necessary
-t.start();
-
-In addition, SwingJS provides swingjs.JSThread, which can be subclassed
-if desired. This class allows simple
-
- while(!interrupted()){
- wait()
- ...
- }
-
-action through an asynchronous function run1(mode). For example:
-
- protected void run1(int mode) {
- try {
- while (true)
- switch (mode) {
- case INIT:
- // once-through stuff here
- mode = LOOP;
- break;
- case LOOP:
- if (!doDispatch || isInterrupted()) {
- mode = DONE;
- } else {
- Runnable r = new Runnable() {
- public void run() {
- // put the loop code here
- }
- };
- dispatchAndReturn(r);
- if (isJS)
- return;
- }
- break;
- // add more cases as needed
- case DONE:
- // finish up here
- if (isInterrupted())
- return;
- // or here
- break;
- }
- } finally {
- // stuff here to be executed after each loop in JS or at the end in Java
- }
- }
-
-image loading
--------------
-- All image loading in SwingJS is synchronous. A MediaTracker call will immediately return "complete".
- However, it still may take one system clock tick to fully load images. Thus, it is recommended that
- images be preloaded in the static block of the applet if it is necessary that they be available in init().
- This is only an issue if you are trying to access the pixel buffer of the image in JavaScript.
-
-- Applet.getImage(path, name) will return null if the image does not exist.
-
-- BufferedImage: only "support" imageType RGB and ARGB
-
- -BH: This is a temporary edit, just to get us started. Certainly GRAY will be needed
-
-
-BigInteger and BigDecimal
--------------------------
-
-java.math.BigInteger is fully supported; java.math.BigDecimal is roughed
-in and not fully tested (07/2019).
-
-Both classes present significant issues for JavaScript, as they are based in
-Java's 64-bit long for all their operations. Here is the JavaDoc note I added
-to BigInteger:
-
- * SwingJS note: Because of the limitations of JavaScript with regard
- * to long-integer bit storage as a double, this implementation drops
- * the integer storage bit length to 24, giving 48 for long and leaving
- * the last 16 bits clear for the exponent of the double number. This should
- * not affect performance significantly. It does increase the storage
- * size by about 33%. By bringing an "int" to 3 bytes, we can easily construct
- * and use byte[] data intended for the original BitSet.
-
-"Easily" may be a bit strong there. This was a serious challenge.
-
-BigDecimal seems to run normally, but in order to do that, my hack involves
-reducing the size of an integer that is allowed to be stored as such and not
-in byte[] as a BigInteger. I'm sure there is a performance hit, but it does work.
-
-no format internationalization
-------------------------------
-
-For now, just en for number and date formatters
-
-no winding rules
-----------------
-
- When filling a graphic, only nonzero winding rule is implemented in HTML5 Canvas2D.
-
-
-
-text-related field implementation
----------------------------------
-
-Text fields are:
-
-JTextField (JavaScript <input type="text">)
-JTextArea (JavaScript <textarea>)
-JTextPane (JavaScript <div>)
-JEditorPane (JavaScript <div>)
-
-For the initial implementation, we don't implement infinite undo/redo, and the abstract
-document model is much less elaborate. Only PlainDocument (in the form of JSPlainDocument)
-is implemented. The Document returned by JTextField.getDocument() is a javax.swing.text.Document.
-
-All scrolling is handled by HTML5. javax.swing.AutoScroller is not implemented.
-public static methods .stop, .isRunning, .processMouseDragged require true Java threading
-and so are not implmented. javax.swing.text.View and its subclasses are not implemented.
-
-The JS document model does not allow two text fields to address the same underlying document.
-
-JavaScript is slightly different from Java in that the field value is changed asynchronously after
-the keypressed event, so Java actions that are keyed to KEY_PRESSED may not pick up the new
-key value even after SwingUtilities.invokeLater() is called. Thus, key pressed actions may need
-to be recorded after a key released event instead.
-
-Formatter/Regex limitations
----------------------------
-
-Some browsers cannot process Regex "look-behind" process such as (?<=\W)
-java.util.regex.Matcher and Pattern use JavaScript's RegExp object rather than
-the native Java object. These are not identical. Only flags /igm are supported.
-Matcher.start(groupID) is not supported.
-
-java.util.Formatter will function correctly for all standard %... patterns.
-
-integer 1/0 == Infinity
------------------------
-
-1/0 in Java throws "java.lang.ArithmeticException: / by zero", but in JavaScript is just Infinity.
-
-
-
-Summary
--------
-
-These are all the known limitations of SwingJS. We have not found any of these limitations
-to be show-stoppers. The primary issue for newcomers to SwingJS is having the source code.
-You must check that source code for all your library jar files is available or, if you
-choose, you will need to decompile those classes. We have used decompilation on some projects,
-and it works just fine. So, technically, all we really need are JAR/class files. But the
-source is by far superior. It's generally prettier, and it has the license information that
-may or may not be present with the JAR or class files. Use class files at your own risk.
-
-Bob Hanson
-2019.08.16
-
-
-Additional Issues
------------------
-
-Annotation is working for classes, methods, and fields (12/22/19). Method reflection, however,
-is limited. Interfaces do not expose their methods, as the transpiler does not actually transpile
-the interfaces themselves. And method reflection only includes annotated methods.
-
-java.util.concurrent is not fully elaborated. This package is rewritten to not actually use the
-memory handling capabilities of concurrency, which JavaScript does not have access to.
-
-System.getProperties() just returns a minimal set of properties.
-
-
+++ /dev/null
-20201219150605
java2script/SwingJS Notes
=========================
+updated 3/11/2023 -- adds support for Java Regex Matcher.start/end(groupID) and .start/end(groupName)
updated 12/31/2020 -- full support for 64-bit long
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
Some browsers cannot process Regex "look-behind" process such as (?<=\W)
java.util.regex.Matcher and Pattern use JavaScript's RegExp object rather than
the native Java object. These are not identical. Only flags /igm are supported.
-Matcher.start(groupID) is not supported.
+Matcher.start(groupID)/.end(groupID) is supported.
+(x*)? failure returns null, not empty string.
java.util.Formatter will function correctly for all standard %... patterns.
-20230210093656
+20230831104534
+++ /dev/null
-This is sources/net.sf.j2s.java.core/dist/DEV_NOTES.txt
-
-_j2sclasslist.txt
-
-the list of .js files concatenated into coreswingjs.js and minified to coreswingjs.z.js
-
-
-SwingJS-site.zip
-
-the full site directory for SwingJS including all files not in the test/ directory.
+++ /dev/null
-This directory holds 3.2.9 transpiler and runtime tagged previous
-to the transpiler fix for boxed number direct manipulation:
-
-Long L = Long.valueOf(3);
-L++;
-L /= 2;
-L += 10;
-L = L / 5;
-
-etc.
-
-These assignments are not made properly and fail.
-
-In addition, this runtime does not handle Long properly and also had an issue with Short.equals(Object)
-
-just saving this and will probably delete it.
-
+++ /dev/null
-java/applet/Applet.js
-java/applet/AppletContext.js
-java/applet/AppletStub.js
-java/applet/JSApplet.js
-java/awt/ActiveEvent.js
-java/awt/Adjustable.js
-java/awt/AWTEvent.js
-java/awt/AWTEventMulticaster.js
-java/awt/AWTKeyStroke.js
-java/awt/BasicStroke.js
-java/awt/BorderLayout.js
-java/awt/Button.js
-java/awt/Color.js
-java/awt/color/ColorSpace.js
-java/awt/Component.js
-java/awt/ComponentOrientation.js
-java/awt/ContainerOrderFocusTraversalPolicy.js
-java/awt/Container.js
-java/awt/Cursor.js
-java/awt/DefaultFocusTraversalPolicy.js
-java/awt/DefaultKeyboardFocusManager.js
-java/awt/Dialog.js
-java/awt/Dimension.js
-java/awt/dnd/peer/DropTargetPeer.js
-java/awt/event/ActionListener.js
-java/awt/event/AdjustmentEvent.js
-java/awt/event/AdjustmentListener.js
-java/awt/event/AWTEventListener.js
-java/awt/event/ComponentAdapter.js
-java/awt/event/ComponentEvent.js
-java/awt/event/ComponentListener.js
-java/awt/event/ContainerListener.js
-java/awt/event/FocusEvent.js
-java/awt/event/FocusListener.js
-java/awt/event/HierarchyBoundsListener.js
-java/awt/event/HierarchyListener.js
-java/awt/event/InputEvent.js
-java/awt/event/InputMethodListener.js
-java/awt/event/InvocationEvent.js
-java/awt/event/ItemEvent.js
-java/awt/event/ItemListener.js
-java/awt/event/KeyListener.js
-java/awt/event/MouseEvent.js
-java/awt/event/MouseListener.js
-java/awt/event/MouseMotionListener.js
-java/awt/event/MouseWheelListener.js
-java/awt/event/TextListener.js
-java/awt/event/WindowAdapter.js
-java/awt/event/WindowEvent.js
-java/awt/event/WindowFocusListener.js
-java/awt/event/WindowListener.js
-java/awt/event/WindowStateListener.js
-java/awt/EventDispatchThread.js
-java/awt/EventFilter.js
-java/awt/EventQueue.js
-java/awt/EventQueueItem.js
-java/awt/FlowLayout.js
-java/awt/FocusTraversalPolicy.js
-java/awt/Font.js
-java/awt/font/FontRenderContext.js
-java/awt/FontMetrics.js
-java/awt/Frame.js
-java/awt/geom/AffineTransform.js
-java/awt/geom/Dimension2D.js
-java/awt/geom/Path2D.js
-java/awt/geom/PathIterator.js
-java/awt/geom/Point2D.js
-java/awt/geom/Rectangle2D.js
-java/awt/geom/RectangularShape.js
-java/awt/geom/RectIterator.js
-java/awt/GraphicsCallback.js
-java/awt/GraphicsConfiguration.js
-java/awt/GraphicsDevice.js
-java/awt/GraphicsEnvironment.js
-java/awt/Image.js
-java/awt/image/ImageObserver.js
-java/awt/Insets.js
-java/awt/ItemSelectable.js
-java/awt/JSComponent.js
-java/awt/JSDialog.js
-java/awt/JSFrame.js
-java/awt/JSPanel.js
-java/awt/KeyboardFocusManager.js
-java/awt/KeyEventDispatcher.js
-java/awt/KeyEventPostProcessor.js
-java/awt/Label.js
-java/awt/LayoutManager.js
-java/awt/LayoutManager2.js
-java/awt/LightweightDispatcher.js
-java/awt/Paint.js
-java/awt/Panel.js
-java/awt/peer/ComponentPeer.js
-java/awt/peer/ContainerPeer.js
-java/awt/peer/FramePeer.js
-java/awt/peer/KeyboardFocusManagerPeer.js
-java/awt/peer/LightweightPeer.js
-java/awt/peer/WindowPeer.js
-java/awt/Point.js
-java/awt/Queue.js
-java/awt/Rectangle.js
-java/awt/RenderingHints.js
-java/awt/Scrollbar.js
-java/awt/ScrollPane.js
-java/awt/Shape.js
-java/awt/Stroke.js
-java/awt/TextArea.js
-java/awt/TextComponent.js
-java/awt/TextField.js
-java/awt/Toolkit.js
-java/awt/Transparency.js
-java/awt/Window.js
-java/beans/ChangeListenerMap.js
-java/beans/PropertyChangeEvent.js
-java/beans/PropertyChangeListener.js
-java/beans/PropertyChangeSupport.js
-java/lang/AbstractStringBuilder.js
-java/lang/Class.js
-java/lang/Enum.js
-java/lang/Iterable.js
-java/lang/reflect/Constructor.js
-java/lang/reflect/Method.js
-java/lang/StringBuffer.js
-java/lang/StringBuilder.js
-java/lang/Thread.js
-java/lang/ThreadGroup.js
-java/math/RoundingMode.js
-java/net/URL.js
-java/net/URLStreamHandlerFactory.js
-java/net/HttpURLConnection.js
-java/net/URLStreamHandler.js
-javax/net/ssl/HttpsUrlConnection.js
-java/text/CharacterIterator.js
-java/text/DecimalFormat.js
-java/text/DecimalFormatSymbols.js
-java/text/DigitList.js
-java/text/FieldPosition.js
-java/text/Format.js
-java/text/NumberFormat.js
-java/util/AbstractCollection.js
-java/util/AbstractList.js
-java/util/AbstractMap.js
-java/util/AbstractSequentialList.js
-java/util/AbstractSet.js
-java/util/ArrayList.js
-java/util/Arrays.js
-java/util/Collection.js
-java/util/Collections.js
-java/util/Comparator.js
-java/util/Deque.js
-java/util/Dictionary.js
-java/util/Enumeration.js
-java/util/EventListener.js
-java/util/EventObject.js
-java/util/HashMap.js
-java/util/HashSet.js
-java/util/Hashtable.js
-java/util/IdentityHashMap.js
-java/util/Iterator.js
-java/util/LinkedHashMap.js
-java/util/LinkedList.js
-java/util/List.js
-java/util/ListResourceBundle.js
-java/util/Locale.js
-java/util/Map.js
-java/util/Objects.js
-java/util/Queue.js
-java/util/Random.js
-java/util/RandomAccess.js
-java/util/ResourceBundle.js
-java/util/Set.js
-java/util/TimSort.js
-java/util/Vector.js
-javajs/api/JSFunction.js
-javajs/util/AjaxURLConnection.js
-javajs/util/AjaxURLStreamHandlerFactory.js
-javajs/util/AU.js
-javajs/util/JSThread.js
-javajs/util/Lst.js
-javajs/util/PT.js
-javajs/util/Rdr.js
-javajs/util/SB.js
-javax/swing/AbstractAction.js
-javax/swing/AbstractButton.js
-javax/swing/AbstractListModel.js
-javax/swing/Action.js
-javax/swing/ActionMap.js
-javax/swing/AncestorNotifier.js
-javax/swing/ArrayTable.js
-javax/swing/border/AbstractBorder.js
-javax/swing/border/BevelBorder.js
-javax/swing/border/Border.js
-javax/swing/border/CompoundBorder.js
-javax/swing/border/EmptyBorder.js
-javax/swing/border/EtchedBorder.js
-javax/swing/border/LineBorder.js
-javax/swing/border/TitledBorder.js
-javax/swing/BorderFactory.js
-javax/swing/BoundedRangeModel.js
-javax/swing/BoxLayout.js
-javax/swing/ButtonGroup.js
-javax/swing/ButtonModel.js
-javax/swing/ClientPropertyKey.js
-javax/swing/ComboBoxModel.js
-javax/swing/DefaultBoundedRangeModel.js
-javax/swing/DefaultButtonModel.js
-javax/swing/DefaultComboBoxModel.js
-javax/swing/DefaultSingleSelectionModel.js
-javax/swing/DropMode.js
-javax/swing/event/AncestorEvent.js
-javax/swing/event/AncestorListener.js
-javax/swing/event/CaretEvent.js
-javax/swing/event/CaretListener.js
-javax/swing/event/ChangeEvent.js
-javax/swing/event/ChangeListener.js
-javax/swing/event/DocumentEvent.js
-javax/swing/event/DocumentListener.js
-javax/swing/event/EventListenerList.js
-javax/swing/event/ListDataEvent.js
-javax/swing/event/ListDataListener.js
-javax/swing/event/UndoableEditEvent.js
-javax/swing/event/UndoableEditListener.js
-javax/swing/FocusManager.js
-javax/swing/InternalFrameFocusTraversalPolicy.js
-javax/swing/LayoutComparator.js
-javax/swing/LayoutFocusTraversalPolicy.js
-javax/swing/SortingFocusTraversalPolicy.js
-javax/swing/SwingContainerOrderFocusTraversalPolicy.js
-javax/swing/SwingDefaultFocusTraversalPolicy.js
-javax/swing/Icon.js
-javax/swing/ImageIcon.js
-javax/swing/InputMap.js
-javax/swing/JApplet.js
-javax/swing/JButton.js
-javax/swing/JCheckBox.js
-javax/swing/JCheckBoxMenuItem.js
-javax/swing/JComboBox.js
-javax/swing/JComponent.js
-javax/swing/JFrame.js
-javax/swing/JLabel.js
-javax/swing/JLayeredPane.js
-javax/swing/JMenu.js
-javax/swing/JMenuBar.js
-javax/swing/JMenuItem.js
-javax/swing/JPanel.js
-javax/swing/JPopupMenu.js
-javax/swing/JRadioButtonMenuItem.js
-javax/swing/JRootPane.js
-javax/swing/JScrollBar.js
-javax/swing/JScrollPane.js
-javax/swing/JSeparator.js
-javax/swing/JTextArea.js
-javax/swing/JTextField.js
-javax/swing/JToggleButton.js
-javax/swing/JViewport.js
-javax/swing/KeyboardManager.js
-javax/swing/KeyStroke.js
-javax/swing/ListModel.js
-javax/swing/LookAndFeel.js
-javax/swing/MenuElement.js
-javax/swing/MutableComboBoxModel.js
-javax/swing/plaf/ActionMapUIResource.js
-javax/swing/plaf/basic/BasicBorders.js
-javax/swing/plaf/BorderUIResource.js
-javax/swing/plaf/ColorUIResource.js
-javax/swing/plaf/ComponentUI.js
-javax/swing/plaf/DimensionUIResource.js
-javax/swing/plaf/FontUIResource.js
-javax/swing/plaf/InputMapUIResource.js
-javax/swing/plaf/InsetsUIResource.js
-javax/swing/plaf/UIResource.js
-javax/swing/RepaintManager.js
-javax/swing/RootPaneContainer.js
-javax/swing/Scrollable.js
-javax/swing/ScrollPaneConstants.js
-javax/swing/ScrollPaneLayout.js
-javax/swing/SingleSelectionModel.js
-javax/swing/SizeRequirements.js
-javax/swing/SwingConstants.js
-javax/swing/SwingPaintEventDispatcher.js
-javax/swing/SwingUtilities.js
-javax/swing/text/AbstractDocument.js
-javax/swing/text/AttributeSet.js
-javax/swing/text/Caret.js
-javax/swing/text/DefaultCaret.js
-javax/swing/text/DefaultEditorKit.js
-javax/swing/text/Document.js
-javax/swing/text/EditorKit.js
-javax/swing/text/Element.js
-javax/swing/text/GapContent.js
-javax/swing/text/GapVector.js
-javax/swing/text/JTextComponent.js
-javax/swing/text/MutableAttributeSet.js
-javax/swing/text/PlainDocument.js
-javax/swing/text/PlainView.js
-javax/swing/text/Position.js
-javax/swing/text/Segment.js
-javax/swing/text/SegmentCache.js
-javax/swing/text/SimpleAttributeSet.js
-javax/swing/text/Style.js
-javax/swing/text/StyleConstants.js
-javax/swing/text/StyleContext.js
-javax/swing/text/TabExpander.js
-javax/swing/text/TextAction.js
-javax/swing/text/Utilities.js
-javax/swing/text/View.js
-javax/swing/tree/TreeNode.js
-javax/swing/UIDefaults.js
-javax/swing/UIManager.js
-javax/swing/undo/AbstractUndoableEdit.js
-javax/swing/undo/CompoundEdit.js
-javax/swing/undo/UndoableEdit.js
-javax/swing/ViewportLayout.js
-javax/swing/WindowConstants.js
-sun/awt/AppContext.js
-sun/awt/AWTAutoShutdown.js
-sun/awt/CausedFocusEvent.js
-sun/awt/ComponentFactory.js
-sun/awt/KeyboardFocusManagerPeerProvider.js
-sun/awt/MostRecentKeyValue.js
-sun/awt/MostRecentThreadAppContext.js
-sun/awt/PaintEventDispatcher.js
-sun/awt/PostEventQueue.js
-sun/awt/RequestFocusController.js
-sun/awt/SunToolkit.js
-sun/awt/WindowClosingListener.js
-sun/awt/WindowClosingSupport.js
-sun/awt/image/DataStealer.js
-sun/awt/image/IntegerComponentRaster.js
-sun/awt/image/IntegerInterleavedRaster.js
-sun/awt/image/SunWritableRaster.js
-sun/font/FontDesignMetrics.js
-sun/swing/DefaultLookup.js
-sun/swing/SwingLazyValue.js
-sun/text/resources/FormatData.js
-sun/text/resources/en/FormatData_en.js
-sun/util/resources/LocaleData.js
-sun/util/locale/BaseLocale.js
-sun/util/locale/LocaleUtils.js
-sun/util/locale/provider/LocaleProviderAdapter.js
-sun/util/locale/provider/LocaleDataMetaInfo.js
-swingjs/a2s/A2SContainer.js
-swingjs/a2s/A2SEvent.js
-swingjs/a2s/A2SListener.js
-swingjs/a2s/Applet.js
-swingjs/a2s/Button.js
-swingjs/a2s/Label.js
-swingjs/a2s/Panel.js
-swingjs/a2s/Scrollbar.js
-swingjs/a2s/ScrollPane.js
-swingjs/a2s/TextArea.js
-swingjs/a2s/TextField.js
-swingjs/api/Interface.js
-swingjs/api/js/DOMNode.js
-swingjs/api/js/HTML5CanvasContext2D.js
-swingjs/api/js/JSInterface.js
-swingjs/jquery/JQueryUI.js
-swingjs/JSApp.js
-swingjs/JSAppletThread.js
-swingjs/JSAppletViewer.js
-swingjs/JSFocusPeer.js
-swingjs/JSFontMetrics.js
-swingjs/JSFrameViewer.js
-swingjs/JSGraphics2D.js
-swingjs/JSGraphicsConfiguration.js
-swingjs/JSGraphicsEnvironment.js
-swingjs/JSImage.js
-swingjs/JSImagekit.js
-swingjs/JSMouse.js
-swingjs/JSNullComponentPeer.js
-swingjs/JSScreenDevice.js
-swingjs/JSThreadGroup.js
-swingjs/JSToolkit.js
-swingjs/JSUtil.js
-swingjs/plaf/ButtonListener.js
-swingjs/plaf/DefaultMenuLayout.js
-swingjs/plaf/HTML5LookAndFeel.js
-swingjs/plaf/JSAppletUI.js
-swingjs/plaf/JSButtonUI.js
-swingjs/plaf/JSCheckBoxMenuItemUI.js
-swingjs/plaf/JSCheckBoxUI.js
-swingjs/plaf/JSComboBoxUI.js
-swingjs/plaf/JSComponentUI.js
-swingjs/plaf/JSEventHandler.js
-swingjs/plaf/JSFrameUI.js
-swingjs/plaf/JSGraphicsUtils.js
-swingjs/plaf/JSLabelUI.js
-swingjs/plaf/JSLayeredPaneUI.js
-swingjs/plaf/JSLightweightUI.js
-swingjs/plaf/JSMenuBarUI.js
-swingjs/plaf/JSMenuItemUI.js
-swingjs/plaf/JSMenuUI.js
-swingjs/plaf/JSPanelUI.js
-swingjs/plaf/JSPopupMenuSeparatorUI.js
-swingjs/plaf/JSPopupMenuUI.js
-swingjs/plaf/JSRadioButtonMenuItemUI.js
-swingjs/plaf/JSRadioButtonUI.js
-swingjs/plaf/JSRootPaneUI.js
-swingjs/plaf/JSScrollBarUI.js
-swingjs/plaf/JSScrollPaneUI.js
-swingjs/plaf/JSSeparatorUI.js
-swingjs/plaf/JSSliderUI.js
-swingjs/plaf/JSTextAreaUI.js
-swingjs/plaf/JSTextFieldUI.js
-swingjs/plaf/JSTextUI.js
-swingjs/plaf/JSTextViewUI.js
-swingjs/plaf/JSViewportUI.js
-swingjs/plaf/JSWindowUI.js
-swingjs/plaf/LazyActionMap.js
-swingjs/plaf/Resizer.js
-swingjs/plaf/TextListener.js
-
-
+++ /dev/null
-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
-
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="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<Object,PRESENT>:
-
- [HashSet] makes no guarantees as to the iteration order of the set.
-
-JavaScript's Map object is different. It is basically a LinkedHashMap, so it guarantees iteration
-in order of object addition.
-
-Starting with java2script 3.2.9.v1, these classes use the JavaScript Map object rather than hash codes
-whenever all keys are strictly of JavaScript typeof "string". If any key is introduced that is not a string, the
-implementation falls back to using hash codes, the same as Java.
-
-Note strings created using new String("xxxx") are NOT typeof "string"; they are typeof "object".
-
-The result is significantly faster performance (3-12 x faster) than originally, and up to 3 x faster
-performance in JavaScript than in Java itself. Right. Faster than Java.
-
-The JavaScript Map implementation is implemented UNLESS the constructor used is the one that
-specifies both initial capacity and load factor in their constructor. Thus,
-
-new Hashtable()
-new HashMap()
-new HashMap(16)
-new HashSet()
-
-all use the JavaScript Map. But
-
-new Hashtable(11, 0.75f)
-new HashMap(16, 0.75f)
-new HashSet(16, 0.75f)
-
-do not.
-
-This design allows for opting out of the JavaScript Map use in order to retain the exact behavior of
-iterators in JavaScript as in Java.
-
-
-interning, new String("xxx") vs "xxx"
--------------------------------------
-
-Note that the following are true in JavaScript:
-
-typeof new String("xxxx") == "object"
-typeof "xxxx" == "string"
-var s = "x";typeof ("xxx" + s) == "string"
-
-There is no equivalence to this behavior in Java, where a String is a String is a String.
-
-Be aware that SwingJS does not always create a JavaScript String object using JavaScript's
-new String(...) constructor. It only does this for Java new String("xxxx") or new String(new String()).
-
-In all other cases, new String(...) (in Java) results in a simple "xxxx" string in JavaScript.
-That is, it will be JavaScript typeof "string", not typeof "object".
-
-The reason for this design is that several classes in the Java core use toString()
-methods that return new String(), and those classes that do that would cause a JavaScript error
-if implicitly stringified if new String() returned a JavaScript String object.
-
-This is fine in JavaScript
-
-test1 = function() { return { toString:function(){ return "OK" } } }
-"testing" + new test1()
->> "testingOK"
-
-But for whatever reason in JavaScript:
-
-test2 = function() { return { toString:function(){ return new String("OK") } } }
-"testing" + new test2()
->> Uncaught TypeError: Cannot convert object to primitive value
-
-The lesson here is never to use
-
- return new String("...");
-
-in a Java toString() method. In Java it will be fine; in JavaScript it will also be fine as long as
-that method is never called in JavaScript implicitly in the context of string concatenation.
-
-A note about interning. Consider the following six Java constructions, where we have a == "x";
-
-"xxx"
-"xx" + "x"
-new String("xxx").intern()
-
-new String("xxx")
-"xx" + a.toString()
-"xx" + a
-
-All six of these will return java.lang.String for .getClass().getName().
-However, the first three are String literals, while the last three are String objects.
-Thus:
- "xxx" == "xxx"
- "xxx" == "xx" + "x"
- "xxx" == new String("xxx").intern()
-
-but none of the other three are equivalent to "xxx" or each other:
-
- "xxx" != new String("xxx")
- "xxx" != "xx" + a.toString()
- "xxx" != "xx" + a
- new String("xxx") != new String("xxx")
- "xx" + a != new String("xxx")
-
-etc.
-
-As in Java, in SwingJS, all of the following Java assertions pass as true:
-
- assert("xxx" == "xx" + "x");
- assert("xxx" == ("xx" + a).intern());
- assert("xxx" === new String("xxx").intern());
-
-and both of these do as well:
-
- assert(new String("xxx") != "xxx");
- assert(new String("xxx") != new String("xxx"));
-
-But the following two fail to assert true:
-
- assert("xxx" != "xx" + a);
- assert("xxx" != "xx" + a.toString());
-
-because in JavaScript, both of these right-side expressions evaluate to a simple "interned" string.
-
-In Java, however, these assertions are true because Java implicitly "boxes" String
-concatentaion as a String object, not a literal.
-
-Most of us know not to generally use == with Strings unless they are explicitly interned.
-Where this problem may arise, though, is in IdentityHashMap, which compares objects using
-System.identityHashCode(), which is not the same for different objects or their string literal equivalents.
-
-My recommendation, if you need to use IdentityHashMap with strings is to always use an explicit String.intern()
-for any keys -- unless you really want to keep every string as separate keys even if they are the same sequence,
-in which case, use new String(). This will work in Java and in JavaScript.
-
-Be aware when working with strings that come from SwingJS and are being used by other JavaScript modules
-that those that are String objects will return "object" for the JavaScript typeof operator, not "string".
-
-The easy way to ensure this is no problem is to concatenate strings with "" to force immediate interning:
-
- var x = aJavaObject.getString() + "";
-
-unless you are certain that the string is being returned is a raw JavaScript string.
-
-Names with "$" and "_"
-----------------------
-
-For the most part, this should be no problem.
-
-Note that the use of $ and _ in Java field names has always been discouraged:
-[https://docs.oracle.com/javase/tutorial/java/nutsandbolts/variables.html]
-
- You may find some situations where auto-generated names will contain the dollar sign,
- but your variable names should always avoid using it. A similar convention
- exists for the underscore character; while it's technically legal to begin your
- variable's name with "_", this practice is discouraged.
-
-Some impacts of transpiling method names with full qualification:
-
-1) SwingJS will introduce fields that start with $ or _. These will not conflict
- if the above convention is followed.
-
-2) Fields that have the same Java name as a method are not an issue.
-
-3) Fields that have a Java name with $ that matches a transpiled method name,
- such as toString$, will need to be refactored in Java to not have that name collision.
-
-4) Fields in a subclass that have the same name as private fields in a superclass
- represent a name collision, because the superclass method needs to call its private
- field even if invoked from a subclass. The solution was to modify the subclass field
- name using one or more prepended $.
-
-5) Use of Class.getDeclaredMethods() reflection will return Method objects having the transpiled
- name, not the Java name. This could require some j2sNative adjustment
- to strip the $... parameters from the name if that is needed.
-
-6) Use of Method.getParameterTypes() should work fine, provided class names
- do not contain "_". This is because the transpiler converts "." to "_" when
- creating the fully qualified JavaScript name.
-
-
-positive integers do not add to give negative numbers
------------------------------------------------------
-
-In Java, the following is true:
-
- 2000000000 + 2000000000 == -294967296
-
-But in SwingJS, that will be 4000000000. So, for example, the following
-strategy will fail in SwingJS:
-
- int newLength = lineBuf.length * 2;
- if (newLength < 0) {
- newLength = Integer.MAX_VALUE;
- }
-
-"-1" in JavaScript is not 0xFFFFFFFF.
-
-And one must take care to not compare a negative number with a 32-bit mask. So
-
-(b & 0xFF000000) == 0xFF000000
-
-is true in Java for (int) b = -1, but is false in JavaScript, because 0xFF000000 is 4278190080,
-while (-1 & 0xFF000000) is, strangely enough, -16777216, and, in fact,
-
-(0xFF000000 & 0xFF000000) != 0xFF000000
-
-because -16777216 is not 4278190080.
-
-The fix is that one must compare similar operations:
-
-if ((b & 0xFF000000) == (0xFF000000 & 0xFF000000)) .....
-
-Importantly, the JavaScript Int32Array does behave properly. From
-the Firefox developer console:
-
->> x = new Int32Array(1)
-<- Int32Array(1) [ 0 ]
->> x[0] = 4000000000
-<- 4000000000
->> x[0]
-<- -294967296
-
-Notice that, perhaps unexpectedly, the following two constructs produce
-different results in JavaScript:
-
-x = new Int32Array(1);
-b = x[0] = 4000000000;
-
-(b will be 4000000000)
-
-and
-
-x = new Int32Array(1);
-x[0] = 4000000000;
-b = x[0];
-
-(b will be -294967296)
-
-
-SwingJS leverages array typing to handle all byte and short arithmetic so as
-to ensure that any byte or short operation in JavaScript does give the same
-result in Java. The design decision to not also do this with integer math was
-a trade-off between performance and handling edge cases.
-
-
-ArrayIndexOutOfBounds
----------------------
-
-You cannot implicitly throw an ArrayIndexOutOfBoundsException in JavaScript.
-JavaScript will simply return "undefined", not throw an Exception. So:
-
-boolean notAGoodIdeaIsOutOfBounds(String[] sa, int i) {
- try {
- return (sa[i] == sa[i]);
- } catch (ArrayIndexOutOfBoundsException e) {
- return false;
- }
-}
-
-will work in Java but not in JavaScript. Code should not depend upon this sort
-of trap anyway, if you ask me.
-
-Throwable vs Error vs Exception
--------------------------------
-
-True JavaScript errors are trapped as Throwable, whereas you can still trap
-Error and Exception as well. So if you want to be sure to catch any JavaScript
-error, use try{}catch (Throwable t){}, not try{}catch (Exception e){}.
-
-j
-ava.awt.Color
---------------
-
-ColorSpace: only "support" CS_sRGB.
-
- TODO -- any volunteers??
-
-
-javax.swing.JFileDialog
------------------------
-
-HTML5 cannot expose a file reading directory structure. But you certainly
-can still do file reading and writing. It just works a little differently.
-It's a simple modification:
-
- b = new JButton("FileOpenDialog");
- b.addActionListener(new ActionListener() {
-
- @Override
- public void actionPerformed(ActionEvent e) {
- JFileChooser fc = new JFileChooser();
- Test_Dialog.this.onDialogReturn(fc.showOpenDialog(Test_Dialog.this));
- // Java will wait until the dialog is closed, then enter the onDialogReturn method.
- // JavaScript will exit with NaN immediately, and then call back with its actual value
- // asynchronously.
- }
-
- });
-
- public void onDialogReturn(int value) {
- if (value != Math.floor(value))
- return; // in JavaScript, this will be NaN, indicating the dialog has been opened
- // If we are here, the dialog has closed, in both Java and JavaScript.
- System.out.println("int value is " + value);
- }
-
-
- @Override
- public void propertyChange(PropertyChangeEvent event) {
- Object val = event.getNewValue();
- String name = event.getPropertyName();
- System.out.println(name);
- switch (event.getSource().getClass().getName()) {
- case "javax.swing.JOptionPane":
- switch (name) {
- case "inputValue":
- onDialogReturn(val);
- return;
- case "value":
- if (val instanceof Integer)
- onDialogReturn(((Integer) val).intValue());
- else
- onDialogReturn(val);
- return;
- }
- break;
- case "javax.swing.ColorChooserDialog":
- switch (name) {
- case "SelectedColor":
- onDialogReturn(val);
- return;
- }
- break;
- case "javax.swing.JFileChooser":
- switch (name) {
- case "SelectedFile":
- File file = (File) val;
- byte[] array = (val == null ? null : /** @j2sNative file.秘bytes || */
- null);
- onDialogReturn("fileName is '" + file.getName() + "'\n\n" + new String(array));
- return;
- }
- break;
- }
- System.out.println(
- event.getSource().getClass().getName() + " " + event.getPropertyName() + ": " + event.getNewValue());
- }
-
-
-Developers are encouraged to create a separate class that handles general calls to JFileDialog.
-An example class can be found in the SwingJS distribution as
-
-/sources/net.sf.j2s.java.core/src/javajs/async/AsyncFileChooser.java.
-
-
-javax.swing.JOptionPane dialogs
--------------------------------
-
-For this action to work, the parentComponent must implement
-propertyChangeListener, and any call to JOptionPanel should allow for
-an asynchronous response, meaning that there is no actionable code following the
-call to the dialog opening.
-
-In addition, for compatibility with the Java version, implementation should
-wrap the call to getConfirmDialog or getOptionDialog in a method call to
-handle the Java:
-
-onDialogReturn(JOptionPane.showConfirmDialog(parentFrame,
-messageOrMessagePanel, "title", JOptionPane.OK_CANCEL_OPTION));
-
-Then parentFrame.propertyChange(event) should also call onDialogReturn.
-
-This will then work in both Java and JavaScript.
-
-Note that there is an int and an Object version of onDialogReturn().
-
-
-In JavaScript:
-
-The initial return from JOptionPane.showConfirmDialog and showMessageDialog
-will be (SwingJS) JDialog.ASYNCHRONOUS_INTEGER (NaN), testable as an impossible
-Java int value using ret != -(-ret) if the parent implements PropertyChangeListener, or -1
-(CLOSE_OPTION) if not.
-
-For showOptionDialog (which returns Object) or showInputDialog (which returns
-String), the initial return will be (SwingJS) JDialog.ASYNCHRONOUS_OBJECT, testable as
-((Object) ret) instanceof javax.swing.plaf.UIResource if the parent implements
-PropertyChangeListeneer, or null if not.
-
-The second return will be the desired return.
-
-In Java:
-
-The initial return will be the one and only modal final return.
-
-
-
-For full compatibility, The calling method must not continue beyond this
-call.
-
-All of the standard Java events associated with Components are also
-available.
-
-Certain fall back mechanisms are possible, where onReturn does not exist, but
-only for the following cases:
-
-
-For showMessageDialog, for WARNING_MESSAGE and ERROR_MESSAGE, a simple
-JavaScript alert() is used, returning 0 (OK_OPTION) or -1 (CLOSED_OPTION).
-
-For showInputDialog, if the message is a string, a simple JavaScript prompt()
-with input box is used, returning the entered string or null.
-
-For showConfirmDialog, a simple JavaScript confirm() is used, in which case:
-
-for YES_NO_OPTION: YES_OPTION or NO_OPTION
-
-for YES_NO_CANCEL_OPTION: YES_OPTION or CANCEL_OPTION
-
-for OK_CANCEL_OPTION or any other: OK_OPTION or CANCEL_OPTION
-
-Note that you should implement a response for CLOSED_OPTION for
-showConfirmDialog. For other dialogs, a null return indicates the dialog was
-closed, just as for Java.
-
-Developers are encouraged to create a separate class that handles general calls.
-An example class can be found in the SwingJS distribution as src/javajs/async/AsyncDialog.java.
-Very simple modifications to the Java allows asynchronous operation using AsyncDialog. Here
-is a simple "do you want to close this frame" example, where you can see that what we have
-done is to set the reply into an ActionListener that is defined in the constructor of
-the AsyncDisplay object:
-
-// Original:
-//
-// private void promptQuit() {
-// int sel = JOptionPane.showConfirmDialog(null, PROMPT_EXIT, NAME, JOptionPane.YES_NO_OPTION);
-// switch (sel) {
-// case JOptionPane.YES_OPTION:
-// resultsTab.clean();
-// seqs.dispose();
-// if (fromMain) {
-// System.exit(0);
-// }
-// break;
-// }
-// }
-
- private void promptQuitAsync() {
- new AsyncDialog(new ActionListener() {
-
- @Override
- public void actionPerformed(ActionEvent e) {
- int sel = ((AsyncDialog)e.getSource()).getOption();
- switch (sel) {
- case JOptionPane.YES_OPTION:
- resultsTab.clean();
- seqs.dispose();
- if (fromMain) {
- System.exit(0);
- }
- break;
- }
- }}).showConfirmDialog(null, PROMPT_EXIT, NAME, JOptionPane.YES_NO_OPTION);
- }
-
-Very simple!
-
-
-native methods
---------------
-
-The J2S compiler ignores all static native method declarations.
-Anything of this nature needs to be implemented in JavaScript if it is needed,
-using j2sNative blocks:
-
-/**
- * @j2sNative
- *
- * var putYourJavaScriptCodeHere
- *
- */
-
- Note that if you follow that directly with a {...} block, then
- the javadoc code will run in JavaScript, and the {...} code will run in Java.
-
-
-key Focus
----------
-
-As of June, 2019, the keyboard focus manager is fully implemented.
-The one catch is that JTextPane and JTextArea, which already consume
-VK_TAB in Java, cannot use CTRL-TAB to continue a tabbing cycle around
-the components in a window. Instead, CTRL-TAB is absorbed by the browser.
-
-
-LookAndFeel and UI Classes
---------------------------
-
-SwingJS implements the native browser look and feel as swingjs.plaf.HTML5LookAndFeel.
-There are small differences between all look and feels -- MacOS, Windows, SwingJS.
-
-Expert developers know how to coerce changes in the UI by subclassing the UI for a
-component. This probably will not work in SwingJS.
-
-Note that LookAndFeel in Java usually determines canvas size in a Frame because
-different operating systems (Mac OS vs Windows vs HTML5) will have
-different edge sizes on their frames. If you want to ensure a component size,
-use getContentPane().setPreferredSize().
-
-
-System.exit(0) does not stop all processes
-------------------------------------------
-
-Although System.ext(int) has been implemented in JavaScript, it just closes the
-frames, stops all pending javax.swing.Timer objects in the queue, and runs any
-threads added using Runtime.getRuntime().addShutdownHook(Thread).
-It may not stop all "threads." So don't rely on that.
-Applications are responsible for shutting down prior to executing System.exit(0).
-
-
-myClass.getField not implemented
---------------------------------
-
-java.lang.reflect.Field is implemented minimally. It is not
-certain that Field.getDeclaringClass() will work. If you just want a
-value of a field, you can do this:
-
-/**
- *@j2sNative
- *
- * return myClass[name]
- */
-
-But that is not a java.lang.reflection.Field object.
-
-
-"window" and other reserved JavaScript names
---------------------------------------------
-
-No reserved top-level JavaScript name is allowed for a package name. So, for example,
-one must rename packages such as "window" or "document" to names such as "win" or "doc".
-
-reserved field and method names
--------------------------------
-
-In order to minimize the chance of added SwingJS field and method names colliding with ones
-developers might use in subclassing Java classes, we have added U+79D8 (first character of Mandarin
-"secret") to the characters already disrecommended by Java documentation ("$" and "_"). The only problem
-would be if you use that character followed by certain English words in certain classes. For example
-\u79D8canvas for JComponents (in java.awt.JSComponent) and \u79D8byte (in java.io.File).
-
-qualified field and method names
---------------------------------
-
-Method names in SwingJS are fully qualified, meaning two methods with the same Java name but different
-parameters, such as write(int) and write(double), must not have the same name in JavaScript. (In this
-case, we will have write$I and write$D.) However, in certain cases it may be desirable to leave the
-method names unqualified. In particular, when an interface actually represents a JavaScript object,
-the transpiler can leave a method name unqualified. The default situation for this is a class name
-includes ".api.js" (case-sensitive). This means that any method in any class in a package js within
-a package api, or any private interface js that has an outer interface api, will have all-unqualified
-methods. An example of this is swingjs.plaf.JSComboPopupList, which needs to communicate with a jQuery
-object directly using the following interface:
-
- private interface api {
-
- interface js extends JQueryObject {
-
- abstract js j2sCB(Object options);
-
- abstract Object[] j2sCB(String method);
-
- abstract Object[] j2sCB(String method, Object o);
-
- abstract Object[] j2sCB(String method, int i);
-
- abstract int j2sCB(String OPTION, String name);
-
- }
- }
-
-Notice that all these variants of j2sCB() will call the same method in JavaScript by design.
-
-
-missing Math methods
---------------------
-
-java.lang.Math is worked out, but some methods are missing, either because they
-involve long integer value that are inaccessible in JavaScript, or because I just
-didn't implement them. This is a result of continued Java development.
-It is easy enough to add these methods if you have the source. They go into j2sClazz.js,
-which is combined with other initial libraries into swingjs2.js by build_site.xml
-
-
-Component.getGraphics(), Graphics.dispose()
--------------------------------------------
-
-Use of component.getGraphics() is discouraged in Java and in SwingJS.
-Specifically in SwingJS, any call to component.getGraphics() or
-BufferedImage.createGraphics() or Graphics.create(...) should be matched with graphics.dispose(),
-particularly when it is called outside the context of a paint(Graphics)
-call from the system.
-
-If you see your graphics scrolling down the page with each repaint,
-look for where you have used Component.getGraphics() and not Graphics.dispose().
-For example, this will definitely NOT work in SwingJS:
-
- this.paint(getGraphics())
-
-and really should not work in Java, either, as it is technically a resource memory leak.
-
-Instead, if you really do not want to use repaint(), use this:
-
- Graphics g = getGraphics();
- paint(g);
- g.dispose();
-
-
-
-Graphics.setClip()
-------------------
-
-The HTML5 canvas.clip() method is permanent. You can only reset the clip using
-save/restore. This is different from Java, where you can temporarily change it using
-
- Shape oldClip = Graphics.getClip();
- Graphics.setClip(newClip);
- ...
- Graphics.setClip(oldClip);
-
-If you need to do something like this, you must schedule the paints
-to not have overlapping clip needs.
-
-
-MAJOR ISSUES--for Bob and Udo within SwingJS
-============================================
-
-fonts
------
-
-Fonts and FontMetrics will all be handled in JavaScript. Font matching will
-not be exact, and composite (drawn) fonts will not be supported.
-
-SwingJS handles calls such as font.getFontMetrics(g).stringWidth("xxx") by
-creating a <div> containing that text, placing it in an obscure location on
-the page, and reading div.getBoundingClientRect(). This is a VERY precise
-value, but can be a pixel or two off from what Java reports for the same font.
-
-
-OS-dependent classes
---------------------
-
-Static classes such as:
-
- java.awt.Toolkit
- java.awt.GraphicsEnvironment
-
-
-which are created using Class.forName are implemented using classes in the swingjs package.
-
-AWTAccessor is not implemented.
-
-
-AWT component peers and component "ui" user interfaces
-------------------------------------------------------
-
-ComponentPeer is a class that represents a native AWT component.
-Components with such peers are called "heavy-weight" components.
-They are expected to do the dirty work of graphics drawing.
-
-Java Swing implements peers only for JApplet, JDialog, JFrame, and JWindow.
-References to such objects have been removed, but clearly there must be
-some connection to similar DOM objects, even for "light-weight" components.
-
-
-
-MAJOR ISSUES--to be resolved by implementers
-============================================
-
-fonts
------
-
-Glyph/composite/outline fonts are not supported.
-
-
-
-threads
--------
-
-Thread locking and synchronization are not relevant to JavaScript.
-Thus, anything requiring "notify.." or "waitFor.." could be a serious issue.
-
-All threading must be "faked" in JavaScript. Specifically not available is:
-
- Thread.sleep()
-
-javax.swing.AbstractButton#doClick(pressTime) will not work, as it requires Thread.sleep();
-
-However, java.lang.Thread itself is implemented and used extensively.
-
-Methods thread.start() and thread.run() both work fine.
-
-For simple applications that use Thread.sleep() just to have a delay, as in a frame rate, for
-example, one can use javax.swing.Timer instead. That is fully implemented.
-
-Likewise, java.util.Timer can be replaced with no loss of performance with javax.Swing.Timer.
-Note that java.util.TimerTask is implemented, but it can also be replaced by an implementation of Runnable.
-
-task = new TimerTask(){....};
-t = new java.util.Timer();
-t.schedule(task, 0, 1);
-
-becomes
-
-task = new TimerTask(){....}; // or task = new Runnable() {...}
-t = new javax.swing.Timer(1, new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- task.run();
- }
-};
-t.setInitialDelay(0); // not particularly necessary
-t.start();
-
-In addition, SwingJS provides swingjs.JSThread, which can be subclassed
-if desired. This class allows simple
-
- while(!interrupted()){
- wait()
- ...
- }
-
-action through an asynchronous function run1(mode). For example:
-
- protected void run1(int mode) {
- try {
- while (true)
- switch (mode) {
- case INIT:
- // once-through stuff here
- mode = LOOP;
- break;
- case LOOP:
- if (!doDispatch || isInterrupted()) {
- mode = DONE;
- } else {
- Runnable r = new Runnable() {
- public void run() {
- // put the loop code here
- }
- };
- dispatchAndReturn(r);
- if (isJS)
- return;
- }
- break;
- // add more cases as needed
- case DONE:
- // finish up here
- if (isInterrupted())
- return;
- // or here
- break;
- }
- } finally {
- // stuff here to be executed after each loop in JS or at the end in Java
- }
- }
-
-image loading
--------------
-- All image loading in SwingJS is synchronous. A MediaTracker call will immediately return "complete".
- However, it still may take one system clock tick to fully load images. Thus, it is recommended that
- images be preloaded in the static block of the applet if it is necessary that they be available in init().
- This is only an issue if you are trying to access the pixel buffer of the image in JavaScript.
-
-- Applet.getImage(path, name) will return null if the image does not exist.
-
-- BufferedImage: only "support" imageType RGB and ARGB
-
- -BH: This is a temporary edit, just to get us started. Certainly GRAY will be needed
-
-
-BigInteger and BigDecimal
--------------------------
-
-java.math.BigInteger is fully supported; java.math.BigDecimal is roughed
-in and not fully tested (07/2019).
-
-Both classes present significant issues for JavaScript, as they are based in
-Java's 64-bit long for all their operations. Here is the JavaDoc note I added
-to BigInteger:
-
- * SwingJS note: Because of the limitations of JavaScript with regard
- * to long-integer bit storage as a double, this implementation drops
- * the integer storage bit length to 24, giving 48 for long and leaving
- * the last 16 bits clear for the exponent of the double number. This should
- * not affect performance significantly. It does increase the storage
- * size by about 33%. By bringing an "int" to 3 bytes, we can easily construct
- * and use byte[] data intended for the original BitSet.
-
-"Easily" may be a bit strong there. This was a serious challenge.
-
-BigDecimal seems to run normally, but in order to do that, my hack involves
-reducing the size of an integer that is allowed to be stored as such and not
-in byte[] as a BigInteger. I'm sure there is a performance hit, but it does work.
-
-no format internationalization
-------------------------------
-
-For now, just en for number and date formatters
-
-no winding rules
-----------------
-
- When filling a graphic, only nonzero winding rule is implemented in HTML5 Canvas2D.
-
-
-
-text-related field implementation
----------------------------------
-
-Text fields are:
-
-JTextField (JavaScript <input type="text">)
-JTextArea (JavaScript <textarea>)
-JTextPane (JavaScript <div>)
-JEditorPane (JavaScript <div>)
-
-For the initial implementation, we don't implement infinite undo/redo, and the abstract
-document model is much less elaborate. Only PlainDocument (in the form of JSPlainDocument)
-is implemented. The Document returned by JTextField.getDocument() is a javax.swing.text.Document.
-
-All scrolling is handled by HTML5. javax.swing.AutoScroller is not implemented.
-public static methods .stop, .isRunning, .processMouseDragged require true Java threading
-and so are not implmented. javax.swing.text.View and its subclasses are not implemented.
-
-The JS document model does not allow two text fields to address the same underlying document.
-
-JavaScript is slightly different from Java in that the field value is changed asynchronously after
-the keypressed event, so Java actions that are keyed to KEY_PRESSED may not pick up the new
-key value even after SwingUtilities.invokeLater() is called. Thus, key pressed actions may need
-to be recorded after a key released event instead.
-
-Formatter/Regex limitations
----------------------------
-
-Some browsers cannot process Regex "look-behind" process such as (?<=\W)
-java.util.regex.Matcher and Pattern use JavaScript's RegExp object rather than
-the native Java object. These are not identical. Only flags /igm are supported.
-Matcher.start(groupID) is not supported.
-
-java.util.Formatter will function correctly for all standard %... patterns.
-
-integer 1/0 == Infinity
------------------------
-
-1/0 in Java throws "java.lang.ArithmeticException: / by zero", but in JavaScript is just Infinity.
-
-
-
-Summary
--------
-
-These are all the known limitations of SwingJS. We have not found any of these limitations
-to be show-stoppers. The primary issue for newcomers to SwingJS is having the source code.
-You must check that source code for all your library jar files is available or, if you
-choose, you will need to decompile those classes. We have used decompilation on some projects,
-and it works just fine. So, technically, all we really need are JAR/class files. But the
-source is by far superior. It's generally prettier, and it has the license information that
-may or may not be present with the JAR or class files. Use class files at your own risk.
-
-Bob Hanson
-2019.08.16
-
-
-Additional Issues
------------------
-
-Annotation is working for classes, methods, and fields (12/22/19). Method reflection, however,
-is limited. Interfaces do not expose their methods, as the transpiler does not actually transpile
-the interfaces themselves. And method reflection only includes annotated methods.
-
-java.util.concurrent is not fully elaborated. This package is rewritten to not actually use the
-memory handling capabilities of concurrency, which JavaScript does not have access to.
-
-System.getProperties() just returns a minimal set of properties.
-
-
+++ /dev/null
-20201219150605