无为

无为则可为,无为则至深!

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  190 Posts :: 291 Stories :: 258 Comments :: 0 Trackbacks

原作者: Anghel Leonard
时间:08/01/2007
翻译:Caoer
2007年8月8

JavaFX 代码同Java代码极容易集成. 这有一个使用JavaFX装载一个图片到窗体例子,它允许
使用者选择一个矩形区域保存这个矩形区域。这个捕捉保存操作由Java代码完成

源码列表 15

import java.io.*;

import javafx.ui.*;

import javafx.ui.canvas.*;

import javafx.ui.filter.*;

import java.awt.Robot;
import java.awt.Rectangle;

import java.awt.image.RenderedImage;

import javax.imageio.ImageIO;

import java.lang.System;

class CaptureExample extends CompositeNode{

attribute lx: Integer;

attribute ly: Integer;

operation CaptureExample();

attribute CaptureExample.lx = 0;

attribute CaptureExample.ly = 0;

operation saveCapture(lx_copy:Integer, ly_copy:Integer) {

    var robot = new Robot();

    var rect = new Rectangle (lx_copy, ly_copy, 50, 50);

    var BI=robot.createScreenCapture(rect);

    var file = new File(".//capture.jpg");

    ImageIO.write((RenderedImage)BI, "jpg", file);

     }

function CaptureExample.composeNode() =Group{

      transform: []

      content:[ImageView {

               transform: []

              image: Image { url: ".//app//Sunset.gif" }

      cursor: DEFAULT

      onMouseClicked: operation(e:CanvasMouseEvent) {

                    saveCapture(e.source.XOnScreen,e.source.YOnScreen);

                      }

      onMouseMoved: operation(e:CanvasMouseEvent) {

                           lx = e.x; ly = e.y;

                             }

       },

               Rect{

               x: bind lx y: bind ly width: 50 height:50 strokeWidth: 1 stroke: black }]

               };

Frame {

   centerOnScreen: true

   visible: true

   height: 230

   width: 300

   title: "Capture the screen..."

   onClose: operation() {System.exit(0);}

   content: ScrollPane {

              background: white

              view: Canvas {

              background: black

              cursor: DEFAULT

              content: CaptureExample }

   }

}

bind的用法. 它是一个用作增值和属性的延迟验证的重要JavaFX操作符。你能够从JavaFX编程语言文档中获得关于这个操作符的

更多信息。 同时需要注意的是,在上面程序中,用两个鼠标事件鼠标点击(onMouseClicked)和鼠标移动(onMouseMoved)

JavaFX支持以下的鼠标事件:  

·                onMouseClicked --鼠标点击

·                onMouseMoved --鼠标移动

·                onMousePressed --按住鼠标

·                onMouseExited --鼠标关闭

·                onMouseEntered --鼠标输入

·                onMouseReleased --释放鼠标

·                onMouseDragged --鼠标拖拽

你能狗使用JavaFX do later 语句进行异步执行的操作,参考代码如下:

源码列表 16

//使用do later 语句进行异步执行

import java.lang.System;

var s1 = "My name is ";

var s2 = "Anghel Leonard";

do later {

System.out.println(s2);

}

System.out.println(s1);

结果: My name is Anghel Leonard

JavaFX 允许你通过把要执行的代码放在do语句里面而使你能够在一个独立线程里执行代码一部分。使用AWT事件分派线程技术,将能够处理所有的输入事件。先面有一个使用在do语句中使用无线循环的例子。注意即使你有一个无限循环也能正常关闭窗口。

Listing 17

import javafx.ui.*;

import java.lang.System;

import javafx.ui.canvas.*;

import java.util.Random;

class DoExample extends CompositeNode{

 attribute randomfill: Color;

 operation changeOpacity();

}

attribute DoExample.randomfill = Color{red:0 green:0 blue:0};

operation DoExample.changeOpacity() {

 do{

    while(true) {

         var r = new Random();

         var g = r.nextInt(255);

         randomfill = Color{red:g green:g blue:g};

    }

 }

}

function DoExample.composeNode() =Group {

               transform: []

               content: [ Text { x: 20 y: 20 content: "Because of \"do\" you can close this window..."

               font: Font {face: VERDANA, style: [ITALIC, BOLD], size: 20}

               fill: bind randomfill opacity: 0.5

               onMouseClicked: operation(e:CanvasMouseEvent) { changeOpacity(); } }]

};

Frame {

 centerOnScreen: true

 visible: true

 height: 100

 width: 580

 title: "\"Do\" example..."

 onClose: operation() {System.exit(0);}

 content: ScrollPane {

        background: white

        view: Canvas {

               background: black

               cursor: DEFAULT       

               content: DoExample

               }

 }

}



JavaFX 代码能够用JavaFX标签类同HTML代码集成。这个类支持以web应用程序一样的使用模式使用HTMLCSS技术。

 Here is an example that renders an HTML table.

Listing 18

import javafx.ui.*;

import java.lang.System;

import javafx.ui.canvas.*;

class Partners {

 attribute name: String;

 attribute company: String;

 attribute phone: String;

 attribute e_mail: String;

