Jump to content
Excelsior Forums
jsiepkes

Excelsior JET + JNA to get a transparent window

Recommended Posts

Hi all,

Sometime I ago I did a quick evaluation of Excelsior JET for a project I am working on. Now that the project is more concrete I'm doing a more in depth evaluation of Excelsior JET to determine if we can you use for our project. I really like the fact that everything is compiled AOT which simplifies deployment, protects code and speeds up start up time.

However I'm encountering a bit of a show stopper; I need a Window with a transparent background (Per-pixel transparency / Alpha channel transparency). With the standard Sun JVM I achieved this with JNA (https://jna.dev.java.net/). After fixing the JNA Field issue (which is described here: http://www.excelsior-usa.com/forum/index.php?topic=1687.0 ) I got some nasty null pointer exceptions from the transparency code. I decided to try out the JNA balloon example to test the JNA and Excelsior JET combination in a simpler environment.

This is with the Sun JVM:

jnaSunBalloon.png

This is with the Jet JVM:

jnaJetBalloon.png

Even stranger is that when I run it on another PC with JET on it, the balloon looks even different (it has a piece on the right corner cut out of it), so something is definitely going wrong. I also tried the clock example; It also had issues with Excelsior JET. It was displaying graphical artefacts.

Besides setting the REQUIRES_FIELD_ORDER field to false I didn't modify anything in JNA or in the balloon example.

So I basically I have a couple of questions; How well does JNA currently work with Excelsior JET and is there an alternative way of getting a transparent Window with Excelsior JET ? Because the 'official' way ( http://java.sun.com/developer/technicalArticles/GUI/translucent_shaped_windows/ ) relies on com.sun stuff so thats not going to work with Excelsior JET.

I haven't tried it yet, but would doing the same thing with JNI instead of JNA make any difference ?

Regards,

Jasper

Edit: whoops, noticed that I incorreclty linked to the images.

Share this post


Link to post
Share on other sites

As far as I understand from the screenshots you have posted here, you have tried the example on Linux. So what Linux distro you have?

Please answer also what version of JNA you use as well as Sun JRE version and Excelsior JET version.

I have just tried JNA 3.1.0 with balloon example on Windows and RedHat Linux distros and the sample behaves equally on Excelsior JET 6.5 and on Sun JRE 1.6.0_12 (Java 6 Update 12).

Share this post


Link to post
Share on other sites

Hi Kit,

Your right, the Balloon Example works fine under windows, but it displays odd behaviour under Linux, weird. Well that's not really a problem for me since I'm only interested in Windows (for JET). I just develop under Linux. For completeness sake here are the Linux platforms I tested the balloon example on which have errors:

-Fedora 9 (2.6.27.25-78.2.56.fc9.i686) with JNA 3.1.0

-Fedora 10 with JNA 3.1.0

Both are fully updated and use Sun JVM 1.6.0_14

I used the balloon example because I thought it would make an easy test case, guess not  :). My real problem is the Window with alpha transparency.

If you look at the AlphaMaskDemo included with JNA that doesn't work for me on Windows or Linux (primary interested in Windows).  First it complains about the field order the JVM uses; I fixed that with a hard hack by setting "REQUIRES_FIELD_ORDER = false" in JNA's Structure.java. This allows the program to start but as soon as you drag an image with Alpha Channel on it it gives a NullPointerException and it doesn't work.

These are the JNA jars I used:

http://members.casema.nl/siepkes/jna.jar

http://members.casema.nl/siepkes/win32-x86.jar

So the jna.jar's Structure.java only has the field order hard hack. Other then that its just plain JNA 3.1.0.

The ShapedWindowDemo does work correctly, however the transparency used in that example just sets the alpha level of the entire application on a OS level, which is no good for me; I need per-pixel transparency (The BalloonExample also uses the alpha level set by the OS technique for the shadow, not per pixel transparency).

Share this post


Link to post
Share on other sites

I fixed that with a hard hack by setting "REQUIRES_FIELD_ORDER = false" in JNA's Structure.java.

That is not correct indeed. JNA documentation as well as the message clearly states that "you must use setFieldOrder". What does it mean?

For your "convenience" JNA assumes that "native" or "C" structures have the same filed order as declared in a successor of JNA's class "Structure" (that describes "native" structure). If a JVM returns getDeclareFileds in the source order than you "do not need" to use setFieldOrder method for your successor of Structure, else you must call it in the constructor of the class passing to it field names in the source order thus actually declaring explicitly native field order. Once you call setFieldOrder method, you may rearrange those field in the Java source as you like and everything will work on any JVM.

