Friday 23 January 2009

Happy 牛 Year!

Happy New Year of the Ox!

Source code available here.

Wednesday 21 January 2009

JavaFX MediaPlayer Memory Leak?

I wrote an e-card using JavaFX 1.0 to celebrate the upcoming Chinese New Year. It's a typical little multimedia applet with some animation, music and sound effect - supposedly perfect for JavaFX. However, I found that the memory usage is steadily climbing even when there is no activity (animation) happening on the canvas. I refactored, double-checked, triple-checked my source code several times to make sure that there was no unnecessary object creation and to reuse objects (by changing the opacity) every time - but to no avail.

Then I did a little experiment and found out that the number-one culprit could be the javafx.scene.media.MediaPlayer. The test program has a MediaPlayer and blank canvas with two buttons - the Start button to play the media/music; and the Stop button to stop the music. The source code for this simple test is shown below.

package testjavafx;

import javafx.animation.Interpolator;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.ext.swing.SwingButton;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.scene.Scene;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;

var m=MediaPlayer {
    autoPlay: false
    repeatCount: MediaPlayer.REPEAT_FOREVER
    media: Media {
        source: "{__DIR__}bubugao.mp3"
    }
};
Stage {
    title: "Application title"
    width: 250
    height: 250
    scene: Scene {
        content: [
            MediaView {
                mediaPlayer: m
            }
            SwingButton {
                translateY:100
                text: "Start"
                action: function() {  
                    m.play();
                }
            },
            SwingButton {
                translateY: 150
                text: "Stop"
                action: function() {  
                    m.stop();
                }
            }
        ]
    }
}

Profiling the application, I found the same memory usage pattern: memory usage climbs steadily with every time the media is played (i.e. pressing the Start button). The heap graphs below are captured from NetBeans 6.5.

The notes on the first graph (on the left) are explained below:

  1. play - the Start button was pressed
  2. GC - garbage collection was forced by pressing the GC icon several times in NetBeans
  3. stop - the Stop button was pressed
  4. GC - garbage collection was forced

The notes on the second graph (on the right) are explained below:

  1. GC - garbage collection was forced by pressing the GC icon several times in NetBeans
  2. play - the Start button was pressed several times quickly
  3. stop - the Stop button was pressed
  4. GC - garbage collection was forced

The MediaPlayer also has very limited support on media formats - it does not support wave files, or MPEG-2.5 sound files... so that I couldn't use most of the sound-effect files available on the internet. So this is Sun's solution to multimedia applications?!

Wednesday 7 January 2009

Moon Monsters in JavaFX

The Moon Monsters demo shows up as the first sample in Microsoft's Silverlight 1.0 Gallery. I thought it'd be great to test-drive JavaFX by porting this demo from Silverlight to JavaFX 1.0.

This seemingly simple demo actually touches on quite a few areas in the core stength of the JavaFX APIs - 2D graphics, data binding and input events handling. While the JavaFX port of the Moon Monsters is a pretty faithful implementation of the original features, it is not 100% complete. The following are not implemented here:

  1. The graphics for paintbrush and keyboard are not included because it is too laborious to copy the coordinates into the JavaFX script.
  2. The HTML Overlay feature is not implemented. I don't know how to do this in JavaFX because unlike Silverlight 1.0, JavaFX is not Javascript based and it is not bound to HTML either. If anyone knows how to do this in JavaFX, please leave a comment.
The source files are available here: alien.zip

Related Posts:

Friday 2 January 2009

Problem Mixing SmartSWT and GWT Widgets

I set out implementing my Address GUI using SmartGWT 1.0b1 together with GWT 1.5.3 for Windows - both are latest releases available for download. The SmartGWT does not have any formal documentation. Information are scattered in Javadoc, showcase and developer/user forums. Although not ideal, the documentation is generally adequate.

I quickly ran into problem with SmartGWT. I wanted to have a menu bar at the top of my application as shown in the following diagram (which is a screenshot of SWT-Ext implementation of the same application).

SmartGWT does have a MenuBar in its API. However, this class does not seem fully implemented - there is no method to add menus (the addMenus() method is missing from the download although it appears in the online javadoc). As a workaround, I decided to use GWT's own MenuBar and MenuItem in combination with SmartGWT's ToolStrip and TabSet widgets as shown below.

I have done the same thing with the SWT-Ext version of the Address GUI (as shown in the first diagram above) using GWT's Menu with SWT-Ext's ToolBar and TabPanel widgets without any problems. However, in SmartGWT, the drop-down menu appears behind the SmartGWT widgets and get obscured by them. So I cannot really use the menu items any more. This result is shown in the above diagram.

It seams that SmartGWT is not so smart after all. [Update 2009-01-03]: Just joking!