JavaFX 1.1 Mobile Example: Using Binding and Key Events

Now that JavaFX SDK 1.1 has been released, which includes JavaFX Mobile, I wanted to show you a couple of code examples along with Java Web Start links to run them. Note: This is an update to a pre-JavaFX 1.1 article posted earlier.

BindingExampleMobile1-1

Webstart.small2

The screenshot above is a simple example of binding, running in the JavaFX Mobile emulator, that uses UI capabilities that exist on the JavaFX Mobile platform. It also demonstrates handling mouse and key events. Click on the screenshot or Launch button above to run this example via Web Start. A little later in this post I'll expand the example to create a UI that behaves somewhat like graphic equalizer controls. Take a look at the code for this example:

/*
* MobileBindingMain.fx
*
* Developed 2009 by James L. Weaver to demonstrate binding in JavaFX
* with UI classes in the JavaFX Mobile profile, and keyboard input.
*/

package projavafx.mobilebinding.ui;

import javafx.stage.Stage;
import javafx.scene.*;
import javafx.scene.input.*;
import javafx.scene.paint.*;
import javafx.scene.shape.*;
import javafx.scene.text.*;

var level:Number = 30;
def MAX_LEVEL:Number = 230;
def MIN_LEVEL:Number = 10;
var rectRef:Rectangle;

Stage {
title: "Binding Example"
scene: Scene {
fill: Color.BLACK
width: 240
height: 320
content: [
Text {
translateX: 20
translateY: 20
textOrigin: TextOrigin.TOP
font: Font {
name: "Sans serif"
size: 18
}
content: "Binding / KeyEvent 1"
fill: Color.WHITE
},
rectRef = Rectangle {
x: 0
y: 60
width: bind level
height: 20
fill: LinearGradient {
startX: 0.0, startY: 0.0, endX: 0.0, endY: 1.0
stops: [ Stop { offset: 0.0 color: Color.LIGHTBLUE },
Stop { offset: 1.0 color: Color.DARKBLUE } ]
}
onMouseDragged: function(me:MouseEvent):Void {
if (me.x >= MIN_LEVEL and me.x <= MAX_LEVEL) {
level = me.x;
}
}
onKeyPressed: function(ke:KeyEvent):Void {
if (ke.code == KeyCode.VK_RIGHT and level <= MAX_LEVEL - 10) {
level += 10;
}
else if (ke.code == KeyCode.VK_LEFT and level >= MIN_LEVEL + 10) {
level -= 10;
}
}
},
Text {
translateX: 20
translateY: 100
textOrigin: TextOrigin.TOP
font: Font {
name: "Sans serif"
size: 18
}
content: bind "Level: {level}"
fill: Color.WHITE
}
]
}
}
rectRef.requestFocus();

The length of the bar can be adjusted by clicking in the bar and dragging the mouse. It can also be adjusted by pressing the left and right arrow keys, either on the computer keyboard or on the mobile emulator. As shown in the listing above, the width of the rectangle is bound to the value of the level variable.

The next example uses a sequence of values to which the bars in the graphic equalizer are bound. Like the previous example, the length of a bar can be controlled by dragging it or pressing the right and left arrow buttons. In addition, the bar to be adjusted can be selected by pressing the up and down arrow keys, as well as clicking it with the mouse. Here's a screenshot of the UI running in the JavaFX Mobile emulator:

EqualizerExampleMobile1-1

Webstart.small2

Click on the screenshot or Launch button above to run this example via Web Start. Then take a look at the code below, noticing the levels sequence to which the Rectangle widths are bound. The fact that five rectangles are created is courtesy of the for expression, which evaluates to a sequence of Rectangle instances:

/*
* MobileEqualizerMain.fx
*
* Developed 2009 by James L. Weaver to demonstrate binding in JavaFX
* with UI classes in the JavaFX Mobile profile, and keyboard input.
*/

package projavafx.mobilebinding.ui;

import javafx.stage.Stage;
import javafx.scene.*;
import javafx.scene.input.*;
import javafx.scene.paint.*;
import javafx.scene.shape.*;
import javafx.scene.text.*;

var levels: Number[] = [30, 40, 50, 45, 35];
var selectedBarIndex: Integer = 0;
def MAX_LEVEL: Number = 230;
def MIN_LEVEL:Number = 10;
var groupRef: Group;

Stage {
title: "Binding Example"
scene: Scene {
fill: Color.BLACK
width: 240
height: 320
content: [
Text {
translateX: 25
translateY: 20
textOrigin: TextOrigin.TOP
font: Font {
name: "Sans serif"
size: 18
}
content: "Binding / KeyEvent 2"
fill: Color.WHITE
},
groupRef = Group {
content: bind for (level in levels)
Rectangle {
x: 0
y: 60 + (indexof level * 30)
width: level
height: 20
fill: LinearGradient {
startX: 0.0, startY: 0.0, endX: 0.0, endY: 1.0
stops: [ Stop { offset: 0.0 color: Color.LIGHTBLUE },
Stop { offset: 1.0 color: Color.DARKBLUE } ]
}
opacity: if (indexof level == selectedBarIndex) 1 else 0.7
onMousePressed: function(me:MouseEvent):Void {
selectedBarIndex = indexof level;
}
onMouseDragged: function(me:MouseEvent):Void {
if (me.x >= MIN_LEVEL and me.x <= MAX_LEVEL) {
levels[indexof level] = me.x;
}
}
}
onKeyPressed: function(ke:KeyEvent):Void {
if (ke.code == KeyCode.VK_RIGHT and levels[selectedBarIndex] <= MAX_LEVEL - 10) {
levels[selectedBarIndex] += 10;
}
else if (ke.code == KeyCode.VK_LEFT and levels[selectedBarIndex] > MIN_LEVEL + 10) {
levels[selectedBarIndex] -= 10;
}
else if (ke.code == KeyCode.VK_DOWN) {
selectedBarIndex = (selectedBarIndex + 1) mod sizeof levels;
}
else if (ke.code == KeyCode.VK_UP) {
selectedBarIndex = (sizeof levels + selectedBarIndex - 1) mod sizeof levels;
}
}
},
Text {
translateX: 25
translateY: 220
textOrigin: TextOrigin.TOP
font: Font {
name: "Sans serif"
size: 18
}
content: bind "Bar:{selectedBarIndex + 1}, Level: {levels[selectedBarIndex]}"
fill: Color.WHITE
}
]
}
}
groupRef.requestFocus();

Most of the UI components currently in JavaFX are Swing components in the Desktop Profile, which don't work on JavaFX Mobile. The next JavaFX release after the upcoming JavaFX SDK 1.1 version is slated to have lots of UI controls that will be in the Common profile, and will therefore work on JavaFX Mobile. My crystal ball is still in the repair shop, but I anticipate this release to be available before JavaOne 2009. Also, phones that support JavaFX Mobile are due to arrive by JavaOne 2009.

Please leave a comment if you have any questions.

0 comments:

Yang Sering Dibaca: