Skip to main content

Translucent windows question

41 replies [Last post]
ratoo
Offline
Joined: 2007-08-27
Points: 0

Hello!

I am playing with AWTUtilities... great. but,
Does it supposed to be in java.* package?
Why is the need to make a special API for this functionality?
From the java.awt.Component.setBackground() - "The background color affects each component differently". Could it be easy just make window.setBackground(new Color(0,0,0,255)) work? Just use transparency and call AWTUtilities.setWindowOpacity(this, (float)x/255);

I am not an expert by any means, but I think that the whole idea of update10 is BAD. Sun promised to do not make Java6.x releases and instead made several versions with different functionalities that we all happy to have, but those are not in Java6 standard...

Regards,

Ratoo

Message was edited by: ratoo

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
ajmmm
Offline
Joined: 2008-07-04
Points: 0

Hello all, again!

I'm in new problems...
For performance purposes, I'm trying to create an application with 2 translucent overlapped JPanels, using a JLayeredPane.
I'd like to work over the top JPanel preventing the bottom panel from being repainted, to keep always the same background and have fast changes in the top layer.
However, I cannot by any mean prevent the bottom JPanel to be automatically repainted each time the top one is. this.setIgnoreRepaint(true); seems to be completely ignored.

Can someone please help me?

Thank you.

Best regards,
Antonio

anthony_p
Offline
Joined: 2006-07-24
Points: 0

Hi Antonio,

I believe this question belongs in the Swing & AWT forum at http://forums.java.net/jive/forum.jspa?forumID=74&start=0
Please repost it there to get some helpful answers.

--
best regards,
Anthony

ajmmm
Offline
Joined: 2008-07-04
Points: 0

Thank you!!

ixmal
Offline
Joined: 2004-08-08
Points: 0

> After some months, I'm stuck again with this
> problem...
> Anthony's advise was perfect, but now, I have to make
> translucent an existing application that has spread
> all over the code arbitrary calls to
> panel.getGraphics(). This results in incorrect

You know, direct calls to getGraphics() effectively turn off most of Swing's painting optimizations - see JComponent.safelyGetGraphics() and related code. That's why I'd suggest you to rewrite the code using paintComponent(), if possible.

In JDK7, when shaped & translucency windows will be supported in java.awt package (public API instead of AWTUtilities), we still plan reusing standard Swing approach, i.e. when all the components are painted from JComponent.paint(), and it's RepaintManager who is responsible for updating the native back buffer used for translucency.

> painting and it will be terribly difficult to change
> all the needed code.
> Is there any other way to force repaint without need

Could you explain, what "to force repaint" means, please?

> to move all drawing code inside paintComponent() or
> paint() methods in the JPanel?
>
> Thank you.
>
> Best regards,
> Antonio

Thanks,

Artem

ajmmm
Offline
Joined: 2008-07-04
Points: 0

Hi all,

and Thank you, Anthony and Artem.
Due to persons like you, this forum is for sure the best i've ever seen.

When I talked about "force repaint", what I meant was to try every paint(), paintComponents(), paintImmediatly() on the related JPanel, to force an intermediate paint outside of JPanel's paint method. But none of them got any results.
I understood that the problem is to have to work on something that started wrong, but the work power needed to change everything will be huge...

...let's do it!!

Thank you, again!

Best regards,
Antonio

component

ajmmm
Offline
Joined: 2008-07-04
Points: 0

Hello, again!

Probably I should start a new thread, but this is just a simple question:

-I'd need to create a translucent JApplet. I suppose it would not be possible, there's no constructor that could receive a GraphicsConfiguration, and the constructor is called by the browser.

The idea is embed a Java translucent frame in a windows native application, allowing to see through the transparency the native background. With a JApplet it would be easy, as the native application could load an ocx containing the applet and keeping coherence between both...

Can someone please tell me if there is any alternative?

Thank you!

Best regards,
Antonio

anthony_p
Offline
Joined: 2006-07-24
Points: 0

Hi Antonio,

Unfortunately it isn't possible. Neither Windows, nor X11 enable child windows to be transparent. Since an (J)Applet is a heavyweight native embedded (--> child) window, it can not be made transparent natively. Hence Java does not provide this functionality. Only top-level windows (those residing on the desktop) may be made transparent.

--
best regards,
Anthony

ajmmm
Offline
Joined: 2008-07-04
Points: 0

Oh... It seems that I need help from windows foruns...

Thank you, Anthony!

ajmmm
Offline
Joined: 2008-07-04
Points: 0

Hello, again!

After some months, I'm stuck again with this problem...
Anthony's advise was perfect, but now, I have to make translucent an existing application that has spread all over the code arbitrary calls to panel.getGraphics(). This results in incorrect painting and it will be terribly difficult to change all the needed code.
Is there any other way to force repaint without need to move all drawing code inside paintComponent() or paint() methods in the JPanel?

