Tuning In With MyTVSchedule
MyTVSchedule uses the JavaFX common profile to display a TV guide over 24 hours. The sample demonstrates the capabilities of JavaFX by building a scheduler that uses graphics, animation and control. The user can mouse over on the horizontal or vertical axis to view a detail schedule for selected channels over a period of 24 hours. The view is enhanced by using pop-up images with a multiline text display to display context-sensitive infromation in detail.
Understanding the Code
MyTVSchedule uses the ToolBar container to add control buttons that implement a control panel. ToolBar is one of the JavaFX SDK 1.3 preview UI controls in com.sun.javafx.scene.control.ToolBar. Figure 1 displays the code fragment of the Panner class that implements the control panel.
public class Panner extends CustomNode{
....
override public function create():Node {
ToolBar {
styleClass:"toolbar"
items: [
imageButton("upArrow", "upArrow"),
imageButton("downArrow", "downArrow"),
imageButton("leftArrow", "leftArrow"),
imageButton("rightArrow", "rightArrow"),
]
}
}
}
Figure 1: Panner Class
The GuideNode class implements the main functions for this sample. The data is set up on a grid formed by rows and columns. Vertical and horizontal scrolling are implemented by using the scrollview function. javafx.scene.control.ScrollBarPolicy and javafx.scene.control.ScrollView help you set up and control scrolling. On mouse events, the panMouseHandler function implements horizontal scrolling. When the mouse curso hovers over a schedule, an image pops up with multiline text display. These capabilities are implemented by using the public classes- javafx.scene.text.Text .
public class GuideNode extends CustomNode {
....
function panMouseHandler (e:MouseEvent) {
println ("e {e.node.id}");
if (e.node.id == "rightArrow" ){
println ("{horiScroll.hvalue}: {horiScroll.hmin} : {horiScroll.hmax}");
if (horiScroll.hvalue == horiScroll.hmax){
horiScroll.hvalue += .10;
dataScroll.hvalue += .10;
}
} else if (e.node.id == "leftArrow") {
if (horiScroll.hvalue = horiScroll.hmin){
horiScroll.hvalue -= .10;
dataScroll.hvalue -= .10;
}
}
}
var vertScroll = ScrollView {
styleClass: "scroller"
translateY:26
node : rowButtons
vbarPolicy: ScrollBarPolicy.NEVER;
hbarPolicy: ScrollBarPolicy.NEVER;
layoutInfo: LayoutInfo { width: 115 height: 280 }
};
var horiScroll = ScrollView {
styleClass: "scroller"
translateX:115
node: colButtons;
vbarPolicy: ScrollBarPolicy.NEVER;
hbarPolicy: ScrollBarPolicy.NEVER;
layoutInfo: LayoutInfo { width: 680 height: 26 }
}
var dataScroll = ScrollView {
styleClass: "scroller"
translateX: 115
translateY:26
node: dataGrid
vbarPolicy: ScrollBarPolicy.NEVER;
hbarPolicy: ScrollBarPolicy.NEVER;
layoutInfo: LayoutInfo { width: 680 height: 280 }
}
override function create() : Node {
generateTimeTable ();
blocksMouse = true;
var corner = Rectangle {
translateY: 0
visible:true
width:115
height: 26
fill: Color.web ("0x415170", 0.0);
stroke: Color.web ("0x415170");
}
var text: Text = Text {
content: "CHANNEL"
translateX: bind (corner.width - text.boundsInLocal.width) / 2.0
translateY: bind (corner.height - text.boundsInLocal.height) / 2.0 + 3
textOrigin: TextOrigin.TOP
textAlignment: TextAlignment.CENTER
styleClass: "channelText"
}
...
}
}
Figure 2: GuideNode Class
The ImageThumbnail class implements the pop-up node for a detail channel infomration. The pop-up appears on entering a cell with a javafx.animation.transition.ScaleTransition animation. The pop-up hides with a the reverse ScaleTranstion animation.
public class ImageThumbnail extends CustomNode {
....
public var imageView = ImageView {
layoutX: 7
layoutY: 7
fitWidth: 231;
fitHeight: 130
preserveRatio: true
styleClass: "thumbnail";
};
// used for popups
var scaleTransition = ScaleTransition {
duration: .5s
node: bind this;
fromX: 0.0 toX: 1.0
fromY: 0.0 toY: 1.0
autoReverse: false
}
// used for hiding popups
var reverseTransition = ScaleTransition {
duration: .5s
node: bind this;
fromX: 1.0 toX: 0
fromY: 1.0 toY: 0
autoReverse: false
}
public function imageMouseOver(mouseX: Number, mouseY: Number) {
var mY = mouseY;
var mX = mouseX;
if (mouseY + height > Main.cStageHeight) {
mY = mouseY - height;
}
if (mouseX + width > Main.cStageWidth){
mX = mouseX - width;
}
this.layoutX = mX;
this.layoutY = mY;
group.visible = true;
scaleTransition.playFromStart();
}
public function imageMouseExit () {
scaleTransition.rate = -1;
reverseTransition.playFromStart();
}
....
}
Figure 3: Pop-up with ScaleTransition