I think that JNA's authors name the method in a confusing way and do not document it well. The correct name would be setNativeFieldOrder or setNativeStructureLayout or simply defineLayout as it names in our own similar JNI proxy implementation xFunction (http://www.excelsior-usa.com/xfunction.html). Moreover, IMHO, it must be declared abstract in Structure (and is called automatically) to force JNA's users to implement it, else it implicitly incites them to write Java programs in non-compliant to Java specification way. Really, if Sun (aka Oracle) decides to change the order of fields in getDeclaredField method tomorrow (that is allowed to them by specification -- http://www.excelsior-usa.com/blog/excelsior-jet/a-tale-of-four-jvms-and-one-app-server) then all (yes all) applications that use JNA and do not call setFieldOrder method in their structures will stop working immediately! So the "convenience" I mentioned above is simply clumsy assistance.

Sorry for my lyric, let us return to the subject. What do you need to make the sample working? The sample uses OS specific classes such as com/sun/jna/examples/win32/GDI32. If you look inside if them, you will see a lot of classes extending Structure class, and yes, they do not use setFieldOrder. Continue? Yes, you have to call this method in constructors for all of them! For instance, let us take GDI32.RECT class. You have to add default constructor to it like this

        public RECT(){
            setFieldOrder(new String[]{"left", "top", "right", "bottom"});
        }

and so on ...

As JNA is open source, you may contribute the changes back to community since it would make JNA more compliant to Java specification.

Share this post


Link to post
Share on other sites

Why do you think so? Did you try it with JET?

Now that you mention it; I tried it under the same Linux installations which also failed to do the JET + JNA 'trick'. Back then they also failed the 'official' transparency + JET method. At the time I assumed this was because of the use of restricted API (com.sun.* stuff).

I tried the 'official' transparency method under Windows with JET and that works! I guess the JNA NullPointerException is probably due to some part of the JNA still not conforming to the Java Language spec ?

The Xorg libs in my F9 and F10 environment are probably somehow messed up in such a way they do not work correclty with JET. The only thing I can think of what these installations have in common is that they both have NX installed, which replaces some X libs.

This fixes my problem and makes it possible for us to use JET for the project, thanks for the help!

Share this post


Link to post
Share on other sites

I guess the JNA NullPointerException is probably due to some part of the JNA still not conforming to the Java Language spec ?

NulPointerException was because you hacked JNA incorrectly. JNA essentially relies that getDeclaredFields returns fields in the source order and hacking this dependency is not correct: if you set REQUIRES_FIELD_ORDER to false, then fields in native structure may be mapped to not correct fields of JNA's Structure in Java. Thus after calling some native function via JNA that fills native structure, its Java counterpart would be filled incorrectly and some field of it that must be filled may be null (or has not correct value) thus provoking NullPointerException.

So since JNA 3.0.5, authors add workaround for the problem: if you call setFieldOrder for all of your Structures then your program written in JNA would work on any JVM. So they shift responsibility  to be Java spec compliant from themselves to their users that is not honest IMHO. So you may now write programs in JNA in Java spec compliant way, but even their own samples are not Java spec compliant yet.

The Xorg libs in my F9 and F10 environment are probably somehow messed up in such a way they do not work correclty with JET. The only thing I can think of what these installations have in common is that they both have NX installed, which replaces some X libs.

I would check the balloon sample on our Fedora 9 installation. Would you point us what sample of "official way" have you tried on it to check it also?

Share this post


Link to post
Share on other sites

I would check the balloon sample on our Fedora 9 installation. Would you point us what sample of "official way" have you tried on it to check it also?

I tried the demo app which is attached to the article ( http://java.sun.com/developer/technicalArticles/GUI/translucent_shaped_windows/TranslucentShapes.zip ) on a F9 and F10 installation. But like I said I think my F9 and F10 X11 environments are borked.

Share this post


Link to post
Share on other sites

Does it work in Linux using the official JDK.

My guess is that you are running your desktop without a composition manager, which is required to get that transparency stuff working. Thats also the case for the official JDK.

- Clemens

Share this post


Link to post
Share on other sites

Does it work in Linux using the official JDK.

My guess is that you are running your desktop without a composition manager, which is required to get that transparency stuff working. Thats also the case for the official JDK.

I was running a compositing window manager at the time of the tests. As outlined in my first post my whole problem was that it worked with the official JDK, but not with JET.

Share this post


Link to post
Share on other sites

Jasper,

My understanding is that despite the fragile design of the JNA library, the problem you reported has been solved.

Please confirm.

Share this post


Link to post
Share on other sites

Sorry again for the late response, all kinds of work just keep messing up my schedule (yes I actually have a schedule :) )

I still encountered the problem with JNA 3.2.1, but like I said it doesnt pose a problem for me any more because I can achieve the same functionality trough a com.sun API which works in Excelsior JET.

So anybody who wants a JFrame with pixel alpha transparency can just use the instructions at http://java.sun.com/developer/technicalArticles/GUI/translucent_shaped_windows/ with Excelsior JET.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×