 attribute partners: Partners*;

}

var myPartners = Partners {

        partners: [Partners{

               name: "Mary J"

               company: "Software ATV Inc."

               phone: "0900090345"

               e_mail: "maryj@yahoo.com" },

                Partners{

               name: "Leona W"

               company: "Winkle LTD"

               phone: "090849435"

               e_mail: "leonaw@yahoo.com" },

                Partners{

               name: "Joe T"

               company: "Press OJ"

               phone: "340909879"

               e_mail: joet@yahoo.com

               }

] };

Frame {

 content: Label {

        text: bind "<html> <h2 align='center'>- My Partners -</h2>

        <table align='center' border='0' bgcolor='#BBAAEE'>

        <tr bgcolor='#FFEE55'>

               <td><b>Name</b></td> <td><b>Company</b></td> <td><b>Phone</b></td> <td><b>E-mail</b></td>

        </tr> {

               if (sizeof myPartners.partners == 0)

               then "<tr bgcolor='#432211'><td colspan='8'><b> I have no partners...</b></td></tr>"

               else foreach (t in myPartners.partners)

               "<tr bgcolor='#FF25AD'>

               <td>{t.name}</td>

               <td>{t.company}</td>

               <td>{t.phone}</td>

               <td>{t.e_mail}</td>

               </tr>"

               }

               </table> </html>" }

visible: true

}

 

Running listing 18
7. 运行源码列表 18
在本文章最后一小节,我们将能够看到展示如何简单使用JavaFX构建复杂的动画效果的两个程序。第一个程序仿真一个时钟。这个设计基于使用JavaFX代码创建的四个图片。

 see two applications that illustrate how easy it is to build complex animations using JavaFX. The first application simulates an analog clock. The design is based on four images animated with JavaFX code.

Listing 19

import javafx.ui.*;

import javafx.ui.canvas.*;

import javafx.ui.filter.*;

import java.lang.System;

class Clock extends CompositeNode{

attribute seconds: Number+;

attribute minutes: Number+;

attribute hours: Number+;

operation startClock();

}

attribute Clock.seconds = 360;

attribute Clock.minutes = 360;

attribute Clock.hours = 360;

operation Clock.startClock() {

        do{

        while(true) {

               if(seconds>=360)

               {seconds = [0,6..360] dur 60000 linear;}

               if(minutes>=360) {minutes = 0; minutes = [0,6..360] dur 3600000 linear;}

               if(hours>=360) {hours = 0;hours = [0,6..360] dur 43200000 linear;}

               }

        }

}

function Clock.composeNode() = Group {

               onMouseClicked: operation(e:CanvasMouseEvent) {

                       startClock();

               }

               transform: [] content:[ImageView {

               image: Image { url: ".//app//clockempty.gif" }

               },

                 ImageView {

               transform: bind [translate(203,82),

               rotate (seconds,2.5,125)]

               image: Image { url: ".//app//l1.gif" }

               antialias: true },

                 ImageView {

               transform: bind [translate(203,100),

               rotate (minutes,2.5,107)]

               image: Image { url: ".//app//l2.gif" }

               antialias: true },

                 ImageView {

               transform: bind [translate(203,115),

               rotate (hours,2.5,92)]

               image: Image { url: ".//app//l3.gif" }

               antialias: true },

               Circle {

               cx: 205

               cy: 205

               radius: 13

               fill: red strokeWidth: 1 }]

        };

Frame {

centerOnScreen: true

visible: true

height: 450

width: 450

title: "JavaFX - Clock"

onClose: operation() {System.exit(0);}

content: ScrollPane {

               background: white

               view: Canvas { background: black cursor: DEFAULT content: Clock }

               }

}

 

Running listing 19
8. 运行源码列表 19
注意dur(duration)操作符。 JavaFX 提供该操作符主要是为了创建动画。它用来异步产生一个数组构建一个时间间隔 队列。从这个数组返回一个元素之前,JavaFX要等到计时等于指定的毫秒。这个处理重复执行直到所有元素都被返回。有四种插入算法类型:

  • linear
  • easein
  • easeout
  • easeboth

 

默认是 ease-in, ease-out 结合.
第二个程序模拟了一个弹出菜单的集合,菜单能够在屏幕上拖拽。 简单点击以下菜单头部,您就能 使用一个很好的不透明效果隐藏或者显示条目。整个设计使用JavaFX绘画功能实现。

源码列表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
9. 运行源码列表 20
注意JavaFX使用触发者(与SQL相似)代替构造函数、 instead of constructors.

一个触发者使用trigger 关键字有头部和体构成。头部指示执行体内容以前必须发生的实践。触发者能狗被创建、插入、删除或者替代。你能在OpenJFX网站上发现关于triggers更多细节。

小结

 

JavaFX 脚本是面向Java平台的一个非常有能力的新语言。使用它你能够在比使用SwingJava2D更短时间内更容易地建立丰富、动态界面。在本文中,你能够了解关于它的基本语法
,同时找到IDE支持,建立展示JavaFX能力的Demo小程序。JavaFX将很快变成Java开发者的工具箱中必要工具。

资源:

 



凡是有该标志的文章,都是该blog博主Caoer(草儿)原创,凡是索引、收藏
、转载请注明来处和原文作者。非常感谢。

posted on 2007-08-09 13:36 草儿 阅读(2783) 评论(1)  编辑  收藏 所属分类: javaJAVA WEB应用

Feedback

# re: JavaFX入门教程二 2008-11-02 11:20 ke.lan@sun.com
您好,最近我也在初学javafx,希望与您沟通交流。
  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: