I am a Java developer, designer, public speaker and a JAS 39 Gripen instructor fighter pilot. A somewhat unusual combination I guess, but I like challenges. I have created miglayout.com, migcalendar.com and Wing, a flight planning system used in several Air Forces. I find end user usability to be the most important part of a system and have therefore specialized in creating such applications. Mikael has posted 10 posts at DZone. View Full User Profile

Java Media Player - Final Chapter?

11.03.2008
| 7555 views |
  • submit to reddit

As those who have been following my blog know, I have dug down deep into the coding of the GUI. I started there since I deemed that to be the most risky part given Java’s tendency for being slow, unless you know exactly what you do and on which platform. I have coded Swing for a long time so I thought that the problems would be quite a few but I was was confident I could code around them.

Seems I was wrong, or at least it looks like that right now. Congratulations to those who left comments in the line of “Why Java since it’s so slow and unreliable on the desktop”. The reasons are complicated but I will try to explain them below. Why? Because maybe if I write them down I can solve them? ;)

First I made a GUI with a few cool, but subtle, effects. I have created the carousel component, the totally customized JScrollBar and both optimized glow and shadow effects. Everything was really fast and smooth, much because of the hardware accelerated image blits and scales. I am very happy with the carousel, it is every bit as fast as iTunes’ Cover Flow.

The second phase was about getting the side docked pullout sidebars to work. I had several fallback options for this that all should look the same as in the screen shots. And since I develop on the Mac using Java 1.6.0_07 everything went really smooth here as well.

To enable translucency you just set the background color to a color that have transparency (e.g. new Color(0, 0, 0, 0) and the rest is handled by the Mac Java implementation. I draw the shadows myself since I needed them to look the same for all platforms. It is easier if I make everything as one big window with the pullouts as normal components (and not heavyweight windows). On the Mac this work beautifully, fast and totally seamless.

Then I switched to test on Windows Vista and XP. There were some initial problems but that was mostly because of me and small inconsistencies that I wasn’t aware of. Like that you need to constantly poll for a new Graphics object from the component you want to animate on Windows. In OS X you could hold on to the same one. No biggie.

The trick of just setting a background color to get transparency doesn’t work in Windows, not even u10. Not sure why since it is such an obvious way to do it. Instead you have to add two lines, one which is in the protected sun libs. This makes this version update 10 and later only, unless of course I do it using reflection. The lines are:

window.setUndecorated(true);
com.sun.awt.AWTUtilities.setWindowOpaque(window, false);

With those lines pixels that aren’t painted with an opaque color will have the background show through.

But.. The performance totally went out the window (pun intended). With that last line in the code the GUI turned to dough though. Even selecting a row in the JTable was painfully slow and with a very noticeable lag. Unusable even. After an hour of investigation I found out, not from the documentation mind you, that when translucency is enabled the whole component tree of the frame will be repainted for every little local repaint!!! For instance, when the cursor blinks in a JTextField the whole frame will be repainted. How stupid is that! And not only that, it will be repainted to a buffer and then that buffer will be software copied to the screen! No wonder it was slow..

OK, I fired up mail to let my favorite Sun engineers know that Java 1.6.0_10 was not bug free just yet. :) I was surprised that they told me that this was the intended behavior! To make things worse they first even tried to convince me that it had to be this way because of how windows works. But after a few emails back and forth it became clear that it is Swing that has a problem with rendering to a translucent back buffer and there were no resources to address that. Bummer… It “may or may not be fixed in an update”…

So, I though that, well, me being a self appointed Swing/Java2D expert I could make my own back buffer and render to it. If I create my own RepaintManager I can intercept the small repaints and only repaint what is need to my own buffer. Then copy that buffer to the Frame, which in turn will be copied to the screen by Swing. But first I thought that I might do some performance testing, to be sure. It turns out that even a GUI that takes 0.0 ms to render is too slow for any window larger than 800×800 on my 2.4GHz one year old computer. So, even if I made the perfect algorithm that was infinitely fast it wouldn’t be enough. Just add a single JTextField to a translucent window of some size (like 1280×1024) and try to edit it… translucent windows in Java makes GHz feel like MHz. :) Dead end.

OK, being an expert and all I was not about to give up just yet. I praised OS X’s version of Java for not having any problems in the first place and took a warm shower, which is the place where most of my ideas come to. Ping! New idea!

I can use the normal window decorations (will look worse, but still ok) and have tool like dialogs for the pullouts. I began testing and at first it looked like it could be done. But it couldn’t… It turns out that there is no way to control the z-ordering of windows/frames/dialogs in Swing. The only control you have is that you can set a Window to be “alwaysOnTop”. Not very usable since that would disrupt the interaction with the other windows on the user’s desktop. Then I tried all the modality modes. You can actually make a tool window float on top of the main window, but not below it! I must have it below since the OS drawn shadow around the Window must be on top of my pullout or it will look very weird. Also, as soon as I pressed the pullout window the main window’s title bar would deactivate which is not the intended behavior. So, dead end there as well and another few hours wasted. And I was out of hot water to get new ideas (OK, not really. (About the water)).

