Application ของเราในวันนี้ เราจะสร้าง ทรงกลม กับข้อความ (sphere and text)

ทรงกลมจะเปลี่ยนความทึบแสง (opacity) ตามช่วงเวลาที่ระบุ

และเรายังลากทรงกลมไปมาได้ด้วยเมาส์

 

 

 

Credit : เนื้อหาและรูปภาพทั้งหมด มาจาก JavaFX.com

แต่มันเป็น tutorial ภาษาอังกฤษ เราลองทำตามดูแล้ว ก็เลยเขียนเป็นภาษาไทยไว้

เผื่อคนอื่นสนใจ จะได้ง่ายขึ้นอีกนิดจ้า 

 

1. สร้าง  JavaFX Script Application project.

a. Choose File > New Project (Ctrl-Shift-N).

b. ในช่อง Project Name ตั้งชื่อว่า FirstJavaFXSphere

c. ในช่อง Project Location ใส่ที่ๆจะเก็บไฟล์โปรเจค

 

 

d. จากนั้นคลิก Finish  จะปรากฏ Main.fx ในส่วนของ   source editor ตามรูป


 

 

สังเกตว่าจะมีโค๊ดที่ Main.fx โดยอัตโนมัติ จะมีพวก  import กับ object literals (เช่น Stage) 

2. แก้ไขโค๊ด  Stage object ตามตัวอย่างข้างล่าง เพื่อใส่  title  ให้ window

   และแก้ไข  Scene object  เพื่อระบุขนาดของ content area และ text ที่ต้องการให้ปรากฏในapplication

a. แก้ไข Stage and Scene object literals ให้เหมือนข้างล่าง เราสามารถ copy บรรทัดที่เป็นตัวหนาและ paste ลงไป  สังเกตว่าพอวางลงไปแล้ว จะมี error flag ขึ้นมา  โดยเราจะแก้ไข error นี้ในขั้นตอนต่อไป

 

Source Code

Stage {

     title: "My First JavaFX Sphere"

     scene: Scene {

         width: 300

         height: 300

         content: [

             Text {

                font: Font { size: 22 }

                x: 20, y: 90

               textAlignment: TextAlignment.CENTER

               content:"Welcome to \nJavaFX  World"

 

             }  //Text

        ] // content

     } // Scene

 

} // Stage

 

b. คลิกขวาตรงไหนก็ได้ที่ว่างๆ แล้วเลือก Fix Imports (Ctrl+Shift+I) เพื่อเอา error ออกไป
จะปรากฏ  import statement ดังข้างล่างนี้ ในส่วนบนสุดของ Main.fx file.

 

Source Code

import javafx.scene.text.TextAlignment;

 

3. ใส่ Circle object ที่เราจะทำให้มันเป็นทรงกลม โดยคลิกขยายส่วนของ Basic Shapes ที่อยู่ในหน้าต่าง Palette แล้วลาก Circle มาวางไว้ในบรรทัดที่อยู่บน Text code block ดังรูปที่แสดงข้างล่าง 

 

 

 

4. แก้ไขค่าของตัวแปรต่างๆ เพื่อให้ใส่ข้อความลงไปได้ แล้วก็ใส่ RadialGradient เพิ่มลงไปเพื่อให้มีความลึก มันจะได้มีหน้าตาเหมือนรูปทรงกลมมากขึ้น

a. แก้ไขโค๊ดตามตัวอย่างที่เป็นตัวหนา

Source Code

Stage {

    title: "My First JavaFX Sphere"

    width: 300

    height: 300

 

    scene: Scene {

        content: [

            Circle {

                centerX: 100,

                centerY: 100

                radius: 90

 

                fill: RadialGradient {

                        centerX: 75

                        centerY: 75

                        radius: 90

                        proportional: false

                        stops: [
                            Stop {
                            offset: 0.0
                            color: Color.web("#3B8DED")
                            },
                            Stop {
                            offset: 1.0
                            color:Color.web("#044EA4")
                            }

                        ] // stops

                } // RadialGradient

 

             } // Circle

             Text {

               font: Font { size: 22 }

               x: 20, y: 90

               textAlignment: TextAlignment.CENTER

               content:"Welcome to \nJavaFX  World"

             }  //Text

        ] // content

     } // Scene 

} // Stage

 

