The Source for Java Technology Collaboration
User: Password:



Romain Guy's Blog

Romain Guy Romain is a French student currently working as an intern with the Swing Team at Sun Microsystems. His numerous other works include being a journalist for computing magazines and translating books for O'Reilly France. He has been using Java for many years and now puts as much time and efforts he can in UI design and Java for the desktop programming.



Make Swing... er... Swing!

Posted by gfx on February 07, 2006 at 01:24 AM | Permalink | Comments (21)

Most GUI are really boring. And I really mean it. Admit it, you'd rather listen to a French stammerer trying to recite a bad English translation of War and Peace during a rainy Sunday afternoon (and boy what a long afternoon it would be) than look yet again at some applications. Besides cool aesthetics, a way to make a GUI for appealing (just talking about the look here) is to introduce animations. Some get it right (Apple), and some get it really wrong (the first thing I do with a fresh Windows install - after muting the sounds - is to shut down all the animations). But that's not the point. Bad or good, we just want animations in our Swing application.

javax.swing.Timer is the preferred way to animate a component, an effect or whatever in Swing. Despite a lack of precision, no better than the native timing resolution (which would be around 15ms on Windows), this timer is really easy to use as it relies on ActionListener and as it posts all its events in the EDT. Unfortunately, this timer's API is very crude and gives you the bare minimum:

Timer crudeTimer = new Timer(1000 / 30, new ActionListener() {
    public void actionPerformed(ActionEvent e) {
    }
});
crudeTimer.start();

That, is a simple timer firing an event 30 times per second (or so it claims at least.) So, what is missing here? Too many things to make animations easy to develop. First, this timer doesn't track the elapsed time. You have to do that by yourself using System.currentTimeMillis() or better yet System.nanoTime(). This timer also doesn't care about the duration of the animation. You have to test the elapsed time against a given delay and stop the timer accordingly, using this beautiful expression: ((Timer) e).stop(). What about repeating an animation? Going back and forth? You get the point, Timer's useful but way too generic for our purpose. I have written so many Timer/ActionListener pairs full of tangled and ugly Java code that I feel pretty confident to herein conclude about the timers: @#!.

Let me introduce you to the solution of the wise man, Chet Haase's timing framework. Before you run away bewildered by such a powerful imagination to name a framework, take a deep breath, sit down and stay focused for a couple more minutes, will you? It's worth it. I swear. Chet ran into the exact same problems as the aforementioned ones. But Chet is not lazy, Chet is full of resources. Chet built a solution to this problem. Bestow our eternal gratitude on Chet (or whatever that is you want to bestow on Chet.) Anyway, Chet wrote a comprehensive and really interesting introduction to his framework that I urge you to read. I won't delve into the details here but the point is, hitherto you were striving to create animations for Swing UI and now it's much easier. How so? Let's take a look at a simple example a nice looking but boring, static button:



Evidence #1. A boring button.


Usually, Swing developers make buttons more interactive by introducing a rollover effect. The nice thing is you just need to call somethin like JButton.setRolloverIcon() to make it work. Unfortunately, the change is sudden and doesn't look so sexy. The solution is to animate the rollover effect. In my case, I added a highlight in the background that gradually appears when the mouse moves over the button. The animation is vey fast (about 300 ms) so it's not annoying but you can still notice it. Here is the animated result:



Evidence #2. A cool button (and animated)


When the mouse exits the button, the contrary happens, and the highlights fades out. In this particular case, I took care of animation consistency. For instance, if you enter the button then exits halfway throught the animation then enter again, you will see the animation react properly. It won't jump to its extreme values. Believe me, that's a pain to handle with javax.swing.Timer. Now, thanks to Chet's timing framework, things are way better than they used to be:

private final class HiglightHandler extends MouseAdapter {
    private TimingController timer;
    private Cycle cycle = new Cycle(300, 1000 / 30);
    private Envelope envelope = new Envelope(1, 0,
                                             RepeatBehavior.FORWARD,
                                             EndBehavior.HOLD);
    
    @Override
    public void mouseEntered(MouseEvent e) {
        animate(true);
    }
    
