Skip to content

Commit 412049a

Browse files
authored
Merge pull request #129 from BobHanson/master
various updates
2 parents ff0cda6 + 0f48c0c commit 412049a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+2972
-2826
lines changed
7.81 MB
Binary file not shown.
5.68 MB
Binary file not shown.
38.3 KB
Binary file not shown.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
20190923090813
1+
20191008173421
38.3 KB
Binary file not shown.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
20190923090813
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

38.3 KB
Binary file not shown.

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

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -109,21 +109,21 @@ public Card(String cardName, Component cardComponent) {
109109
*/
110110
int vgap;
111111

112-
/**
113-
* @serialField tab Hashtable
114-
* deprectated, for forward compatibility only
115-
* @serialField hgap int
116-
* @serialField vgap int
117-
* @serialField vector Vector
118-
* @serialField currentCard int
119-
*/
120-
private static final ObjectStreamField[] serialPersistentFields = {
121-
new ObjectStreamField("tab", Hashtable.class),
122-
new ObjectStreamField("hgap", Integer.TYPE),
123-
new ObjectStreamField("vgap", Integer.TYPE),
124-
new ObjectStreamField("vector", Vector.class),
125-
new ObjectStreamField("currentCard", Integer.TYPE)
126-
};
112+
// /**
113+
// * @serialField tab Hashtable
114+
// * deprectated, for forward compatibility only
115+
// * @serialField hgap int
116+
// * @serialField vgap int
117+
// * @serialField vector Vector
118+
// * @serialField currentCard int
119+
// */
120+
// private static final ObjectStreamField[] serialPersistentFields = {
121+
// new ObjectStreamField("tab", Hashtable.class),
122+
// new ObjectStreamField("hgap", Integer.TYPE),
123+
// new ObjectStreamField("vgap", Integer.TYPE),
124+
// new ObjectStreamField("vector", Vector.class),
125+
// new ObjectStreamField("currentCard", Integer.TYPE)
126+
// };
127127

128128
/**
129129
* Creates a new card layout with gaps of size zero.

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

0 commit comments

Comments
 (0)