seeking advice on where to initialize Canvas for classes that implement Drawable

3 views
Skip to first unread message

Jacob Beard

unread,
Jun 6, 2009, 6:21:47 PM6/6/09
to java2script, Vineet Sinha
Hi all,

Hooking GC up to Sebastian's Canvas is going very well. I think in
a day or two, I might have some very nice demos to show. Right now,
I'm trying to determine what is the best place to initialize the
Canvas itself.

I now have a pure Java question. It seems like, semantically we
would like to say that whatever class implements Drawable should be
able to be drawn on. Procedurally, I imagine that when the time comes
to instantiate a new GC from a Control that implements Drawable, the
constructor for GC should instantiate the Canvas if it is not already
instantiated. I think it is important to defer instantiation of the
Canvas, because, in general, the developer will not want to draw on
each SWT element, and thus it would be wasteful to instantiate a new
DOM node for each SWT element.

The way I originally thought to accomplish this was to put a
_canvas attribute in the Drawable interface. We've already established
that putting data into an interface is rather dangerous and generally
frowned upon. Also, if we put a canvas attribute inside of the
Drawable interface, I believe it would have to be static and final.
Final might be OK (although it would make deferred initialization
difficult), but static I think would not work at all, as each Drawable
instance needs to aggregate its own canvas. We just sort of want an
attribute mixin for Drawable; but Java doesn't support this. So I'm
not quite sure what is the best way to accomplish this task.

I'd greatly appreciate any guidance anyone can provide.

Thanks,

Jake

Jacob Beard

unread,
Jun 7, 2009, 12:21:40 PM6/7/09
to java2script, Vineet Sinha
Hi all,

I think I figured out what is the optimal way to handle this. I
realized it would be wrong to put platform-specific code in the
Drawable interface, because SWT pretty clearly enumerates places where
platform-specific code should go. One place where platform-specific
code can go is in GC, and thus, it seems like it would make sense to
make GC responsible for keeping track of the (1-to-0-or-1)
relationships between Drawables and their Canvases. I'll do this by
creating a platform-specific, private final static Hashtable attribute
on GC which maps Drawables to Canvases. When a new GC is created from
a Drawable, the GC looks the Drawable up in the Hashtable and returns
the corresponding Canvas, if it exists. If it doesn't exist, it
instantiates the Canvas and puts it in the Hash.

The way I see it, this will only fail if the Drawable needs to access
its Canvas itself. I'm not sure if there's a case where it would need
to do that... Maybe when changing the location of the Drawable
(dragging-and-dropping)? You would want the Canvas to track as well.
Please let me know what you think about this.

In hooking up the above implementation, I found a bug in Hashtable:

https://sourceforge.net/tracker/?func=detail&aid=2802552&group_id=155436&atid=795800

This appears to be a serious bug that needs to be resolved for me to
complete the above implementation, but it is not blocking me from
continuing to hook GC into Canvas.

Thanks,

Jake

Zhou Renjian

unread,
Jun 7, 2009, 8:12:16 PM6/7/09
to java2...@googlegroups.com
Hi Jake,

For a quick fix for the bug you filed, add @J2SKeep or @j2sKeep javaDoc like the following:
    /**
     * @j2sKeep
     */
    private static <K, V> Entry<K, V> newEntry(K key, V value, int hash) {
        return new Entry<K, V>(key, value);
    }
This bug is a compiler bug. We will fix it later.

We actually do not recommend you to use Hashtable if you take JavaScript performance into consideration. Use JavaScript Object's properties for Hashtable may be a better way.

BTW: Here is the tutorial of @j2s* : http://j2s.sourceforge.net/articles/tutorial-advanced-programming-on-j2s.html

Regards,
Zhou Renjian

--
http://webuzz.im/ Web IMs (G/A/M/Y)
http://j2s.sourceforge.net/ Java2Script

Jake B