    @Override
    public void mouseExited(MouseEvent e) {
        animate(false);
    }

    private void animate(boolean forward) {
        if (timer != null && timer.isRunning()) {
            timer.stop();
        }
        timer = new TimingController(cycle, envelope, new AnimateGhost(true));
        timer.start();
    }
}

private final class AnimateGhost implements TimingTarget {
    private boolean forward;
    private float oldValue;

    AnimateGhost(boolean forward) {
        this.forward = forward;
        oldValue = ghostValue;
    }

    public void timingEvent(long cycleElapsedTime,
                            long totalElapsedTime,
                            float fraction) {
        ghostValue = oldValue + fraction * (forward ? 1.0f : -1.0f);
        repaint();
    }

    public void begin() {
    }

    public void end() {
    }
}

This code might seem a bit long but when you look more closely you'll see it is very easy. You can see a mouse adapter that handle the mouse enter/exit events and start the animation accordingly. All three fields from HiglightHandler uses classes from Chet's timing framework. The Cycle defines the total duration of the animation as well as its number of frames per second. The Envelope describes the animation itself: it is played once, with no initial delay, it goes forward in time (to get a time fraction going from 0.0 to 1.0) and holds its last value when the animation is over. Finally, the TimingTarget is where the nicest thing happens: the timingEvent() callback gives you everything you need to animate your GUI. In our case we just use the fraction (our position in time) and use it to modify the ghostValue. This value is just used as the transparency level of the white highlight you can see in the second screenshot.

As you can see, this small framework makes things easier both for the author of the code but also for the readers. Chet, Chris and I are currently using this framework almost everyday and as we go along, Chet is discovering new things to integrate into it. You can expect really nice things in a near future, like non-linear progressions. In the meantime, give it a try, I'm sure you will love it.

I couldn't post a webstart demo of the small effect I presented here but I'll try to do that this week if I have some time. Yet, you can download the animation (QuickTime format, 46kb) to see what it looks like. You can also check the talk Desktop Java in Action Richard Bair and I gave at JavaPolis. At the end of the presentation, in the FX section, I talk more about how to use Swing's timers for animations and the related problems.



Video Presentation: Desktop Java in Action

Posted by gfx on January 04, 2006 at 11:25 PM | Permalink | Comments (1)

Richard Bair and I have created a presentation entitled Desktop Java in Action for JavaPolis. I also presented this talk in Paris at Sun Microsystems. I recently made the slids of the talk available online but as every slide set, they lack a lot of information given by the speaker(s).

If you speak french, you are very lucky because Developpez, a french programming network, offers a video of the presentation online for free. The talk is 3 hours long but they did a great job by slicing it into more than 20 parts. Each part has a short description that will help you find your favorite topics.

If you do not speak french, don't worry, all JavaPolis talks will be available as videos within a couple of months.



NetBeans with anti aliasing

Posted by gfx on January 02, 2006 at 03:42 PM | Permalink | Comments (11)

I have Mustang as my primary VM for work and personal use. Yet I had to reinstall Tiger to be able to run NetBeans 5.0 beta2 properly because I kept getting a nasty exception regarding some XML things. Anyway, I couldn't use NB on Mustang, meaning I couldn't benefit from the subpixel anti aliasing. Hopefully, the NB guys told me today it is a bug in the JDK itself and it has been fixed in b61 so I installed a nightly build of Mustang b65 and it now works perfectly!

NB with anti aliasing

It looks so much better now! Unfortunately there is still a bug in Mustang's rasterizer which makes my favorite fixed width font (BitStream Vera Sans Mono free, GPL font) look really bad at small sizes.



JavaPolis 2005

Posted by gfx on December 05, 2005 at 02:49 AM | Permalink | Comments (0)

JavaPolis 2005

JavaPolis is European Java conference taking place from December 12th to December 16th in Antwerp, Belgium. This new installment will be the occasion fo attend interesting sessions by very interesting guys, like Ben Galbraith, Karsten Lentzsh, Heliott Rusty Harol, Graham Hamilton, Joshua Bloch, Neal Gafter and many others. It's not as big as JavaOne but whether you like Java SE, Java EE, Open Source projects or desktop applications, you'll find what you want there. All the content from the previous years is available on the web site, so go check it out.

Richard Bair, leader of the SwingLabs project, and I will give a talk on Monday entitled Desktop Java in Action. We'll talk about SwingX, data binding, UI special effects and more. I will also present Extreme Swing on Thursday, just before Karsten's JGoodies session, to explain how to create 2.5D/3D effects with Swing and Java2D.

As a bonus, I will finally go home for a few days after 7 months in the US. I have to catch up on the food and the beer. Anyway, if you happen to be at JavaPolis next week and if you want to talk about Swing, Java2D and UI design, comme see us anytime!



Façade, gaming redefined

Posted by gfx on November 28, 2005 at 08:07 PM | Permalink | Comments (7)

I am what you would call a "gamer". I have been playing video games starting with the NES. Since then I owned many consoles and dozens of video games. My love for video games is due do the stories and the wonderful worlds game designers imagine for us. That's why even though I bought 4 consoles since I arrived in the US 7 months ago I am not a hard-core gamer. Once the story has been told, the game is over and I want to play at my own pace. I can spend weeks without playing and when I play, it cannot be more than a few hours a week and this makes me happy.

Project Gotham Racing 3
Beautiful? Booooring!

I should be thrilled by the recent release of the XBox 360 but I am not. I am, actually, sad. As the hardware becomes more and more complex, game developers need more and more time to create their games, most of the time for the sake of better graphics. I love good looking games but most of them don't entertain me anymore. And despite its incredible power the XBox 360 only offers me games I've played with millions of times before. I've always liked Nintendo's approach to gaming and I cannot thank them enough for what they are doing with the Nintendo DS and the Revolution: the hardware forces game developers to be creative, to bring us a new breed of video games. I don't want yet another Blizzard's RTS, another Madden NFL iteration, another boring FPS with dark hallways... I want more of ICO, Shadow of the Colossus, Wario Ware, Pac Pix, Meteos!

Yoshi Touch and Go
You mean I have to BLOW in my Nintendo DS to get rid of the clouds? Gimme that game!

Façade might just be what I was waiting for. This innovative game is in fact an AI based art/research experiment. Presented as a one-act drama, Façade first appears as crude-looking, very short game. Yet, thanks to 5 years of engineering, its authors managed to create a novel architecture which supports emotions, body language, facial expressions, natural language generation and parsing and a drama-managed plot.

The game doesn't even dictate you who you are. When launching the game you are asked to choose a name, and therefore your sex. You are then dropped in the game itself, a 3D world in which you interact through a first person point of view. The game starts at the front door of two of your friends, Trip and Grace, who invited you over for dinner. As the drama unfolds it becomes apparent their couple is having trouble and you are the witness of their unhappiness. What should you do? I can't tell. It's different every time you play the game. The characters react to your actions (you can comfort, hug and kiss them) and to your words (you can talk to them at anytime by simply typing something on your keyboard) so it's really up to you. You can try to help them the way you want. Or you can just sit tight and see what happens. There is no goal other than experiencing a good moment of what gaming could be.

Even though it's not graphically appealing, Façade is technically impressive in the way it parses the sentences you type. I also really enjoyed the generation of natural dialogues. Characters hesitate, interrupt each other and so on. It's not perfect but it's refreshing. Also the lips-syncing might no be very good but look at the facial expressions and the body language of Trip and Grace. After having seen bland and neutral states on characters faces in almost every 3D video game I played to, I'm thrilled.

So please, if you are on Windows, go to the official web site and download your free copy of the game. Some of you will love it, some will find it deeply boring but I doubt you will remain unconcerned about it.

Oh and I wouldn't worry too much if you are not on Windows and cannot play the game. After all, it's written in Java and OpenGL and the authors seem interested in any help to port the game to another OS (at least MacOS X).



February 2006
Sun Mon Tue Wed Thu Fri Sat
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28        


Search this blog:
  

Archives

February 2006
January 2006
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005

Recent Entries

Make Swing... er... Swing!

Video Presentation: Desktop Java in Action

NetBeans with anti aliasing



Powered by
Movable Type 3.01D


 XML java.net RSS