Saturday, May 12, 2007

Easier Alpha Masks

The per-pixel alpha masking in this post has been codified into a simple API.

WindowUtils.setWindowTransparent(Window w, boolean transparent);

This effectively gives the window a transparent background. The alpha levels of the window's contents are preserved.

The demo is similar to the previous one but adds a few standard components to the mix.



UPDATE If you have a linux system and this for some reason doesn't work, please post a comment to that effect, or post a message to users@jna.dev.java.net so we can ensure this works reliably across all linux systems (64-bit is in the works).

26 comments:

  1. Anonymous10:28 PM

    Cool! Can't wait to try this. I've noticed that if you hover your mouse on the button, the transparency jumps back to 100% (i.e. no transparency). I'm running JRE 1.6.0_01 on XP. Could be triggered by the repainting of the button (it gets a yellowish border when mouse is over it), because I doubt this is as per design... Also, do you know if this will work with desklets from Josh M.'s Glossitope project ?

    ReplyDelete
  2. Java source link is not working:

    Authorization Required

    This server could not verify that you are authorized to access the document requested. Either you supplied the wrong credentials (e.g., bad password), or your browser doesn't understand how to supply the credentials required.

    ReplyDelete
  3. Anonymous8:36 AM

    Great stuff!

    One small problem though:
    When you start dragging the image, the transparency is set back to opaque.

    ReplyDelete
  4. Francis,
    The alpha mask code is probably working at cross-purposes to the constant-alpha code, since on w32 they are two entirely different mechanisms. Shouldn't be that hard to fix.

    Josh said he was going to put shaped/mask support into Glossitope for JavaOne, but I don't know if he got it done in time. Romain Guy did include it in his Rich Clients presentation.

    redsolo,
    You may need a dev.java.net account to see the source; you can also try navigating directly to http://jna.dev.java.net and follow the SCM/Subversion browsing links.

    ReplyDelete
  5. Anonymous5:50 PM

    Can you post your code to glossitope.org? They urgently need it :-)

    ReplyDelete
  6. Anonymous9:21 PM

    Looks like Josh started integrating some of your new stuff into its Glossitope project. Getting better and better!

    ReplyDelete
  7. Anonymous4:01 AM

    I use this in a JFX app I have, and get a weird stack trace. Any ideas, what's going on?

    http://sellmic.com/lab/dev/jfx/clock/webstart/jna_stack_trace.txt

    Here's the app ...
    http://sellmic.com/blog/2007/05/22/javafx-clock-update-now-with-transparency/

    ReplyDelete
  8. You might try rebuilding the JNA example library from source. There have been significant changes to WindowUtils since the last library snapshot.

    Seems odd that it's a generic "Exception" that's thrown...

    ReplyDelete
  9. Thanks, downloaded the latest sources and recompiled (plus removed a lot of unused stuff in examples.jar) and it works great now.

    Somebody posted on my blog they were having problems in Ubuntu, wish I had an install to try it out.

    Thanks!!!

    ReplyDelete
  10. Wayne Meissner added some path searching code that should improve things for ubuntu users. A workaround for the old version is to set -Djna.library.path=/usr/lib and ensure that libX11.so is properly symlinked to libX11.so.6 (for some reason ubuntu doesn't do this while other distros do).

    ReplyDelete
  11. Added that path, but yes seem Ubuntu doesn't do that symlink.

    The new path searching code, is it in subversion?

    I also installed Ubuntu on a virtual machine under XP, but after doing the symlink I got another exception asking about a render library. Symlinked that too, and got another error saying shaped/transparent windows are not supported.

    ReplyDelete
  12. The improved JNA path searching is in SVN. If you're using that and it doesn't work, please post to users@jna.dev.java.net.

    Make sure you have xfce, beryl, compiz, or any other window manager installed which supports compositing.

    I found xfce the easiest; it is the default with X-Ubuntu. The KDE wm should work as well.

    JNA looks for a 32-bit X visual, if none is found you get the "not supported" error. Do "xdpyinfo" in a terminal and see if you get any 32-bit entries in the output.

    ReplyDelete
  13. I am using WindowUtils.setWindowTransparent(Window w, boolean transparent) in Macintosh.

    I have a JFRame with JTextPane with JSCrollPane.

    The vertical scrollbar doesn't work well.When i drag the thumb all the frame is moved.
    Can you tell me what is the reason?

    In windows i don't have such problem.

    ReplyDelete
  14. do Component.setBackground(new Color(0,0,0,0)) on the problematic frame, instead of WindowUtils.setTransparent(). Does the problem still occur? If so, report a bug to Apple at bugreporter.apple.com.

    ReplyDelete
  15. Problem :(
    I got the AlphaMaskDemo2 and only replaced the image.
    Everytime I use the WindowUtils.setWindowTransparent I get this error on console:

    java.lang.Exception
    at com.sun.jna.examples.WindowUtils$W32WindowUtils$W32RepaintTrigger.update(WindowUtils.java:510) at com.sun.jna.examples.WindowUtils$RepaintTrigger.paintComponent(WindowUtils.java:181)
    at javax.swing.JComponent.paint(Unknown Source)
    at javax.swing.JComponent.paintChildren(Unknown Source)
    at javax.swing.JComponent.paint(Unknown Source)
    at javax.swing.JLayeredPane.paint(Unknown Source)

    ReplyDelete
  16. Pick up the most recent code from http://jna.dev.java.net and build from source. The issue you're seeing has been fixed there.

    ReplyDelete
  17. Thanks technomage, I got the WindowUtils source and it worked. But it still seems slow, when I click on a button it takes 1 second to execute it. This only happens when Im using the setWindowTransparent() method. Any idea?

    ReplyDelete
  18. Post you question with relevant details to the JNA user's list (users at jna.dev.java.net).

    You may also find some useful info in the list archives; there have been some optimizations posted there.

    Netbeans' profiler is very easy to use if you want to take a look at the performance yourself.

    ReplyDelete
  19. BTW, the exception posted to the console is only a debug stack trace that was inadvertently left in the code.

    ReplyDelete
  20. Hi,

    Ive built the latest source and when I use it in my app the widgets get painted only when you hover over them

    I am using the WindowUtils.setWindowTransparent()on windows xp


    Thanks,
    Donny.

    ReplyDelete
  21. Anonymous1:45 PM

    i'm running ubuntu6.10 .. i hope this is useful

    Java Web Start 1.5.0_08
    Using JRE version 1.6.0 Java HotSpot(TM) Client VM
    User home directory = /home/something
    ----------------------------------------------------
    c: clear console window
    f: finalize objects on finalization queue
    g: garbage collect
    h: display this help message
    m: print memory usage
    o: trigger logging
    p: reload proxy configuration
    q: hide console
    r: reload policy configuration
    s: dump system and deployment properties
    t: dump thread list
    0-5: set trace level to
    ----------------------------------------------------
    Exception in thread "AWT-EventQueue-0" java.lang.UnsatisfiedLinkError: X11
    at com.sun.jna.Function.find(Native Method)
    at com.sun.jna.Function.[init](Function.java:85)
    at com.sun.jna.Function.[init](Function.java:59)
    at com.sun.jna.Library$Handler.invoke(Library.java:192)
    at $Proxy0.XOpenDisplay(Unknown Source)
    at com.sun.jna.examples.WindowUtils$X11WindowUtils.getAlphaVisuals(WindowUtils.java:863)
    at com.sun.jna.examples.WindowUtils$X11WindowUtils.isWindowAlphaSupported(WindowUtils.java:821)
    at com.sun.jna.examples.WindowUtils$X11WindowUtils.getAlphaCompatibleGraphicsConfiguration(WindowUtils.java:828)
    at com.sun.jna.examples.WindowUtils.getAlphaCompatibleGraphicsConfiguration(WindowUtils.java:1097)
    at com.sun.jna.examples.AlphaMaskDemo2.run(AlphaMaskDemo2.java:107)
    at java.awt.event.InvocationEvent.dispatch(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)

    ReplyDelete
  22. More recent builds of JNA address this automatically, but what you are missing on your ubuntu system is symlinks like this:

    libX11.so -> libX11.so.6.0.1
    libXext.so -> libXext.so.6.0.1

    These are usually included in the developer X11 packages, but not in a vanilla install.

    The lack of symlinks is handled automagically in later JNA builds, so the demo will just work whether or not you have the symlinks.

    ReplyDelete
  23. i got the same problem that zen

    Ive built the latest source and when i use a jButton its not rendering very well. just some times when i roll over or when i click. a very strange behavior...

    I am using the WindowUtils.setWindowTransparent()on windows xp

    ReplyDelete
  24. i get the following error when i use this function

    Exception in thread "main" java.lang.IllegalArgumentException: Window GraphicsConfiguration 'X11GraphicsConfig[dev=X11GraphicsDevice[screen=0],vis=0x23]' does not support transparency
    at com.sun.jna.examples.WindowUtils$X11WindowUtils.setWindowTransparent(WindowUtils.java:1369)
    at com.sun.jna.examples.WindowUtils.setWindowTransparent(WindowUtils.java:1510)
    at MainClass$TransparentScreen.<init>(MainClass.java:123)
    at MainClass.main(MainClass.java:55)

    but i can make any window transparent by clicking alt and mouse scroll down which means transparency is supported on my system.

    I am using Ubuntu 8.04

    ReplyDelete
  25. You need to create your window or frame with a proper GraphicsConfiguration argument obtained via WindowUtils.getAlphaCompatibleGraphicsConfiguration(). Otherwise the GC you obtain will likely lack an alpha channel.

    ReplyDelete
  26. Finally Sun officially implemented transparent/shaped window support in JDK 7
    (was also already present in JDK 6_10)

    (see here)

    ReplyDelete