Thank you.

Best regards,
Antonio

anthony_p
Offline
Joined: 2006-07-24
Points: 0

Hi Antonio,

You might try putting the graphics output code directly into the frame's paint() method. However, "any-time painting" (i.e. when you obtain the graphics anywhere outside the paint() method of a component) is not supported. There's no workaround. Sorry about that.

--
best regards,
Anthony

anthony_p
Offline
Joined: 2006-07-24
Points: 0

By the way, probably you also forgot to make your window undecorated (see Frame.setUndecorated() method). The effect is only supported for undecorated windows actually.

ajmmm
Offline
Joined: 2008-07-04
Points: 0

Hi, Anthony!

Thank you for your answer. At this moment I have no access to my laptop, but I'll send the code in brief. Considering the decoration, I did not set the frame undecorated, indeed...

Best regards,
Antonio

anthony_p
Offline
Joined: 2006-07-24
Points: 0

One more useful thing to print is the result of the frame.getGraphicsConfiguration() - just to make sure it doesn't get changed behind the scene. If it differs from one you use when constructing your frame then this is possibly a bug.

ajmmm
Offline
Joined: 2008-07-04
Points: 0

Hello, Anthony!

I checked again and a simple test worked in windows.

Thank you, once again, for your help.

Best regards,

Antonio

ajmmm
Offline
Joined: 2008-07-04
Points: 0

Hi, Anthony!