unread,
Jun 7, 2009, 9:19:43 PM6/7/09
to java2...@googlegroups.com
Hi Zhou,

JavaScript object properties are well known to me, however, I'm not
clear, how would you recommend I use them from Java with Java2Script?

Please let me know. Thanks,

Jake

Jake B

unread,
Jun 7, 2009, 10:19:51 PM6/7/09
to java2...@googlegroups.com, Vineet Sinha
Hi Zhou,

I just thought I should mention, I think I've discovered the proper
(read, SWT-centric) solution to the problem of how to initialize GC
and Canvas.

First, I discovered that Drawable is implemented by only three
classes: Image, Device, and Control. For some reason, the JavaDoc[0]
had confused me about this, and I thought that about 30-some classes
implemented Drawable. So, this will make injecting platform-specific
logic much faster, cleaner and easier.

I also discovered that methods relating to the internal platform live
in Drawable, namely internal_dispose_GC and internal_new_GC. So, it's
OK to put platform-specific code in Drawable and abstract
implementations.

The pattern for initializing GC and Canvas then appears to be as follows:

In its constructor, GC instantiates a new, empty GCData, which is a
pure data container with a number of uninitialized fields relating to
the underlying platform and its configuration. GC's constructor then
calls internal_GC_create on the Drawable passed into its constructor,
passing in the new GCData. The Drawable takes care of initializing the
GCData instance (which has been passed in by reference).

The attributes of GCData may include an adapter that exposes the
underlying drawing API, so something like Sprite for Flash or Surface
for a drawing API based on Dojo. For our current implementation, it
will be Sebastian's Canvas.

Also for our purposes, each class that implements Drawable can also
maintain a private, platform-specific attribute to keep the Canvas. It
will get intialized during the first call to internal_GC_create, and
gets returned in each call thereafter.

That's it! Tomorrow I hope to glue it all together, and start to hook
up the logic that maps GC's API to Canvas's API. I'll let you know how
it goes.

Jake
[0] http://help.eclipse.org/stable/nftopic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/graphics/Drawable.html

Zhou Renjian

unread,
Jun 8, 2009, 9:17:39 AM6/8/09
to java2...@googlegroups.com
Hi Jake,

I meant that if your Java classes are only run in JavaScript environment, you can modify your codes into a mixture of Java and JavaScript codes for a better performance.

In my opinion, importing java.util.Hashtable may require lots of *.js being loaded, and it is not running very fast too. So modify your Hashtable member into an JavaScript Object member and use its properties to store key and value. It will load less and run faster.


Regards,
Zhou Renjian

--
http://webuzz.im/ Web IMs (G/A/M/Y)
http://j2s.sourceforge.net/ Java2Script


Jake B

unread,
Jun 8, 2009, 9:23:55 AM6/8/09
to java2...@googlegroups.com
Hi Zhou,

> So modify your Hashtable member
> into an JavaScript Object member and use its properties to store key and
> value. It will load less and run faster.

I'm just not clear, is there a Java wrapper class around JavaScript
object for Java2Script, like GWT's JavaScriptObject class? If you
could give me a code snippet, that will help me better understand what
you mean.

Thanks,

Jake

Zhou Renjian

unread,
Jun 8, 2009, 9:31:33 AM6/8/09
to java2...@googlegroups.com
In JavaScript, we use @J2SNative annotation or @j2sNative javaDoc to do so, like the following:

class A {
  private Object o;
  public void put(String k, String v) {
    if (k != null)
    /** @j2sNative
     *  this.o[k]=v;
     */ {}
  }
  public void get(String k) {
    /** @j2sNative
     *  return this.o[k];
     */ {}
  }
}

or

class A {
  private Object o;
  /**
   * @j2sNative
   * this.o[k]=v;
   */
  public void put(String k, String v) {
  }
  /**
   * @j2sNative
   * return this.o[k];
   */
  public native void get(String k);

}