This is where I am now. At a dead end. I could of course release only for the Mac, but no.. That would go against the whole thing of sharing music with your friends, not many of them have macs…

Actually when I was writing this I came up with another idea. Not sure it is viable but I might try it. I can set the main window and pullouts to clip with round rectangle shape. No window decorations. That means no problem with z-order or deactivated title bars since I draw the title bar and the windows will not overlap. Of course this means that there won’t be any shadows (not an option) but that might be solved with a kind of shadow-only window that has those much needed translucent pixels. Since those windows aren’t changed much, and they don’t host that many pixels in the first place it might actually work. I’ll think about it some more…

A lot of wining, I know, but I actually thought Sun would step up to the plate and make Java a viable choice for the desktop. And when I mean the desktop I’m not talking boring enterprise apps with crappy GUIs, I’m talking media players and widgets.

To add insult to injury it turns out that resizing windows on at least Vista turned sluggish with the jump from 1.6.0_07 to _10. Look at this post for more info: java.net forum link

Cheers,
Mikael Grev

ps. For those of you that come here for the screenshots, if you have managed to get through my ramblings here’s how the Media Player looks right now on the Mac. Everything, including the shadows, is drawn with Java2D (except the album art picture of course) and it is really really fast. Even the volume control is working… :)

From http://miginfocom.com/blog/

Published at DZone with permission of its author, Mikael Grev.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Dirk Lemmermann replied on Mon, 2008/11/03 - 5:20am

It is too sad to read once again how Java's success on the Desktop gets constrained by Swing (or by the Swing team / management?). We (as in JavaSE Desktop Developers) waited so long for transparency, we were told it has arrived ... and it doesn't work, yet, and probably never will. How disappointing is that? Transparency and a "real" tree table implementation would really make my day.

 --Dirk 

Jeff Devis replied on Mon, 2008/11/03 - 6:24am

even if there is no pb in the gui developpement part, it will be in the player it self!

cause we are still waiting for the resurection of jmf  :(

Otengi Miloskov replied on Mon, 2008/11/03 - 9:00am

JavaFX API using the scenegraph and Java2D with Java or JavaFXscript I think is the way to go for the future of Client and desktop Java. Just we need more components and controls and deprecate Swing because still have lots and lots of bugs. I cant believe after all this years Swing still unusable.

Personally Im not interested on JavaFXscript, I want to use the LIBS with Java.

Collin Fagan replied on Mon, 2008/11/03 - 11:28am

Hey that's Breaking Benjamin, I have that CD. :) It's sad a rendering bug on windows keep this from working right. Have you tried it on Linux?

Mikael Grev replied on Mon, 2008/11/03 - 11:53am in response to: Otengi Miloskov

JavaFX is using Swings components under the hood so they aren't going anywhere soon. Also JavaFXScript is just another lanugage, it won't "solve" anything. Even though Sun say that it is there for the designers I haven't seen any designers using it yet. All I see are tests made around the web by us normal developers...

Cheers,
Mikael

Mikael Grev replied on Mon, 2008/11/03 - 11:56am in response to: Collin Fagan

Yeah, BB is king!

I have not tried it on Linux. My target audience isn't really the techies that are using Linux though. This Media Player is for the other 99%. :)

But of course, it will work in Linux. I just won't put that much initial effort that way.

Cheers,
Mikael

Michael Bien replied on Mon, 2008/11/03 - 2:07pm in response to: Mikael Grev

just a warning, test complex Java2D applications on linux only if you are in very (very) good mood (and disable transparency proactive, it wont work anyway) ;-)

Mikael Grev replied on Mon, 2008/11/03 - 2:39pm

<removed>

Mikael Grev replied on Mon, 2008/11/03 - 2:40pm in response to: Michael Bien

Or, I test it a day when I am already in a bad mood. So that I don't ruin a perceftly fine day! ;)

I am thinking of a command line interface for Linux actually. It will probably be recieved better by the users anyway...

/usr/local/bin/java -jar /usr/local/bin/media_player.jar -no_user_data_givaway_mode -khz 48k -sound on -append_track_to_currentl_playing_playlist /a/very/long/and/complicated/path/my_long_song_name.mp3

Cheers,
Mikael

Sumaila Alfa replied on Thu, 2010/07/22 - 5:01pm

I think the Look And Feel also matters in the display, try using the UIManager.setLookAndFeel("com.sun.java.swing.plaf.metal.MetalLookAndFeel");

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.