b. คลิกขวาแล้วเลือก  Fix Imports (Ctrl+Shift+I)  จะปรากฏ  import statement ดังข้างล่างนี้ ในส่วนบนสุดของ Main.fx file

   

Source Code

import javafx.scene.paint.RadialGradient;

import javafx.scene.paint.Stop;  

 

5. Save (Ctrl+S) และดู Preview โดยคลิกปุ่ม Preview button ที่อยู่บน toolbar.
จะมี Preview window ขึ้นมา แสดงรูปวงกลมที่เราพึ่งปรับแต่งให้มันดูคล้ายทรงกลม  

 

 

6.  โดย default แล้วตัวหนังสือถูกกำหนดให้เป็นสีดำ เราสามารถเปลี่ยนเป็นสีขาวได้ ด้วยการแก้ไขสีตรงตัวแปร fill

 

Source Code

Text {

    font: Font { size: 22 }

    x: 20, y: 90

    textAlignment: TextAlignment.CENTER

    content:"Welcome to \nJavaFX  World"

    fill: Color.WHITE

}

 

7. เพิ่ม animation ที่จะเปลี่ยนค่า opacity ของทรงกลม

a. เพิ่มตัวแปร opacity และกำหนดค่าเริ่มต้นให้เป็น 1.0 ตัวแปรนี้จะถูกใช้ใน timeline ที่เราจำสร้างในขั้นตอนต่อไป

 

Source Code

var opacity = 1.0;

 