Regards,
Zhou Renjian

--
http://webuzz.im/ Web IMs (G/A/M/Y)
http://j2s.sourceforge.net/ Java2Script


Jake B

unread,
Jun 8, 2009, 9:41:11 AM6/8/09
to java2...@googlegroups.com
Got it. Thanks :)

Jake

Jake B

unread,
Jul 1, 2009, 1:36:56 AM7/1/09
to java2...@googlegroups.com, Vineet Sinha
Hi all,

I just wanted to report that I have made some progress. I'm not quite
sure what is the best way to deploy a Java2Script application (any
pointers on this would be appreciated), but here's a quick screenshot
showing some of my results:

http://jacobbeard.net/research/Screenshot-Mozilla%20Firefox-j2sCanvas.png

The graphics there were compiled using Java2Script, use SWT GC API's,
and target HTML canvas. It's an incomplete implementation of GC, but a
full implementation is, I think, quite feasible. This is now fairly
low risk, and I'd estimate it to be about a week of work to finish
implementing GC on top of HTML canvas.

Rather than pursue this, I'd like to now drill down on what appear to
me to be two higher-risk problems:
1. Getting more sophisticated uses of GC to work, for example
org.eclipse.swt.examples.graphics.GraphicsExample from the
org.eclipse.swt.examples project.
2. Getting more sophisticated libraries that target GC to work on top
of Java2Script, specifically Draw2d.

I have so far encountered challenges with both of these.

For 1., it is still unclear what the best solution is for emulating
PaintListener, which is what many GC demos require. I feel we should
reopen the discussion regarding what is the best way to emulate this.

There were other technical challenges that I encountered for 1. and 2.
When attempting to run the compiled
org.eclipse.swt.examples.graphics.GraphicsExample the compiled version
of caused Firefox 3.0 to hang, it seems when it was trying to load
Tree.z.js. For 2., when attempting to run the compiled Draw2d Hello
World demo (org.eclipse.draw2d.exmpales/org.eclipse.draw2d.examples.HelloWorld),
I got errors in core.z.js, about too much recursion. I don't really
have a sense of how to debug issues like these. They seem to be
compiler issues, and I feel like I'm not really in a position to delve
deep into the inner workings of the j2s compiler. Hence my inclination
is to flag 1. and 2. as high-risk. I'd appreciate any insight you
might have as to how to track down what might be causing these
problems, as well as to whether it would be worthwhile to file bug
reports for them.

Also, I wonder if it might be worthwhile to open a discussion
regarding the feasibility of using GWT compiler in place of the
Java2Script compiler, as was mentioned on the e4-dev list. This might
help solve some of the above issues. Or it might tremendously
complicate things :P

I have two final small questions:
* What is the easiest way to deploy Java2Script applications to a
normal web server (no servlet container)?
* How can I tell Java2Script to import external JavaScript resources
like excanvas.js?

Please let me know what you think. Thanks,

Jake

2009/6/8 Jake B <otak...@gmail.com>:

Vineet Sinha

unread,
Jul 1, 2009, 8:32:55 AM7/1/09
to Jake B, java2...@googlegroups.com
Jake,
Glad to hear that you had good results.

I completely agree, finishing GC on top of HTML canvas is perhaps the
lowest priority among those you listed.

Also, based on my experience (and I thought I mentioned this earlier)
I think the highest risk for such a project is in getting external
libraries to compile and to run, i.e. No 2 below. This is also part of
the reason, I feel like merging with GWT might be better - though it
might be alot of work also.

So I would definitely suggest having null implementations for the
other two cases and focusing on getting Draw2D bulit. Note that GEF
and GMF will likely raise more compiler issues than Draw2D - but just
getting Draw2D working will be a good milestone.

Vineet

Sebastian Gurin

unread,
Jul 1, 2009, 9:27:00 AM7/1/09
to java2...@googlegroups.com, Jake B, Vineet Sinha
Hi Jake, congratulations for your work. It looks promising...

On Wed, 1 Jul 2009 01:36:56 -0400
Jake B <otak...@gmail.com> wrote:

> I have two final small questions:
> * What is the easiest way to deploy Java2Script applications to a
> normal web server (no servlet container)?

This is what I do: make a copy of j2slib directory inside your java2script project's folder. Right click in the compilation unit you want to run -> Run configurations... -> Miscellaneous -> check "use global .js url -> and specify your j2slib directory in "J2Slib base URL", for example, "j2slib". This way you have both, your application and j2slib resources inside your project's directory and so, you only have to copy your project directory to your html server (and perhaps rename some .html to index.html for the default page).

> * How can I tell Java2Script to import external JavaScript resources
> like excanvas.js?
>

That depends on the script. If it is a simple script, you can include its source code in any java compilation unit using @j2sPrefix in the main class comment (see for example org.sgx.j2s.canvas.Canvas in my example project mathWebThings)

Nevertheless, some scripts need to be included in <head> before the DOM is loaded so the last sollution will not work. In this case, you must include a <script src="yourscript.js"> in document's <head>. For this, again, go to Run configurations -> HTML -> and include a <script> element in, for example, "header of header" section.

good look.
--
Sebastian Gurin <sgu...@softpoint.org>

Zhou Renjian

unread,
Jul 1, 2009, 12:29:21 PM7/1/09
to java2...@googlegroups.com
On Wed, Jul 1, 2009 at 1:36 PM, Jake B <otak...@gmail.com> wrote:

Hi all,

I just wanted to report that I have made some progress. I'm not quite
sure what is the best way to deploy a Java2Script application (any
pointers on this would be appreciated), but here's a quick screenshot
showing some of my results:

http://jacobbeard.net/research/Screenshot-Mozilla%20Firefox-j2sCanvas.png

Congratulations!
 


The graphics there were compiled using Java2Script, use SWT GC API's,
and target HTML canvas. It's an incomplete implementation of GC, but a
full implementation is, I think, quite feasible. This is now fairly
low risk, and I'd estimate it to be about a week of work to finish
implementing GC on top of HTML canvas.

Rather than pursue this, I'd like to now drill down on what appear to
me to be two higher-risk problems:
1. Getting more sophisticated uses of GC to work, for example
org.eclipse.swt.examples.graphics.GraphicsExample from the
org.eclipse.swt.examples project.
2. Getting more sophisticated libraries that target GC to work on top
of Java2Script, specifically Draw2d.

Draw2D is complicated, and GEF would be much more complicated. No body has been there until someone reaches there step by step.



I have so far encountered challenges with both of these.

For 1., it is still unclear what the best solution is for emulating
PaintListener, which is what many GC demos require. I feel we should
reopen the discussion regarding what is the best way to emulate this.

It seems that PaintListener is a necessary for you.

One of the key question to emulating PaintListener is what is the time to send an SWT.Paint event: When canvas is created, resized, destroyed? Sending too much SWT.Paint events will make the whole UI very slow.

You can change
protected boolean SetWindowPos(Object hWnd, Object hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);
to send out an SWT.Paint event. You'd better using a delayed thread to send out event.
 


There were other technical challenges that I encountered for 1. and 2.
When attempting to run the compiled
org.eclipse.swt.examples.graphics.GraphicsExample the compiled version

In my environment GraphicsExample is loading as expected, no browser freezing. And this might be a bug that we need to dig it out.


of caused Firefox 3.0 to hang, it seems when it was trying to load
Tree.z.js. For 2., when attempting to run the compiled Draw2d Hello
World demo (org.eclipse.draw2d.exmpales/org.eclipse.draw2d.examples.HelloWorld),
I got errors in core.z.js, about too much recursion. I don't really

Too much recursion might be a defect of Java2Script. Try to avoid polymorphous constructors or methods like

