-
Notifications
You must be signed in to change notification settings - Fork 30
Expand file tree
/
Copy pathUpdates.txt
More file actions
1749 lines (1196 loc) · 54.8 KB
/
Updates.txt
File metadata and controls
1749 lines (1196 loc) · 54.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
Notes
=====
update 12/4/2018 -- 3.2.4.07
this update advances JTextArea, JTextPane, and JEditorPane, and adds many more classes of java.nio.
update 10/1/2018 -- 3.2.4.01
AWT components in SwingJS:
-- can be accessed directly as java.awt Components
-- receive posted events to the component's MouseDown, MouseMove, etc, methods;
-- can also be extended to use (or can alternatively use) Swing MouseListener and MouseAdapter methods;
-- are subclasses of JComponent (JavaScript only, not Java), so also take all the event possibilities of Swing;
-- require explicit graphics.dispose() if getGraphics() is called in any component.
update 9/29/2018 -- 3.2.4 adds support for JAXB, changes default for ResourceBundle.getBundle
update 9/23/2018 -- 3.2.3 adds support for direct use of java.awt.* components and java.applet.Applet
-- no need for switching to a2s.*
update 7/14/2018 -- 3.2.1 removes Java2ScriptJavaBuilder; uses CompilationParticipant instead
-- note that this change requires that the .project builder be set back to org.eclipse.jdt.core.javabuilder
updated 9/5/17 -- merge with net.sf.j2s.java.core
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 JDK 1.6
=============================================================================
SwingJS implements a wide range of the Java language in JavaScript. The base
version for this implementation is Java 1.6. However, some classes were
implemented using older source code, and there are some missing methods.
=================
DESIGN PHILOSOPHY
=================
The 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.
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; overloaded methods (methods with the same name but different
signatures) should be renamed.
Threads
-------
Although there is only a single thread in JavaScript, meaning 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 refectored to allow Timer-like callbacks. That is,
they must allow full exit and re-entry of Thread.run(), not the typical while/sleep motif.
Several examples are available illustrating how to do this. [TODO: more description here]
Non-Swing AWT Components
------------------------
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, in v. 3.2.3 (Sept. 2018), all standard AWT components are subclasses of Swing equivalents.
For example, java.awt.Button subclasses javax.swing.JButton, and Canvas subclasses javax.swing.JPanel.
This is accomplished through an adapter package (a2s.*).
There will be some nuanced differences, particularly when a developer subclasses an AWT component
and then uses super.xxx() to access a superclass method of the same name. But other than that,
nothing is lost in this reorganization.
Basically, now:
java.awt.Panel and java.awt.Canvas both subclass javax.swing.JPanel,
through an a2s.Panel adapter class:
java.awt.Component
java.awt.JSComponent
java.awt.Container
javax.swing.JComponent
javax.swing.JPanel
a2s.Panel
java.awt.Panel (,java.awt.Canvas)
rather than the separate hierarchies:
java.awt.Component
java.awt.Container
javax.swing.JComponent
javax.swing.JPanel
and
java.awt.Component
java.awt.Container
java.awt.Panel (,java.awt.Canvas)
where java.awt.JSComponent is slipped in between Container and Component,
providing specialized Component methods that are JavaScript-specific.
For all components, java.awt.Xxxx is equivalent to a2s.Xxxx.
java.awt.Xxxx now just consists of a set of constructors that all go to
super(...). This allows developers to use either java.awt.Xxxx or
a2s.Xxxx interchangeably. (This is the big change for this version.)
a2s.* also uses super(...) extensively, but also adds rerouting of
Swing events to AWT events, conversion of AWT constant values to
SwingConstants values, default backgrounds and opacity that are
different between Swing and AWT, and a few other functions.
a2s.* also provides method equivalents (as best we can) from AWT
to Swing. Right now this is hit and miss. [TODO: There is more to do there.]
Standard Swing components subclass JComponent, as usual,
while AWT components subclass a2s.* component adapters,
which then subclass the Swing implementation of AWT:
java.awt.Component
java.awt.JSComponent
java.awt.Container
javax.swing.JComponent
javax.swing.AbstractButton (,javax.swing.JLabel,...)
javax.swing.JButton
a2s.Button (,JToggleButton,JMenuItem,...)
java.awt.Button
Window now subclasses JComponent. In this way, Frames, InternalFrames,
Dialogs, and PopupMenus can all be JComponents as well:
java.awt.Component
java.awt.JSComponent
java.awt.Container
javax.swing.JComponent
java.awt.Window [was subclass of java.awt.Container]
java.awt.JSFrame [was java.awt.Frame]
javax.swing.JFrame
a2s.Frame (,javax.swing.JInternalFrame)
java.awt.Frame
In standard Java, JInternalFrame subclasses JComponent, reproducing
independently all the standard Frame interface. This is much simpler,
with JInternal frame subclassing JFrame.
Same idea for Dialog:
java.awt.Component
java.awt.JSComponent
java.awt.Container
javax.swing.JComponent
java.awt.Window
java.awt.JSDialog [formerly java.awt.Dialog]
javax.swing.JDialog
a2s.Dialog
java.awt.Dialog
java.awt.Window has moved to subclass JComponent, again so that
all of its subclasses can be Swing components.
java.awt.Component
java.awt.JSComponent
java.awt.Container
javax.swing.JComponent
java.awt.Window
java.awt.JWindow
Note that the original ordering involving java.awt.Window was:
java.awt.Component
java.awt.Container
java.awt.Window (,javax.swing.JComponent)
javax.swing.JWindow (,Frame, Dialog, PopupMenu)
Finally, Applet now subclasses JApplet via a2s.Applet:
java.awt.Component
java.awt.JSComponent
java.awt.Container
java.awt.JSPanel [formerly java.awt.Panel]
java.applet.JSApplet [formerly java.applet.Applet]
javax.swing.JApplet
a2s.Applet
java.applet.Applet
Thus, the only components that are not JComponents now are Applet and JApplet.
The a2s Adapter Package
-----------------------
Thus, 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. It's not perfect, and the ultimate
solution is probably to just change java.awt.Xxxx itself to subclass javax.swing.JXxxx.
In any case, it works -- mostly. By adding the a2s package to a project and changing the include
statements to target a2s instead of java.awt, non-Swing applets can be easily converted to JavaScript.
Certainly there will be issues such as missing methods. It is all a work in progress.
As of v. 3.2.3, as mentioned above, java.awt.Xxxx components all now subclass a2s.Xxxx and,
by doing so, all become JComponents. java.applet.Applet subclasses a2s.Applet, which subclasses
javax.swing.JApplet, which subclasses java.awt.Container via java.applet.JSApplet and
java.awt.JSPanel. So javax.swing.JApplet and java.awt.Applet are not JComponents.
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 component) and the Component "uiClass" (one per class).
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
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 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.
UNIMPLEMENTED CLASSES and METHODS BY DESIGN
===========================================
accessibility
security
serialization
key listeners
keyboard accelerators
TODO LIST FOR UNIMPLEMENTED CLASSES
===================================
JEditorPane (minimal implementation)
JSplitPane (in development, BH)
MINOR ISSUES--requiring some rewriting/refactoring outside of SwingJS
=====================================================================
ArrayIndexOutOfBounds
native classes
key focus
LookAndFeel
toString() may need to be explicit
myClass.getField not implemented
"window" and other reserved JavaScript names
ResourceBundle.getBundle
MAJOR ISSUES--for Bob and Udo within SwingJS
============================================
fonts
OS-dependent classes
AWT component peers
MAJOR ISSUES--to be resolved by implementers
============================================
fonts
Dialogs
threads
some Swing components not implemented
image loading
no BigInteger; no BigDecimal
no format internationalization
no winding rules
text-related field implementation
Formatter/Regex limitations
========================================================================
//////////////////////////////////////////////////////////////////////////////
UNIMPLEMENTED CLASSES
=====================
accessibility
-------------
All Accessibility handling has been commented out to save the download footprint.
This removes the need for sun.misc.SharedSecrets
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.
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.
key listeners
-------------
The KeyListener interface for JTextField and JTextArea has not been implemented.
Alternative coding is to use ActionListener, TextListener, or DocumentListener (largely untested)
keyboard accelerators
---------------------
JMenu.setAccelerator() and JMenuItem.setAccelerator() hae not been implemented in SwingJS.
Thus, menus cannot be opened just be typing CTRL-C or similar shortcuts.
MINOR ISSUES--requiring some rewriting/refactoring outside of SwingJS
=====================================================================
primitive numerical types
-------------------------
JavaScript cannot distinguish among primitive number types
int, short, float, and double. Bob's J2S fix does allow for
distinguishing between int[] and float[], but that is all.
The implication is for overloaded methods and constructors.
For example:
Color(int r, int g, int b, int a)
Color(float r, float g, float b, float a)
cannot be distinguished. A very important case in this regard is
StringBuffer.append(int)
StringBuffer.append(float)
There is no way to know one's intent here. Integers must be changed to strings:
sb.append("" + i)
This will need careful checking and will be the source of bugs, for sure,
because it is next to impossible to find all of these, and even if they are
found, certain cases such as above will never be perfectly resolved.
In addition, JavaScript does not/cannot support "long".
One cannot test against Long.MAX_VALUE or Long.MIN_VALUE.
Since int, long, byte, and char are not really integers, care must be taken
to avoid a loop such as the following, which was in java.text.DigitList:
while (source > 0) {
...
source /= 10
}
Similarly, large integers will never roll over to negative ones. They will
just get bigger.
int newLength = lineBuf.length * 2;
/**
* @j2sIgnore
*/
{
// never going to happen in JavaScript
if (newLength < 0) {
newLength = Integer.MAX_VALUE;
}
}
Also, J2S does not translate properly
int n = 110
n /= 100
This needs to be recast as
n = n / 100
For example, SimpleDateFormat needs
month = Clazz.doubleToInt(month / 367);
instead of
month /= 367
Because "-1" in JavaScript is not 0xFFFFFFFF one must take care to not compare a negative number with a 32-bit mask;
(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.
One must compare similar operations:
if ((b & 0xFF000000) == (0xFF000000 & 0xFF000000)) .....
ArrayIndexOutOfBounds
---------------------
You cannot intentionally throw an ArrayIndexOutOfBoundsException in JavaScript.
JavaScript will simply return "undefined", not throw an Exception.
ArrayIndexOutOutBoundsException cannot be trapped in JavaScript because
it is a JavaScript Error, not a Java Exception.
Solution is to change that catch to catch(Throwable e),
which includes all JavaScript errors and is transpiled as "catch(e)"
java.awt.Color
--------------
See note under primitive types, above.
ColorSpace: only "support" CS_sRGB
-BH: This is a temporary edit just to get us started.
native classes
--------------
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
*
*/
{
// it is critical to remember to insert this { } phrasing,
// or the block will be ignored!
}
key Focus
---------
- Less explicit key focus
- handling (mostly done by Browser/HTML)
- no SwingUtilities.findFocusOwner
- focus traversal not implemented
LookAndFeel
-----------
SwingJS implements the native browser LookAndFeel. Token UIManager methods are
present but unimplemented; methods returning key bindings or other arrays return null.
Note that LookAndFeel determines canvas size in a Frame because different operating
systems (Mac OS vs Windows vs HTML5) will have different edge sizes on their frames.
toString() may need to be explicit (Can't convert .... to primitive type)
-------------------------------------------------------------------------
JavaScript will use its own method of creating a string form of an object. So if you
have implemented a toString() method for x instanceof X, then you should use it
explicitly as "foo " + x.toString(), not "foo " + x.
This problem was first seen in the original form of java.awt.image.BufferedImage.toString()
where we got the JavaScript error "Can't convert .... to primitive type" in an error message
due to " " + this.raster, where this.raster was a sun.awt.image.IntegerInterleavedRaster.
myClass.getField not implemented
--------------------------------
java.lang.reflect.Field is not implemented. You can get a field value very simply
using:
/**
*@j2sNative
*
* return myClass[name]
*/
"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".
ResourceBundle.getBundle
------------------------
java.util.ResourceBundle(String) default is Control.FORMAT_DEFAULT, which
first checks for a Java class, then a properties file. This causes problems
as missing class files is a major failure case. The default in SwingJS is
FORMAT_PROPERTIES meaning that the default is NOT to look for a class file.
It is felt that the developer should know which of these it is, and if it is
a class file, then the ResourceBundle call should specify that.
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.
Jmol handles calls such as font.getFontMetrics(g).stringWidth("xxx") by
creating an off-page DOM image and querying its context.
This will be done here as well.
OS-dependent classes
--------------------
Static classes such as:
java.awt.Toolkit
java.awt.GraphicsEnvironment
which are created using Class.forName
will be implemented as JavaScript classes in the swingjs package
AWTAccessor and AwtContext need to be customized
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
Dialogs
-------
Dialogs need special attention by developers. Except for the simplest types,
confirm() and prompt(), they cannot be made truly modal (wait for response).
But a modal dialog can be "faked" by setting up a state-based system.
See examples for ways of doing this. [TODO: say more; it all works very nicely]
some Swing components not implemented
-------------------------------------
The following Swing components are not implemented:
JEditorBox
JTree
[TODO: more? or is this really it now]
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();
Internally, SwingJS uses swingjs.JSThread, which can serve as a
state-based alternative to Thread. This class allows simple
while(!interrupted()){
wait() or sleep()
...
}
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
-------------
- JavaScript does not allow synchronous image loading. A callback is required, and
since there is no Thread.sleep, this could be a problem in some cases.
- BufferedImage: only "support" imageType RGB and ARGB
-BH: This is a temporary edit, just to get us started. Certainly GRAY will be needed
no BigInteger; no BigDecimal
----------------------------
BigInteger and BigDecimal are not supported
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>; non-editing; TODO)
JEditorPane NOT IMPLEMENTED
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.
Thus, the Document returned by JTextField.getDocument() is a javax.swing.text.Document, but it
is a swingjs.JSPlainDocument (extending swingjs.JSAbstractDocument)
rather than a javax.swing.text.PlainDocument (extending javax.swing.text.AbstractDocument).
all scrolling is handled by HTML5
javax.swing.AutoScroller is not implemented
public static methods .stop, .isRunning, .processMouseDragged require true Java threading
javax.swing.text.View and its subclasses are not implemented.
The JS document model does not allow two fields to address the same underlying document.
Formatter/Regex limitations
---------------------------
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.
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 anyway.
We now have jsjava.lang.Thread and jsjava.lang.ThreadGroup. These should be useful in
figuring out what we want to do with those. ThreadGroup in particular is interesting,
as it is used to key for AppContexts. We will see if that use useful or not.
PROGRESS
========
7/23/2016
We (Andreas Raduege, Nadia ElMouldi, and Bob Hanson) have now converted 24 Falstad applets,
including Circuit. These applets are running approximately 3-6 times slower than in Java,
in some cases after a bit of for-loop optimization.
No significant issues have been found, though we continue to find mostly minor j2s
compiler bugs. Mostly what is taking time is the addition of missing features, such
as audio, pop-up menus, menu bars, sliders, graphics2D capability,
independent frames and dialogs, and threading.
At this point we have a good variety of common controls. Events are being handled properly
through the "java" event queue. Mouse operation is smooth.
BH 11/2/2016 8:53:44 AM -- bug #38 in compiler -- if a class has a constructor such as JButton() that calls
this(null, null), and that class is subclassed with a
class such as ToggleButton that contains a constructor
such as ToggleButton(String,String), then the call to JButton()
will improperly call that subclass's constructor. This is a
problem due to the fact that in Java "this" in a superclass
DURING CONSTRUCTION does not refer to the "this" of the
subclass.
BH 7/23/2016 6:16:30 PM -- bug #27 in compiler -- need Boolean.from(string) not new Boolean(string)
BH 7/23/2016 6:17:31 PM -- but #26 in compiler -- compiler can inappropriately use Clazz.overrideMethod
BH 7/22/2016 1:29:12 PM -- bug #25 in compiler for int f() { return 'o' } -- will return a string, not int
BH 7/20/2016 2:58:17 PM -- bug #24 in compiler found for files with both interfaces and classes present
BH 7/20/2016 2:57:36 PM -- basic audio (8- and 16-bit mono/stereo once-through or streamed)
BH 7/7/2016 2:28:59 PM -- Formatter/Regex implemented
BH 7/7/2016 11:21:48 AM -- j2s bug #3 is still a serious issue
BH 7/4/2016 1:36:20 PM -- j2s bug #23 inner/anonymous class may reference wrong superclass instance
BH 7/4/2016 10:22:39 AM -- j2s bug #22 final vars not passed to local class
6/01/2015 BH -- development has shifted for the summer to the "near" branch.
working applet development can be followed at
http://chemapps.stolaf.edu/jmol/swingjs/site/swingjs/examples
12/20/2015 BH -- j2s bug #21 (byte) ignored so that 0xFF remains 0xFF
7/19/2015 BH -- j2s bug #20 no implicit primitive from wrapped primitive (int/Integer) in SAEM
7/18/2015 BH -- j2s bug #19 improper signature identification in SAEM with untyped null parameter
7/17/2015 BH -- j2s bug #18 (jalview.commands.EditCommand)
7/15/2015 BH -- j2s bug #17 (jalview.analysis.RNA)
6/3/2015 BH
JTextField ENTER action enabled
JPasswordField working using simple HTML5 type="password"
JFormattedTextField working; proper validation enabled for number formatters with FocusLost action
see http://chemapps.stolaf.edu/jmol/swingjs/site/swingjs/examples/oracle/formattedfield.htm
and swingjs/test/FormattedTextFieldDemo.java
see http://chemapps.stolaf.edu/jmol/swingjs/site/swingjs/examples/oracle/converter.htm
(this app still needs selection boxes
SwingJS J2S bug #16 NumberFormat.js includes the inner public class NumberFormat.Field, which is called here by instanceOf
Solution was to change the requirement to the outer class:
@J2SRequireImport(NumberFormat.class)
@J2SIgnoreImport(NumberFormat.Field.class)
public class NumberFormatter extends InternationalFormatter...
5/30/2015 BH
jQuery Slider is implemented for JSlider
-- see site/swingjs/seethroughimage.htm
jQueryUI files may be found in swingjs.jquery:
jquery-ui-slider.css
jquery-ui-slider.js
JQueryUI.js
JQueryUI.js is just a shell Java class;
loading of jQueryUI occurs when a class utilizes
@J2SRequireImport(swingjs.jquery.JQueryUI.class)
and then also has a static block such as:
static {
swingjs.JSToolkit.getJavaResource ("swingjs/jquery/jquery-ui-slider.css");
swingjs.JSToolkit.getJavaResource ("swingjs/jquery/jquery-ui-slider.js");
}
method in the loading a css style block or executing JavaScript, as appropriate.
The CSS for the slider widget is scoped as "swingjs". On the page, a slider
gets implemented as:
<div id="testApplet_SliderUI_13_5div" style="position: absolute; left: 0px; top: 150px;">
<div id="testApplet_SliderUI_13_5_wrapdiv" class="swingjs" style="width: 200px; height: 20px;">
<div id="testApplet_SliderUI_13_5" class="ui-slider ui-slider-horizontal ui-widget ui-widget-content ui-corner-all swingjs-ui">
<a class="ui-slider-handle ui-state-default ui-corner-all swingjs-ui" href="#" style="left: 50%;"></a>
</div>
</div>
</div>
The className "swingjs-ui" tells SwingJS (in JSmolCore.js) to ignore all mouse
action and work directly with jQuery events. These events fire a method in
the component UI class that looks like this:
Clazz.defineMethod (c$, "jqueryCallback",
function (event, ui) {
var value = 0;
value = ui.value;
this.jSlider.setValue (this.val = value);
}, "~O,swingjs.api.DOMNode");
The widget itself is created using a standard jQuery widget constructor:
me.$(me.jqSlider).slider({
orientation: me.orientation,
range: false,
min: me.min,
max: me.max,
value: me.val,
change: function( event, handle ) {
me.jqueryCallback(event, handle);
},
slide: function( event, handle ) {
me.jqueryCallback(event, handle);
}
});
It is nice to see that the jQuery bindings to key actions (UP, DOWN,
LEFT, RIGHT, HOME, END, PGUP, PGDN all work properly.
There is a complication with z-index, because jQuery sets that, and
we need to have it correct in the heirarchy of applets and dialogs.
So to implement that, we catch the "ancestor" change property event, and
hope that somewhere up the chain the z-index is set. I am not sure this is
completely correct. We probably need to adjust the z-index for all DOM child
nodes when this happens.
It seems that it is also possible to lose an event, in which case the
handle image just floats away from the handle with the user's mouse, and
a click is required to reset that.
I have not tried tics and labels on sliders
5/25/2015 BH
- found J2S bug #13,#14,#15
- java.awt.image.BufferedImage implemented; RescaleOp working for alpha scaling
- see seethroughimage.htm
- working on SeeThroughImageApplet (slider, image filtering)
5/24/2015 BH
- fix for "south" button not spanning full width
5/23/2015 BH
- fix for java.util.Random.nextInt(bits)
- adds loadimage.htm and jumbledimage.htm
- Q: What sets the "south" button to be the full width?
- reading and drawing of PNG, JPG, GIF, and BMP image formats
java.awt.Toolkit.getDefaultToolkit().getImage(String filename)
java.awt.Toolkit.getDefaultToolkit().getImage(URL)
java.awt.Toolkit.getDefaultToolkit().createImage(String filename)
java.awt.Toolkit.getDefaultToolkit().createImage(URL)
java.awt.Toolkit.getDefaultToolkit().createImage(byte[], intOffset, intLength)
javax.imageio.ImageIO.read(URL)
java.awt.Graphics2D.drawImage(...)
- implementation of focus, though not traversal: