ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Introduction to JavaFX Script
Pages: 1, 2, 3, 4, 5, 6

The second application simulates a set of pop-up menus that can be dragged on the screen. With a simple click on the menu headers you can hide/show the items using a nice opacity effect. The whole design was written with JavaFX drawing capabilities:

Listing 20
import javafx.ui.*;
import javafx.ui.canvas.*;
import javafx.ui.filter.*;
import java.lang.System;
class MenuOptions extends CompositeNode{
attribute px: Integer;
attribute py: Integer;
attribute lx: Integer;
attribute ly:Integer;
attribute lw:Integer;
attribute itemsOpacity:Number;
attribute menutext: String;
}
trigger on new MenuOptions {
    this.px = 0;
    this.py = 0;
    this.menutext = "";
    this.lx = 0;
    this.ly = 0;
    this.lw = 150;
    this.itemsOpacity = 0.0;
    }
function MenuOptions.composeNode() = 
Group {
    transform: bind []
    opacity: bind itemsOpacity
    content:[Rect {
    x: bind lx
    y: bind ly
    width: lw
    height: 20
    arcHeight: 10
    arcWidth: 10
    fill: Color {red:190 green:181 blue:215}
    stroke: Color {red:68 green:54 blue:103}
    strokeWidth: 2
    onMouseEntered: operation(e:CanvasMouseEvent) {
    if(itemsOpacity == 0.7) {itemsOpacity = 1.0;}
    }
    onMouseExited: operation(e:CanvasMouseEvent) {
    if(itemsOpacity == 1.0) {itemsOpacity = 0.7;}
    }
    onMouseClicked: operation(e:CanvasMouseEvent) {
    eventListener(this.menutext);
    }
    },
    Text {
    x: bind lx+5
    y: bind ly+5
    content: bind menutext
    font: Font {face: VERDANA, style: [BOLD], size: 11}
    fill:Color {red:68 green:54 blue:103}
    }]
    };
class MainMenu extends CompositeNode{
attribute option: String;
attribute px: Integer;
attribute py: Integer;
attribute lx: Integer;
attribute ly:Integer;
attribute lw:Integer;
attribute menutext: String;
attribute step: Integer;
attribute submenu: MenuOptions+;
operation addSubmenu(t:MenuOptions);
operation show_hide();
}
trigger on new MainMenu {
    this.option = "";
    this.px = 0;
    this.py = 0;
    this.menutext = "";
    this.lx = 0;
    this.ly = 0;
    this.lw = 150;
    this.step = 20;
    this.submenu = null;
    }
operation MainMenu.addSubmenu(t:MenuOptions) {
t.lx = this.lx;
t.lw = this.lw;
t.ly = this.ly+step;
step=step+20;
insert t into submenu;
}
operation MainMenu.show_hide() {
if(submenu.itemsOpacity[1] == 0.7){submenu.itemsOpacity =
 [0.7,0.6,0.5,0.4,0.3,0.2,0.1,0.0] dur 1200;}
    else if(submenu.itemsOpacity[1] == 0.0){
    submenu.itemsOpacity =
     [0.1,0.2,0.3,0.4,0.5,0.6,0.7] dur 1200;}
}
function MainMenu.composeNode() = 
Group {
    transform: bind []
    content:[Rect {
    x: bind lx
    y: bind ly
    height: 20
    width: bind lw
    arcHeight: 10
    arcWidth: 10
    fill: Color {red:68 green:54 blue:103}
    stroke: Color {red:190 green:181 blue:215}
    strokeWidth: 2
    onMouseDragged: operation(e:CanvasMouseEvent) {
    lx += e.localDragTranslation.x;
    ly += e.localDragTranslation.y;
    submenu.lx += e.localDragTranslation.x;
    submenu.ly += e.localDragTranslation.y;
    }
    onMouseClicked: operation(e:CanvasMouseEvent) {
    show_hide();
    }
    },
    Text {
    x: bind lx+5
    y: bind ly+5
    content: bind menutext
    font: Font {face: VERDANA, style: [BOLD], size: 11}
    fill:Color {red:190 green:181 blue:215}
    },
    bind submenu]
};
var menu_1 = new MainMenu();
menu_1.lx = 120;
menu_1.ly = 140;
menu_1.lw = 128;
menu_1.menutext = "Navigate";
var submenu_11 = new MenuOptions();
submenu_11.menutext = "Go to Class...";
var submenu_12 = new MenuOptions();
submenu_12.menutext = "Go to Test";
var submenu_13 = new MenuOptions();
submenu_13.menutext = "Back";
var submenu_14 = new MenuOptions();
submenu_14.menutext = "Forward";
var submenu_15 = new MenuOptions();
submenu_15.menutext = "Go to Line...";
menu_1.addSubmenu(submenu_11);
menu_1.addSubmenu(submenu_12);
menu_1.addSubmenu(submenu_13);
menu_1.addSubmenu(submenu_14);
menu_1.addSubmenu(submenu_15);
var menu_2 = new MainMenu();
menu_2.lx = 260;
menu_2.ly = 140;
menu_2.lw = 90;
menu_2.menutext = "Refactor";
var submenu_21 = new MenuOptions();
submenu_21.menutext = "Rename....";
var submenu_22 = new MenuOptions();
submenu_22.menutext = "Pull Up...";
var submenu_23 = new MenuOptions();
submenu_23.menutext = "Push Down...";
menu_2.addSubmenu(submenu_21);
menu_2.addSubmenu(submenu_22);
menu_2.addSubmenu(submenu_23);
operation eventListener(s:String) {
System.out.println("You choose:{s}");
}
Frame {
    centerOnScreen: true
    visible: true
    height: 500
    width: 500
    title: "JavaFX - Menu"
    onClose: operation() {System.exit(0);}
    content: ScrollPane {
    background: white
    view: Canvas {
    background: black
    cursor: DEFAULT
    content: [menu_1, menu_2]
    }
    }
}

Running listing 20
Figure 9. Running Listing 20

Notice that JavaFX uses triggers (like SQL) instead of constructors. A trigger is marked by the trigger keyword and is made of a header and a body. The header indicates the event that must occur before executing the body content. A trigger can be created, inserted, deleted, or replaced. You can find more details about triggers on the OpenJFX site.

Conclusion

JavaFX Script is a capable new language for the Java platform. With it, you can easily build rich, dynamic interfaces in much less time than you could build something comparable in Java with Swing and Java 2D. In this article, we have stepped through the basic syntax, looked at IDE support, and built a demonstration application that shows off some of JavaFX's Capabilities. JavaFX will quickly become a necessary tool in the Java developer's toolbox.

Resources

Anghel Leonard is a senior Java developer with more than 12 years of experience, specializing in GIS applications. He has written two books about XML and Java.


Return to ONJava.com.