Hello(int x) {
    this(0L);
}

Hello(long x) {
    this.x = x;
}

Java2Script might not distinguish some data types, like all short, int, long, float, dobule are Number. and String, Object and arrays might confuse Java2Script.

Try to find out methods that are cuasing problems. Comment out some methods or ignore all other methods leaving only one method by using @j2sIgnore and merge all those methods into one method using @j2sNative Javadoc. ...

Hope this information helps.


have a sense of how to debug issues like these. They seem to be
compiler issues, and I feel like I'm not really in a position to delve
deep into the inner workings of the j2s compiler. Hence my inclination
is to flag 1. and 2. as high-risk. I'd appreciate any insight you
might have as to how to track down what might be causing these
problems, as well as to whether it would be worthwhile to file bug
reports for them.

Also, I wonder if it might be worthwhile to open a discussion
regarding the feasibility of using GWT compiler in place of the
Java2Script compiler, as was mentioned on the e4-dev list. This might
help solve some of the above issues. Or it might tremendously
complicate things :P

I consider the two compilers may have a big gap to fill.



I have two final small questions:
* What is the easiest way to deploy Java2Script applications to a
normal web server (no servlet container)?

You do not need a servlet container to deploy Java2Script applications. Just copy folder "j2slib" and all your *.js, *.css, *.html, image files to an HTTP server. You may need to modify your entry *.html a little bit, correcting the relative path according to your server path.


* How can I tell Java2Script to import external JavaScript resources
like excanvas.js?

What about creating a new EXCanvas.java and wrapping excanvas.js content using @j2sPrefix Javadoc like:
/**
 * @j2sPrefix
/-*! ....comments
-*-/
var swfobject = function() {
...
}
 */
public class FlashUtils {
    public static boolean isFlashEnabled() {
        return true;
    }
}

We do NOT recommend to use internal Java2Script ClassLoader API for loading external *.js file.

Jake B

unread,
Jul 1, 2009, 1:38:26 PM7/1/09
to java2...@googlegroups.com, Vineet Sinha
Hi Sebastian,

Replies below:

On Wed, Jul 1, 2009 at 9:27 AM, Sebastian Gurin<sgu...@softpoint.org> wrote:
>
> Hi Jake, congratulations for your work. It looks promising...
>
> On Wed, 1 Jul 2009 01:36:56 -0400
> Jake B <otak...@gmail.com> wrote:
>
>> I have two final small questions:
>> * What is the easiest way to deploy Java2Script applications to a
>> normal web server (no servlet container)?
>
> This is what I do: make a copy of j2slib directory inside your java2script project's folder. Right click in the compilation unit you want to run -> Run configurations... -> Miscellaneous -> check "use global .js url -> and specify your j2slib directory in "J2Slib base URL", for example, "j2slib". This way you have both, your application and j2slib resources inside your project's directory and so, you only have to copy your project directory to your html server (and perhaps rename some .html to index.html for the default page).

That worked, although it was a bit confusing how I needed to have my
j2slib folder inside of another folder (e.g. "lib/j2slib"; "lib" gets
assigned to "base", and "j2slib" gets assigned to "alias"). I was
actually able to use symlinks to link up to net.sf.j2s.lib/j2slib/,
which is in my workspace. rsync then transparently copied the links
over. Here it is being hosted:

http://jacobbeard.net/research/gsoc2009/testj2s/Snippet50.html

Which is generated from this:

http://jacobbeard.net/research/gsoc2009/testj2s/src/Snippet50.java

>
>> * How can I tell Java2Script to import external JavaScript resources
>> like excanvas.js?
>>
>
> That depends on the script. If it is a simple script, you can include its source code in any java compilation unit using @j2sPrefix in the main class comment (see for example org.sgx.j2s.canvas.Canvas in my example project mathWebThings)
>
> Nevertheless, some scripts need to be included in <head> before the DOM is loaded so the last sollution will not work. In this case, you must include a <script src="yourscript.js"> in document's <head>. For this, again, go to Run configurations -> HTML -> and include a <script> element in, for example, "header of header" section.

