Skip to content

Commit 0f48c0c

Browse files
authored
Merge pull request #115 from BobHanson/hanson1
Hanson1
2 parents e76fa51 + 677f72a commit 0f48c0c

File tree

22 files changed

+2727
-2620
lines changed

22 files changed

+2727
-2620
lines changed
1.76 KB
Binary file not shown.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
20191001111303
1+
20191008173421
1.76 KB
Binary file not shown.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
20191001111303
1+
20191008173421

sources/net.sf.j2s.core/doc/howItWorks.md

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
1-
Java2Script: How It Works
1+
***Java2Script: How It Works***
22

3+
**java2script/SwingJS**
4+
5+
The full java2script/SwingJS operation involves two parts: Creating the JavaScript from the abstract syntax tree (java2script), and running that within the browser (SwingJS). Both are discussed below.
6+
7+
The code for these two parts are well-separated:
8+
9+
net.sf.j2s.core java2script transpiler
10+
net.sf.j2s.java.core SwingJS runtime
11+
12+
[Note: You may notice that the java2script project includes several other net.sf.... projects. Frankly, I have no idea what they are for. My guess is that they don't work. I think perhaps they were early attempts to get all this working within Eclipse at runtime, with "hot" connections to code. But that never ever worked for me, and what we have now -- direct creation of a site directory that can be debugged in a standard external browser is way better, anyway. I have left them there just because I haven't taken the time to get rid of them.]
13+
14+
**java2script transpiler**
15+
16+
[Note: Changes in java2script should be necessary only when core Java syntax changes or is supplemented in the core Java. For example, Java 8 allows switch cases that are String constants, while Java 6 does not. When we went to Java 8, we had to modify Java2ScriptVisitor.java to account for that. If ever there is a need to fix something that the java2script compiler is doing wrong or to adapt to new Java syntax, as for Java 11, look in net.sf.j2s.core.Java2ScriptVisitor.]
317