Stage {

    title: "My First JavaFX Sphere"

    width: 300

    height: 300

   

b. เพิ่ม opacity instance variable เข้าไปใน Circle object และผูกมันเข้ากับ opacity global variable

 

Source Code

Circle {

    centerX: 100, centerY: 100

    radius: 90

    opacity: bind opacity

    fill: RadialGradient {

        centerX: 75

        centerY: 75

        radius: 90

        proportional: false

        stops: [

            Stop {

                offset: 0.0

                color: Color.web("#3B8DED")

            },

            Stop {

                offset: 1.0

                color:Color.web("#044EA4")

            }

        ] // stops

    } // RadialGradient

}

c. ขยายส่วนของ Animation ที่อยู่ในหน้าต่าง Palette   ลาก Timeline มาไว้ตรงบรรทัดที่อยู่ก่อน Stage code block เหมือนในภาพ

 

 

การเคลื่อนไหวจะเกิดขึ้นตลอด timeline ซึ่งแสดงแทนด้วย  javafx.animation.Timeline object

ทุก timeline จะมีอย่างน้อย 1  key frames ซึ่งแสดงแทนด้วยjavafx.animation.KeyFrame objects

 

d. เปลี่ยนค่าของตัวแปร time จาก 1s  เป็น 5s

 

Source Code

Timeline {

    repeatCount: Timeline.INDEFINITE

    keyFrames : [

        KeyFrame {

            time : 5s

            canSkip: true

 

        } // KeyFrame

    ] // keyFrames

} // Timeline

 

timeline จะวนซ้ำไปเรื่อยๆ รอบละ 5 วินาทีตามที่เรากำหนด

e. ลาก  Animation > Values element จาก  Palette มาไว้บนบรรทัดหลังตัวแปร time 

 

 

Values จะเป็นการกำหนดตัวแปรที่จะให้มีการเปลี่ยนแปลงค่าไป ในแต่ละ key frame

f. copy บรรทัดตัวหนาข้างล่าง

 

Source Code

 

Timeline {

    repeatCount: Timeline.INDEFINITE

    keyFrames : [

        KeyFrame {

            time : 5s

            canSkip: true

            values : [

               opacity => 0.2 tween Interpolator.LINEAR 

            ] // values

        } // KeyFrame

    ] // keyFrames

} // Timeline

 

 ค่าของ opacity จะถูกกำหนดภายในรอบ 5 วินาทีของ keyframe.

เครื่องหมาย => operator provides a literal constructor (a special notation) that makes it easier to express the list of key interpolated values or object properties.

เราใช้ tween operator เพื่อค่อยๆแก้ไขค่า opacity ระหว่าง 1.0 ถึง 0.2

The Interpolator.LINEAR is the built-in interpolator instance that provides linear time interpolation.

g. เพิ่ม KeyFrame เข้าไปอีกอัน เพื่อเปลี่ยน opacity จาก 0.2 ถึง 1.0 ภายในรอบ 5 วินาทีต่อมา

 

Source Code

Timeline {

    repeatCount: Timeline.INDEFINITE

    keyFrames : [

        KeyFrame {

            time : 5s

            canSkip: true

            values : [

               opacity => 0.2 tween Interpolator.LINEAR

            ] // values

        } // KeyFrame

        KeyFrame {

            time : 10s

            canSkip: true

            values : [

               opacity => 1.0 tween Interpolator.LINEAR

            ] // values

        } // KeyFrame

    ] // keyFrames

} // Timeline

 

h. เติม .play(); ต่อท้ายในส่วนที่ประกาศ Timeline object  เหมือนที่แสดงเป็นตัวหนาข้างล่าง

play() method จะทำการเล่น timelineที่กำหนด

 

Source Code

Timeline {

    repeatCount: Timeline.INDEFINITE

    keyFrames : [

        KeyFrame {

            time : 5s

            canSkip : true

            values : [

            opacity => 0.2 tween Interpolator.LINEAR

            ]//values

        }//KeyFrame

        KeyFrame {

            time : 10s

            canSkip : true

            values : [

            opacity => 1.0 tween Interpolator.LINEAR

            ]//values

        }//KeyFrame

    ]

}.play(); //Timeline


8. เพิ่มความสามารถในการเคลื่อนย้ายทรงกลมได้ โดยการคลิกเมาส์แล้วลาก
ตำแหน่งของ objects ใน  application ถูกระบุโดยใช้  absolute coordinates.

เราจะแก้ไขโค๊ด เพื่อให้ตำแหน่งของ object ขึ้นอยู่กับตำแหน่งของ  mouse pointer.

อย่าลืมว่าทรงกลมจะต้องถูกลากไปพร้อมกับ RadialGradient และตัวหนังสือ เมื่อเราต้องการให้หลายๆ object มีพฤติกรรม/ความสามารถที่เหมือนๆกัน เราควรจะทำการรวมมันให้เป็นกลุ่มเดียวกัน (group)

a. สร้างตัวแปร x และ y  กำหนดค่าเริ่มต้นให้เป็น 100.0 ตัวแปรนี้จะผูกตำแหน่งของวงกลมกับตำแหน่งของเมาส์

 

Source Code

var opacity = 1.0;

var x = 100.0;

var y = 100.0;

 

Timeline {

    repeatCount: Timeline.INDEFINITE

    keyFrames: [

 

b. ผูกตำแหน่งของ Circle object เข้ากับตัวแปร x และ y ดังโค๊ดตัวอย่างด้านล่าง
นำ  translateX และ translateY ไปแทนที่ centerX และ centerY ซึ่งจะกำหนด X และ Y coordinates ของการเคลื่อนย้ายวงกลมไป

 

Source Code

scene: Scene {

    content: [

       Circle {

           translateX: bind x

           translateY: bind y

 

           radius: 90

 

c. แก้ไข coordinates ของจุดศูนย์กลางของ RadialGradient To get a new value for the centerX coordinate, substract the current value of translateX, which is 100, from the initial value of centerX, which is 75. Thus you obtain -25. Perform a similar calculation for the centerY coordinate.

 

Source Code

fill: RadialGradient {

    centerX: -25

    centerY: -25

    radius: 90

 

d. คลิกขวาตรงที่ว่างๆ แล้วเลือก Fix Imports (Ctrl+Shift+I) จะทำการ import javafx.transform.Translate

e. ลบตัวแปร x และ  y  ที่ระบุตำแหน่งของตัวหนังสือออก แล้วใส่ Translate transformation แล้วผูกตัวแปร x และ y  เข้ากับตัวแปร x และ y   ที่เป็น Global

 

Source Code

Text {

    font: Font { size: 22 }

    textAlignment: TextAlignment.CENTER

    content:"Welcome to \nJavaFX  World"

    fill: Color.WHITE

    transforms: [

        Translate{

            x: bind x - 76

            y: bind y - 10

        }

    ]

}

 

ลอง Preview ดูว่าแก้ไขไปแล้ว หน้าตาวงกลมและข้อความยังเหมือนเดิมรึป่าว

f. แก้ไข content เพิ่มทำการรวมกลุ่มของวงกลมและตัวหนังสือเข้าด้วยกัน

 

Source Code

scene: Scene {

    width: 300

    height: 300

    content: Group {

        content: [

            Circle {

                translateX: bind x

                translateY: bind y

                radius: 90

                opacity: bind opacity

                fill: RadialGradient {

                    centerX: -25

                    centerY: -25

                    radius: 90

                    proportional: false

                    stops: [

                        Stop {

                            offset: 0.0

                            color: Color.web("#3B8DED")

                        },

                        Stop {

                            offset: 1.0

                            color:Color.web("#044EA4")

                        }

                    ] // stops

                 } // RadialGradient

              }//Circle

 

             Text {

                 font: Font { size: 22 }

                 textAlignment: TextAlignment.CENTER

                 content:"Welcome to \nJavaFX  World"

                 fill: Color.WHITE

                 transforms: [

                     Translate{

                         x: bind x - 76

                         y: bind y - 10

                     }

                 ]

             }  //Text

        ] // content

    } //Group

} // Scene

 

g. คลิกขวาตรงที่ว่างๆแล้วเลือก Fix Imports (Ctrl+Shift+I) จะทำการ import javafx.scene.Group

  h. ลาก Action > onMouseDragged จาก Palette มาไว้ก่อนเครื่องหมายปีกกาปิดของGroup object 

 

 

 

 

i.Copy บรรทัดที่เป็นตัวหนาไปวาง เพื่อกำหนด function ที่จะถูกเรียกเมื่อเกิดเหตุการณ์ mouse-dragged event

 

Source Code

onMouseDragged: function( e: MouseEvent ):Void {

x = e.x;

y = e.y;

}

 

9. Save และ run the project.

a.  ในหน้าต่าง project คลิกขวาที่ FirstJavaFXSphere project แล้วเลือก Run Project.
Netbeans จะทำการ compile จะเตรียมไฟล์ที่จำเป็นในการรัน application เมื่อcompiled สำเร็จ จะปรากฏทรงกลมที่เปลี่ยน opacity

b. ลองลากทรงกลมด้วยเมาส์  สังเกตว่าเราสามารถลากทรงกลมออกนอกหน้าต่าง application ได้

ขั้นตอนต่อไป เราจะปรับปรุงให้มันลากออกไปนอกหน้าต่างแล้วหายไป

 

10. สร้างตัวแปรแบบ global ชื่อ X และ Y เพื่อจะนำไปใช้คำนวณ ในการควบคุมการลากทรงกลม

 

Source Code

var x = 100.0;

var y = 100.0;

var X;

var Y;

 

a. ลาก Action > onMousePressed จาก Palette ไปไว้ที่บรรทัดก่อน onMouseDragged function

b. Copy บรรทัดที่เป็นตัวหนาเพื่อกำหนด function ที่จะถูกเรียกเมื่อเกิดเหตุการณ์ mouse-pressed

 

Source Code

onMousePressed: function( e: MouseEvent ):Void {

    X = e.sceneX - e.node.translateX;

    Y = e.sceneY - e.node.translateY

}

c. Here e.sceneX หมายถึง X coordinate ของจุดที่เกิดเหตุการณ์เกี่ยวกับเมาส์

 e.node.translateX หมายถึง X coordinate ของมุมซ้ายบนของ node เมื่อเกิดเหตุการณ์เกี่ยวกับเมาส์

d. Copy บรรทัดตัวหนาไปวางเพื่อแก้ไข onMouseDragged function.

 

Source Code

onMouseDragged: function( e: MouseEvent ):Void {

   if (e.sceneX - X <0) {

        e.node.translateX = 0;

    } else { if (e.sceneX - X > 280 - e.node.boundsInLocal.width){

           e.node.translateX = 280 - e.node.boundsInLocal.width;

    } else {

           e.node.translateX = e.sceneX - X;

    }

    }

    if (e.sceneY - Y <0) {

        e.node.translateY = 0;

    } else {if (e.sceneY - Y > 280 - e.node.boundsInLocal.height){

           e.node.translateY = 280 - e.node.boundsInLocal.height;

    } else{

         e.node.translateY = e.sceneY - Y;

    }

    }

}

 

11.Save the code and run the project.

ตอนนี้ทรงกลมก็ไม่สามารถลากออกนอก scene ได้อีกต่อไป


สำเร็จแล้ว  JavaFX application ชิ้นแรกของเรา

 

 

 

Comment



smilebig smileopen-mounthed smileconfused smilesad smileangry smiletonguequestionembarrassedsurprised smilewinkdouble winkcry

Tweet

โอโห เอา โค้ดมา ขนาดนี้ คนทั่วไปจะเข้าใจมั้ยเนี่ยsad smile sad smile

#1 By Pygmii on 2009-06-08 01:48

เห็น code แล้วนึกถึง flash version เก่า ที่ทำเป็นรูปแบบ class เอา java มาเล่นแบบนี้ รู้สึกว่าใช้ flash จะดีกว่า

ปล. ยังไง java fx ก็ต้องมีจุดเด่นในตัวมันเองสิน่า

#2 By s23697 on 2009-06-08 07:37

โอ้ว้าววววว
ละเอียดถี่ยิบมากเลยค่ะ

Ps.ขอบคุณที่แวะไปเยี่ยมกันนะคะconfused smile

#3 By [Tikky] My Moment on 2009-06-08 12:40

ขอการ

เชค Even การกดปุ่มบนมือถืออะไรแบบนี้อะค่ะ

พอจาทำได้รึป่าว ขอวิธีการทำแบบข้างบนเลย ขอบคุณค้ะ

#4 By (125.24.171.249) on 2009-06-15 22:08

แน่นอนครับ JavaFX มีจุดเด่น เรื่องการติดต่อกับ Java ได้เป็นอย่างดี เช่น ใช้ FX สร้าง Graph แต่เอาข้อมูลมาจาก JDBC หรือแม้แต่ติดต่อเวปแอพ อย่าง Servlet หรือ JSP ครับ
รายละเอียดของ JavaFx ยังมีอีกมา ตัวอย่างเช่น สามารถเอา code เดิมที่เราเขียนนี่ละ แต้ไปรันบน Mobile , TV(ในอนาคต) ก็ได้คับ

#5 By kasa (58.10.103.81) on 2009-08-03 09:35

เดี๋ยวนี้ ไม่เขียนบทความลง web guitarist แต่หันมาเอาดีกับ Java แทนแล้วเหรอจ๊ะ นู๋วิว :-)

#6 By pleX (82.227.198.156) on 2009-09-04 00:38