I used the run configuration option. The problem with j2sPrefix, in my
mind, is that the JavaScript code must be inlined. When the scripts
are part of their own libraries and are nontrivial, it seems like they
should be kept in their own files so that they can continue to be
version-controlled. It might be worthwhile to add a feature to the j2s
compiler that works like j2sPrefix, but specifies a path to an
external js file, which then gets inlined.

Thanks again for your advice, it was very useful in helping me get set up.

Jake

Sebastian Gurin

unread,
Jul 1, 2009, 2:50:37 PM7/1/09
to java2...@googlegroups.com, Jake B, Vineet Sinha

hi Jake

On Wed, 1 Jul 2009 13:38:26 -0400
Jake B <otak...@gmail.com> wrote:

> That worked, although it was a bit confusing how I needed to have my
> j2slib folder inside of another folder (e.g. "lib/j2slib"; "lib" gets
> assigned to "base", and "j2slib" gets assigned to "alias"). I was
> actually able to use symlinks to link up to net.sf.j2s.lib/j2slib/,
> which is in my workspace. rsync then transparently copied the links
> over. Here it is being hosted:

First of all, I recommend you to build the html NOT using firefox extension support. The j2s application launcher code is more simpler. This is the launcher code without firefox extension support and "use global url" == "lib/j2slib"

ClazzLoader.packageClasspath ("java", "lib/j2slib/", true);
ClazzLoader.setPrimaryFolder ("bin/");
ClazzLoader.packageClasspath ([.......], "bin/");
ClazzLoader.loadClass ("org.sgx.AppsMenu", function () {
org.sgx.AppsMenu.main([]);
});

As you can see the important relative path to configure are j2slib folder .js output folder (usually the same of .class output folder). You can configure j2slib folder in run configurations. You can configure your .j2s output dir editing your project's .j2s file, variable 2s.output.path.

Note that you can have j2slib folder in a separate project (for example, using ClazzLoader.packageClasspath ("java", "../j2slib/", true); so several java2script applications can make use of the same j2slib files...

If you need to support firefox extension, I think the important property is "base" and not "alias"

hope that helps

good look, your archivmennts look great.... I think a fully GC implementation can be a great tool for people migrating existing swt apps to the browser..

>
> http://jacobbeard.net/research/gsoc2009/testj2s/Snippet50.html
>
> Which is generated from this:
>
> http://jacobbeard.net/research/gsoc2009/testj2s/src/Snippet50.java
>
> >
> >> * How can I tell Java2Script to import external JavaScript resources
> >> like excanvas.js?
> >>
> >
> > That depends on the script. If it is a simple script, you can include its source code in any java compilation unit using @j2sPrefix in the main class comment (see for example org.sgx.j2s.canvas.Canvas in my example project mathWebThings)
> >
> > Nevertheless, some scripts need to be included in <head> before the DOM is loaded so the last sollution will not work. In this case, you must include a <script src="yourscript.js"> in document's <head>. For this, again, go to Run configurations -> HTML -> and include a <script> element in, for example, "header of header" section.
>
> I used the run configuration option. The problem with j2sPrefix, in my
> mind, is that the JavaScript code must be inlined. When the scripts
> are part of their own libraries and are nontrivial, it seems like they
> should be kept in their own files so that they can continue to be
> version-controlled. It might be worthwhile to add a feature to the j2s
> compiler that works like j2sPrefix, but specifies a path to an
> external js file, which then gets inlined.
>
> Thanks again for your advice, it was very useful in helping me get set up.
>
> Jake
>
> >


--
Sebastian Gurin <sgu...@softpoint.org>
Reply all
Reply to author
Forward
0 new messages