418
A compiler converts code in one computer language to another. Typically this is from a higher-level language to a lower-level "machine code" language. In the case of the Java compiler, this is from written Java code (*.java) to "Java byte code" (*.class). In the case of of java2script, this is from Java to JavaScript. There are two basic requirements of a compiler: reading and writing. The reading process involves converting the written Java code to an <i>abstract syntax tree</i> [https://en.wikipedia.org/wiki/Abstract_syntax_tree]. The writing process involves scanning that tree, creating one or more output files from the original input file.
519

@@ -25,9 +39,54 @@ So this is pretty straightforward. All the output that is ultimately saved in *.
2539

2640
etc.
2741

28-
If ever there is a need to fix something that the java2script compiler is doing wrong or to adapt to new Java syntax, as for Java 11, look in net.sf.j2s.core.Java2ScriptVisitor. There is great documentation on all of these org.eclipse.jdt.core.dom.ASTNode subclasses.
42+
[Note that a big difference between Java and JavaScript is that JavaScript functions cannot be "overloaded", meaning the two calls in JavaScript:
43+
44+
write(b)
45+
write(b, 2, 3)
46+
47+
will both point to the same function. A major task of the java2script transpiler is to sort this out before it becomes an issue at runtime. It does this by creating signature-specific function names in JavaScript, such as write$B and write$B$I$I.]
48+
49+
50+
**Creating a New Transpiler**
51+
52+
The transpiler is created in Eclipse by checking out the net.sf.j2s.core project from GitHub as a standard Java project and adjusting the code as necessary. When it is desired to create the transpiler (net.sf.j2s.core.jar):
53+
54+
1) Use File...Export...Deployable plug-ins and fragments
55+
(if you do not see this option, check that you are using Eclipse
56+
Enterprise)
57+
2) Choose net.sf.j2s.core (Version 3.2.4), check the directory,
58+
and press finish.
59+
3) Copy this file to the drop-ins directory, restart Eclipse,
60+
and test.
61+
4) Copy this file to the project dist/swingjs folder and also
62+
to the swingjs/ver/3.2.4 folder (or appropriate).
63+
64+
I do this with a DOS batch file, which also adds a timestamp.
65+
66+
That's it. I advise to NOT change the version number. I know, this
67+
sounds stupid, but if you change that number, installation in Eclipse requires starting Eclipse with a -clean as the first option. https://www.eclipsezone.com//eclipse/forums/t61566.html
68+
This is pain. If you do not do this clean build, Eclipse just
69+
ignores your drop-in.
70+
71+
The dist directory also includes SwingJS-site.zip, created from the net.sf.j2s.core.java project.
72+
73+
74+
**SwingJS runtime maintenance**
75+
76+
[Note: As of 10/2019, SwingJS is still a collection of Java code from a variety of sources. There is some original Apache Java code from before 2016, and there is code that is a mix of Java6 and Java8. Some of the core java.lang classes are created in j2sClazz.js directly, disregarding the class files in src. I realize this makes maintenance challenging, but that is the way it is. It's a volunteer operation....]
77+
78+
As Java evolves, new packages, classes, and methods are added. Some classes are deprecated and perhaps even removed. For example, the java.util.stream package was added in Java 8, and along with that, several core java.lang classes and interfaces (such as java.lang.String) were augmented to include stream-based methods. There have also been a number of cases where generic classes have been converted to typed classes. For example, staring in Java 7, javax.swing.JComboBox became javax.swing.JComboBox<E>. To date, this has not been an issue. (Particularly in the area of generics, java2script uses an aliasing scheme to refer to the same method by different names so that code from different Java versions still runs appropriately. -- For example, java.util.Calendar.compareTo is aliased as
79+
80+
compareTo$java\_util\_Calendar, compareTo$, and compareTo$TT
81+
82+
Java 11 makes a huge leap in the handling of String and char. SwingJS will have to be maintained to keep up with these changes.
83+
84+
The important thing here is to maintain backward compatibility at all times. It is critical that any changes to SwingJS do not break the running of code from older versions of Java. We do not have the luxury in SwingJS of packaging code with its own JRE (other than the obvious fact that you can put whatever you want into site/swingjs/j2s on your own web site).
85+
86+
So, basically, you can add to or modify any of the several thousand classes in j2s.net.sf.java.core/src. Just be careful to allow for what is already there to still run. Adding a new class can be a challenge. Note that we have not implemented serialization or accessibility. This was a design decision based on need. We needed applet code to run, and these two features added far too much complexity to the task. So we ignored them. (Serialization, in particular, is probably not ever going to work in JavaScript, because the java2script transpiler does not preserve enough information about variable types to make that work properly.)
87+
2988

30-
Bob Hanson 2019.06.07.
89+
Bob Hanson 2019.10.13
3190

3291

3392

1.76 KB
Binary file not shown.

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

Lines changed: 67 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -3045,81 +3045,76 @@ void resetGC() {
30453045
// }
30463046
}
30473047

3048-
/**
3049-
* Sets the location of the window relative to the specified
3050-
* component.
3051-
* <p>
3052-
* If the component is not currently showing, or <code>c</code>
3053-
* is <code>null</code>, the window is placed at the center of
3054-
* the screen. The center point can be determined with {@link
3055-
* GraphicsEnvironment#getCenterPoint GraphicsEnvironment.getCenterPoint}
3056-
* <p>
3057-
* If the bottom of the component is offscreen, the window is
3058-
* placed to the side of the <code>Component</code> that is
3059-
* closest to the center of the screen. So if the <code>Component</code>
3060-
* is on the right part of the screen, the <code>Window</code>
3061-
* is placed to its left, and vice versa.
3062-
*
3063-
* @param c the component in relation to which the window's location
3064-
* is determined
3065-
* @see java.awt.GraphicsEnvironment#getCenterPoint
3066-
* @since 1.4
3067-
*/
3068-
public void setLocationRelativeTo(Component c) {
3069-
Container root=null;
3070-
3071-
if (c != null) {
3072-
if (c.isWindowOrJSApplet()) {
3073-
root = (Container)c;
3074-
} else {
3075-
Container parent;
3076-
for(parent = c.getParent() ; parent != null ; parent = parent.getParent()) {
3077-
if (parent.isWindowOrJSApplet()) {
3078-
root = parent;
3079-
break;
3080-
}
3081-
}
3082-
}
3083-
}
3084-
3085-
if((c != null && !c.isShowing()) || root == null ||
3086-
!root.isShowing()) {
3087-
Dimension paneSize = getSize();
3048+
/**
3049+
* Sets the location of the window relative to the specified component.
3050+
* <p>
3051+
* If the component is not currently showing, or <code>c</code> is
3052+
* <code>null</code>, the window is placed at the center of the screen. The
3053+
* center point can be determined with {@link GraphicsEnvironment#getCenterPoint
3054+
* GraphicsEnvironment.getCenterPoint}
3055+
* <p>
3056+
* If the bottom of the component is offscreen, the window is placed to the side
3057+
* of the <code>Component</code> that is closest to the center of the screen. So
3058+
* if the <code>Component</code> is on the right part of the screen, the
3059+
* <code>Window</code> is placed to its left, and vice versa.
3060+
*
3061+
* @param c the component in relation to which the window's location is
3062+
* determined
3063+
* @see java.awt.GraphicsEnvironment#getCenterPoint
3064+
* @since 1.4
3065+
*/
3066+
public void setLocationRelativeTo(Component c) {
3067+
Container root = null;
3068+
3069+
if (c != null) {
3070+
if (c.isWindowOrJSApplet()) {
3071+
root = (Container) c;
3072+
} else {
3073+
Container parent;
3074+
for (parent = c.getParent(); parent != null; parent = parent.getParent()) {
3075+
if (parent.isWindowOrJSApplet()) {
3076+
root = parent;
3077+
break;
3078+
}
3079+
}
3080+
}
3081+
}
30883082

3089-
Point centerPoint = GraphicsEnvironment.getLocalGraphicsEnvironment().getCenterPoint();
3090-
setLocation(centerPoint.x - paneSize.width / 2,
3091-
centerPoint.y - paneSize.height / 2);
3092-
} else {
3093-
Dimension invokerSize = c.getSize();
3094-
Point invokerScreenLocation = c.getLocationOnScreen();
3095-
3096-
Rectangle windowBounds = getBounds();
3097-
int dx = invokerScreenLocation.x+((invokerSize.width-windowBounds.width)>>1);
3098-
int dy = invokerScreenLocation.y+((invokerSize.height - windowBounds.height)>>1);
3099-
Rectangle ss = root.getGraphicsConfiguration().getBounds();
3100-
3101-
// Adjust for bottom edge being offscreen
3102-
if (dy+windowBounds.height>ss.y+ss.height) {
3103-
dy = ss.y + ss.height-windowBounds.height;
3104-
if (invokerScreenLocation.x - ss.x + invokerSize.width / 2 <
3105-
ss.width / 2) {
3106-
dx = invokerScreenLocation.x+invokerSize.width;
3107-
}
3108-
else {
3109-
dx = invokerScreenLocation.x-windowBounds.width;
3110-
}
3111-
}
3083+
if ((c != null && !c.isShowing()) || root == null || !root.isShowing()) {
3084+
Dimension paneSize = getSize();
3085+
Point centerPoint = GraphicsEnvironment.getLocalGraphicsEnvironment().getCenterPoint();
3086+
setLocation(centerPoint.x - paneSize.width / 2, centerPoint.y - paneSize.height / 2);
3087+
} else {
3088+
Dimension invokerSize = c.getSize();
3089+
Point invokerScreenLocation = c.getLocationOnScreen();
3090+
3091+
Rectangle windowBounds = getBounds();
3092+
int dx = invokerScreenLocation.x + ((invokerSize.width - windowBounds.width) >> 1);
3093+
int dy = invokerScreenLocation.y + ((invokerSize.height - windowBounds.height) >> 1);
3094+
Rectangle ss = root.getGraphicsConfiguration().getBounds();
3095+
3096+
// Adjust for bottom edge being offscreen
3097+
if (dy + windowBounds.height > ss.y + ss.height) {
3098+
dy = ss.y + ss.height - windowBounds.height;
3099+
if (invokerScreenLocation.x - ss.x + invokerSize.width / 2 < ss.width / 2) {
3100+
dx = invokerScreenLocation.x + invokerSize.width;
3101+
} else {
3102+
dx = invokerScreenLocation.x - windowBounds.width;
3103+
}
3104+
}
31123105

3113-
// Avoid being placed off the edge of the screen
3114-
if (dx+windowBounds.width > ss.x + ss.width) {
3115-
dx = ss.x + ss.width - windowBounds.width;
3116-
}
3117-
if (dx < ss.x) dx = ss.x;
3118-
if (dy < ss.y) dy = ss.y;
3106+
// Avoid being placed off the edge of the screen
3107+
if (dx + windowBounds.width > ss.x + ss.width) {
3108+
dx = ss.x + ss.width - windowBounds.width;
3109+
}
3110+
if (dx < ss.x)
3111+
dx = ss.x;
3112+
if (dy < ss.y)
3113+
dy = ss.y;
31193114

3120-
setLocation(dx, dy);
3121-
}
3122-
}
3115+
setLocation(dx, dy);
3116+
}
3117+
}
31233118

31243119
/**
31253120
* Overridden from Component. Top-level Windows should not propagate a

sources/net.sf.j2s.java.core/src/java/awt/image/BufferedImage.java

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1420,6 +1420,7 @@ public int getTileGridYOffset() {
14201420
* @exception <code>ArrayIndexOutOfBoundsException</code> if both
14211421
* <code>tileX</code> and <code>tileY</code> are not equal to 0
14221422
*/
1423+
@Override
14231424
public Raster getTile(int tileX, int tileY) {
14241425
// SwingJS not implemented
14251426
// if (tileX == 0 && tileY == 0) {
@@ -1436,6 +1437,7 @@ public Raster getTile(int tileX, int tileY) {
14361437
* @return a <code>Raster</code> that is a copy of the image data.
14371438
* @see #setData(Raster)
14381439
*/
1440+
@Override
14391441
public Raster getData() {
14401442

14411443
// REMIND : this allocates a whole new tile if raster is a
@@ -1470,6 +1472,7 @@ public Raster getData() {
14701472
* specified region of the <code>BufferedImage</code>
14711473
* @see #setData(Raster)
14721474
*/
1475+
@Override
14731476
public Raster getData(Rectangle rect) {
14741477
SampleModel sm = raster.getSampleModel();
14751478
SampleModel nsm = sm.createCompatibleSampleModel(rect.width, rect.height);
@@ -1502,6 +1505,7 @@ public Raster getData(Rectangle rect) {
15021505
* image, or <code>null</code>
15031506
* @return a reference to the supplied or created <code>WritableRaster</code>.
15041507
*/
1508+
@Override
15051509
public WritableRaster copyData(WritableRaster outRaster) {
15061510
if (outRaster == null) {
15071511
return (WritableRaster) getData();
@@ -1717,6 +1721,15 @@ public void setPixels() {
17171721
秘havePix = true;
17181722
}
17191723

1724+
1725+
@Override
1726+
public void flush() {
1727+
// call this method after drawing to ensure that
1728+
// pixels are recreated from the HTML5 canvas
1729+
秘pix = null;
1730+
秘havePix = false;
1731+
// was for surfaceManager only super.flush();
1732+
}
17201733
/**
17211734
* convert [r g b a r g b a ...] into [argb argb argb ...]
17221735
*
@@ -1778,9 +1791,10 @@ public Graphics2D getImageGraphic() {
17781791
* pix.img = this;
17791792
*
17801793
*/
1781-
{
1782-
}
1783-
秘pix = null;
1794+
1795+
// 秘pix = null;
1796+
flush(); // also setting 秘havePix false
1797+
17841798
}
17851799
Graphics2D g2d = (Graphics2D) (Object)秘g;
17861800
if (秘component != null) {

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import java.awt.Graphics2D;
3838
import java.awt.HeadlessException;
3939
import java.awt.LayoutManager;
40+
import java.awt.Point;
4041

4142
/**
4243
* An extended version of <code>java.applet.Applet</code> that adds support for
@@ -641,4 +642,14 @@ protected String paramString() {
641642
// protected class AccessibleJApplet extends AccessibleApplet {
642643
// // everything moved to new parent, AccessibleApplet
643644
// }
645+
646+
/**
647+
* SwingJS needs this for the applet
648+
* because the jQuery.offset() call does not work for it directly.
649+
*/
650+
@Override
651+
public Point getLocationOnScreen() {
652+
return (isShowing() ? getRootPane().getLocationOnScreen() : null);
653+
}
654+
644655
}

0 commit comments

Comments
 (0)