Dragging an MP3 Player Applet to the Desktop
Java SE 6 Update 10 gives developers the ability to create draggable applets which users can then save on their desktop to use later. One great use for this feature is for a music band specific MP3 player. The band can put the player on its website, preload it with their songs, and have a back button which takes the listener back to the band's website later.
Understanding the Code
Basic support for draggable applets in JavaFX is quite easy. You just have to add the draggable:true attribute in the JavaScript code that generates the applet tag. To give your applet a positive dragging experience, however, requires a bit more work. JavaFX enables you to customize the drag behavior to create your own draggable title bar, close button, and drag hint indicator.
Creating a Draggable Region
To make your application draggable, you must first collect all of the data that you need. Your should check the following:
- Whether it is currently running as an applet, in case it might be launched as a Java Web Start application
- If applet dragging is supported (in case the user has an older version of Java software)
- Whether the mouse cursor is inside the "draggable area."
The draggable area is the part of your user interface that you can use to drag the application out of the browser and move it around. This is typically a title bar-like rectangular area at the top edge of your window frame, but the exact shape is entirely up to you. The code in Figure 1 shows how to collect all of this information.
var isApplet = "true".equals(FX.getArgument("isApplet") as String); var inBrowser = isApplet; var draggable = AppletStageExtension.appletDragSupported; var dragRect:Rectangle = Rectangle { x: 155 y: 30 width: 420 height: 40 fill: Color.TRANSPARENT onMouseDragged:function(e:MouseEvent):Void { stage.x += e.dragX; stage.y += e.dragY; } }; var dragTextVisible = bind inBrowser and draggable and dragRect.hover;
Figure 1: Main.fx, Draggable Applet Support
The dragRect in Figure 1 has an onMouseDragged event handler which updates the stage position. This is the part of your GUI that implements the standard dragging behavior after the applet is already outside of the browser. The ability to perform the initial drag is defined elsewhere, as explained later. Also notice in Figure 1 that the isApplet variable is initialized using a check for an argument named isApplet. This is a parameter you should set in the HTML for your applet, as shown in Figure 2.
javafx({
archive: "webstart/DraggableMP3Player.jar,webstart/lib/FXDContainer.jar,webstart/lib/FXDPackager.jar,webstart/lib/javafx-fxd-1.0.jar,",
width: 510,
height: 345,
code: "draggablemp3player.Main",
draggable: true,
name: "appl"
} , {
isApplet: "true"
}
);
Figure 2: Set the isApplet Attribute of the Applet Tag
Making the Stage Draggable
With the Boolean variables in place, you can now make the stage itself draggable. You add this feature by creating an instance of the AppletStageExtension and customizing the event handlers, as shown in Figure 3. Since you want the user to drag the applet only when the mouse is pressed inside the drag area, the shouldDragStart event handler checks for both the state of the mouse and if dragRect.hover is true. When the drag starts, it sets the inBrowser variable to false. When the applet moves back inside the browser by calling stage.close(), the inBrowser variable is set back to true. Also notice that the background fill of the scene is bound to the inBrowser variable. This bind makes the background white when in the browser, but switches it to transparent when the user drags out the applet.
stage = Stage {
scene: Scene {
//conditionally make the background white or transparent
fill: bind if (inBrowser) Color.WHITE else Color.TRANSPARENT
content: // your gui goes here...
}
extensions: [
AppletStageExtension {
shouldDragStart: function(e): Boolean {
return inBrowser and e.primaryButtonDown and dragRect.hover;
}
onDragStarted: function(): Void {
inBrowser = false;
}
onAppletRestored: function(): Void {
inBrowser = true;
}
useDefaultClose: false
}
]
}
Figure 3:
Josh MarinacciStaff Engineer,
Sun Microsystems