I had to suspend my previous work, due to the referred bug (http://bugs.sun.com/view_bug.do?bug_id=6710012). Currently, I see in its page that the status is "10-Fix Delivered" and "Release Fixed" is "6u10(b31)".
Can you tell me, please, when update b31 is expected to be made available?

Best regards,

Antonio

rogyeu
Offline
Joined: 2006-07-30
Points: 0

b31 is out now. You can download it here:
https://jdk6.dev.java.net/6u10ea.html#Download

Thanks,
Roger Y.

ajmmm
Offline
Joined: 2008-07-04
Points: 0

Hello!

Thank you, all, for your last help.
Currently, I returned to the project that needs these features and could already have transparent frames without problems. It's just a question of cycle through available GraphicsConfigurations and create the JFrame with the correct one (Thanks, Anthony!!).

Now, my problem is: -If I get a Graphics2D object to paint some strokes, 2 strange things happen. First, some of the components are not painted, or are painted but almost immediatly disappear. Second, if I apply RenderingHints for antialiasing, no strokes are painted at all.

Can you tell me, please, if there is some special step or mistake that I can be forcing (Like 'do not mix 2D strokes with something...')?

Thank you.

Regards,

Antonio

anthony_p
Offline
Joined: 2006-07-24
Points: 0

Hi,

I would suggest you to wrap all your painting code in the overridden paintComponent() method of your JPanel or wahtever other component, so that all painting happens in this method. Then just add this component to the content pane of your JFrame and you should be able to see the painting on the screen.

--
best regards,
Anthony

ajmmm
Offline
Joined: 2008-07-04
Points: 0

Hi!

Thank you, again, for your help.

I'll have to change lots of code, but I'll try it and give you some feedback.

Thank you!
Best regards,

Antonio

ajmmm
Offline
Joined: 2008-07-04
Points: 0

Hello, all!

I'm still in this translucency cruzade!...
Currently, after have main problems solved in Linux, I had to go back to Windows and new problems arouse.
Now, if I have a transparent JFrame (with setWindowOpaque) and place a JPanel, I have to call panel.setDoubleBuffered(false) to get it really transparent. However, it seems to do not get capture events, after call setDoubleBuffered(false) and setBackground(new Color(0,0,0,0)). If it has any component (like a JLabel), clicking in the label works; but if I click an area of the panel aoutside any child component, the back window gets focus.
Should I do something else, apart call setBackground and SetDoubleBuffered?

Thank you.

Best regards,
Antonio

anthony_p
Offline
Joined: 2006-07-24
Points: 0

If you need to make sure the mouse events get delivered to the component, it has to have a non-completely-transparent color (like (0, 0, 0, 1) if the range of alpha component is 0..255). Set this background color to your panel and it should start catching the clicks.

--
best regards,
Anthony

anthony_p
Offline
Joined: 2006-07-24
Points: 0

And by the way, currently the support for this feature on X11 is broken. The bug can be tracked here:

http://bugs.sun.com/view_bug.do?bug_id=6710012

Please use a MS Windows system to play with the feature for now.

ajmmm
Offline
Joined: 2008-07-04
Points: 0

Thank you again, Anthony.

My solution deens to be deployed in Linux; so, I assume that I did not test it thoroughly in windows. But I'll do it now.
Does your experience tell you how much time would to be needed to get this bug solved?

Best regards,

Antonio

anthony_p
Offline
Joined: 2006-07-24
Points: 0

The bug will be solved in the next update release after 6u10. I can't tell when exactly it happens. Maybe in few months.

ajmmm
Offline
Joined: 2008-07-04
Points: 0

Hi, Anthony!

Could you please give me a tip on this subject, again?
The bug you spoke about exists, but, in Linux, I'm still a step behind it. I'm still in the "IllegalArgumentException" problem.
There are forums that assume hardware/operating system as the cause - for instance, in
http://forums.sun.com/thread.jspa?threadID=5313882
However, I would like to not assume it so easily, because (if I'm not wrong), my machine can find a suitable configuration. I used:

GraphicsConfiguration gc=null;
GraphicsDevice[] devices= GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
for (int i = 0; i < devices.length ; i++)
{
GraphicsConfiguration[] configs = devices[i].getConfigurations();
for (int j = 0; j < configs.length ; j++)
{
if(AWTUtilities.isTranslucencyCapable(configs[j]) &&AWTUtilities.isTranslucencySupported(AWTUtilities.Translucency.PERPIXEL_TRANSLUCENT))
gc=configs[i];
break;
}
}

System.out.println("GC:"+gc);
if(gc!=null)
frame = new JFrame(gc);
else
frame = new JFrame("Failed...");

frame.setSize(600,400);
AWTUtilities.setWindowOpaque(frame, false);

(...)

The code seems to find a suitable configuration; so, it should not be a OS/hardware problem, I suppose:
GC:X11GraphicsConfig[dev=X11GraphicsDevice[screen=0],vis=0x23]

But the error persists:
SEVERE: Application class desktopapplication1.TranslucencyTest failed to launch
java.lang.IllegalArgumentException: The window must use a translucency-compatible graphics configuration
at com.sun.awt.AWTUtilities.setWindowOpaque(AWTUtilities.java:371)
(...)

Could you please help me finding my mistake?

Thank you.
Best regards,

Antonio

anthony_p
Offline
Joined: 2006-07-24
Points: 0

Please use the "code" tags in square brackets (w/o the quotes, of course) to submit the source code. Otherwise it's unreadable.

Could you provide the full stack trace of the exception you get (I assume the loop you started to write did indeed return you a non-null GC that is translucency-capable)?

shakeer
Offline
Joined: 2008-05-08
Points: 0

Hi,

I am new to swings.
I am working on a tool in which the Window internal layers which extends JComponent should be transparent. is this possible with AWTUtilities.setWindowOpacity(); but it accepts only window objects as arguments. Anyone pls help me in this regard.

Thanks in Advance,
Shkeer.K

shakeer
Offline
Joined: 2008-05-08
Points: 0

Sorry, My window should be transparent with borders and some of the components opaque.

thanks,
Shakeer.K

ajmmm
Offline
Joined: 2008-07-04
Points: 0

Hi!!

I share the same problem. I need to create an application that allows to sketch (completely opaque strokes) over arbitrary backgrounds (completely transparent JFrame). I cannot achieve this in anyway. Already tried AWTUtilities, WindowUtilities (jna), but without success...

Is there someone that could help me, please?

Regards

anthony_p
Offline
Joined: 2006-07-24
Points: 0

Hi ajmmm,

Could you please tell us what you did with AWTUtilities, and what exactly didn't work as you expected with your code?

--
best regards,
Anthony

ajmmm
Offline
Joined: 2008-07-04
Points: 0

Hi, Antony!

Thank you for your kind answer.

I'm trying to use AWTUtilities.setWindowOpacity(myJFrame, (float)transparency), but when the background gets transparent, the strokes get invisible (because they turn transparent, as well).
Then, I think I should use setWindowOpaque(myJFrame, false); to enable per-pixel transparency. However, the call to this method always generates an "java.lang.IllegalArgumentException: The window must use a translucency-compatible graphics configuration".
There is lots of documents about this subject and graphics configurations, but I could not find a way to solve this problem - both in windows and linux, with compiz. That's why I gave up...

Can you please help me?

Thank you.
Best regards,

Antonio

anthony_p
Offline
Joined: 2006-07-24
Points: 0

I would suggest you reading this article:

http://java.sun.com/developer/technicalArticles/GUI/translucent_shaped_w...

it explains in details how to use the AWTUtilities capabilities correctly. You will also find a demo application with a complete source code there. Hope this helps.

trembovetski
Offline
Joined: 2003-12-31
Points: 0

> Does it supposed to be in java.* package?

No new public API can be added in an update release, so this API
can't be in java.*. It will probably be moved to java.awt.* (or, rather,
a new api added to existing toplevel components) in Java 7.

> Could it be easy just make window.setBackground(new Color(0,0,0,255)) work? Just use transparency and call AWTUtilities.setWindowOpacity(this, (float)x/255);

Because the opacity of the frame background doesn't necessarily imply
the opacity of its children. You don't expect all Frame's children to become
red if you set red background to the Frame, right?

Dmitri

trembovetski
Offline
Joined: 2003-12-31
Points: 0

Although I guess the developer can take care of the children's bg as well.

ratoo
Offline
Joined: 2007-08-27
Points: 0

That was the idea... A developer can setOpaque(false) for the rootPane, contentPane and any another component... This is how the glassPane event blocking hack works.

I understand that you can not put this API into java.awt for jdk6, but you can make transparency work now

JDK6: window.setBackgroud() { AWTUtilities.setWindowShape() }
JDK7: both ways are available - window.setBackgroud() and java.awt.Toolkit(?).setWindowShape()

In my current project I am making a tray tooltip and it looks ugly without a transparency :-(
I expect to release it for update10 (somewhere in September)... and ya byl by ochen' schastliv to have it... :-)

swpalmer
Offline
Joined: 2003-06-10
Points: 0

This could have been done as indicated, to pay attention to the alpha of the color set on the root pane. On Mac OS X this ALREADY works to make windows translucent. (It may not be the root pane exactly, I can't remember right now, but the same idea)

Why not be compatible with what already works on the Mac?

trembovetski
Offline
Joined: 2003-12-31
Points: 0

For one, you'd need a way to check if particular translucency type is supported
(which it may not be). Also, separating different kinds of window translucency
(like same alpha for all window pixels) helps with performance and clearly
states which type the particular window uses.

Dmitri

swpalmer
Offline
Joined: 2003-06-10
Points: 0

I disagree.

If it isn't supported it won't work.. just like it doesn't work now... no big deal. There can still be a private API to test ahead of time that it doesn't work, but that is a different issue.

If I paint the root pane with non-opaque colors then I want per-pixel window shaping so if it is possible just do it. Worst case, enable the automatic behavior with a property just like is used to pick a rendering pipeline. You could even use a property to indicate what is supported I suppose.

EDIT:
Think of it this way.. when would I ever set the root pane color to something that wasn't opaque UNLESS I wanted per-pixel translucency on the window? I just don't see it happening unless the expectation is a shaped window or one with non-uniform transparency. Make it enabled with a property just in case there is some odd-ball app in the wild that is painting the root pain with non opaque colors by accident. In general you have to go out ouf your way to make that happen though.

denkel
Offline
Joined: 2008-05-27
Points: 0

I totally agree,

look at the code snippet below. This is how to make it happen on a Mac including behaviors like if a pixel is fully transparent and one clicks on this pixel the click is dispatched to whatever app is behind this pixel which is quite nice and exactly what the user expects without any additional code from my side.

public static void setWindowTransparent(Window w)
{
// set the rootPane, layeredPane and contentPane transparent
if (w instanceof RootPaneContainer)
{
RootPaneContainer rpc = (RootPaneContainer) w;

rpc.getRootPane().setOpaque(false);
root.getLayeredPane().setOpaque(false);
((JComponent) root.getContentPane()).setOpaque(false);
}

// make the window fully transparent
w.setBackground(new Color(0, 0, 0, 0));
}

trembovetski
Offline
Joined: 2003-12-31
Points: 0

This is all nice, but such a change could not be made in an update release.

Even though the suggested approach doesn't change the interface
it does change the meaning of what setBackground does.

Also, there's no way to communicate to the application if window translucency
can not be enabled, which is to me crucial.

It may also break existing applications - imagine if an application was setting
a translucent color to the background by mistake. Prior to this change it would
just have worked because setting a translucent bg doesn't do much now.
But now suddenly it would behave completely differently.

And if you think that won't happen because there are no such apps, let me
assure you otherwise. If something can be done wrong it will be.

It is possible that this feature will be implemented in this way in Java 7 -
although concerns about backward compatibility may still arise.

Dmitri

swpalmer
Offline
Joined: 2003-06-10
Points: 0

A simple property much like what already exists to specifiy different graphics pipelines could be added to enable this behavior. Then you don't have to worry about compatibility issues.

E.g.:

-Djava.awt.allowTranslucentWindows=true

I also disagree that it changes the meaning of what setBackground does - particularly if you require the setOpaque(false) on the root pane. In a sense it actually respects what a color with a alpha channel and setOpaque means instead of ignoring it.

It could be interpretted as a bug fix, since setting a translucent background color is not allowing what is underneath to show through now.