JavaFX 1.0 Example

Im letzten Beitrag habe ich kurz JavaFX vorgestellt. Zu den theoretischen Daten folgt nun ein kleines praktisches Beispiel.

Das Beispiel basiert auf das Tutorial von SUN [1] und wurde um die Eigenschaft erweitert, dass das Applet auch auf dem Desktop verwendet werden kann.

Das Beispiel erstellt eine analoge Uhr, welche man sich auf den Desktop ziehen kann. Der Fokus liegt auf die Implementierung und nicht auf jegliche graphische Feinheiten.

Ein JavaFX Script wie im unteren Listing zu sehen beinhaltet immer eine Stage Klasse. Dies ist der globale Container, der alle weiteren Elemente beinhaltet.

[lang=java] import javafx.scene.Scene; import javafx.stage.Stage;

var stage = Stage { title: "JavaFX Test Clock" width: 300 height: 300 scene: Scene { content: [] } } [/lang]

Da JavaFX eine deklarative Sprache ist, beschreibt man, was man haben will. Dafür gibt es verschiedene Propterties (wie in dem Fall: width, height, scene, content), die man belegen kann.

Ein Stage Container besitzt ein Scene, in dem verschiedene Nodes enthalten sind. Node kann hier als ein graphisches Element (Rectangle, Text, ImageView) angesehen werden. In dem oberen Listing gibt es noch keine Nodes - content ist ein leeres Array.

Eine Uhr besteht aus verschiedenen Kreisen und Linien für die Zeiger. Nun könnte man in dem stage.scene.content diese graphischen Elemente schreiben, da man jedoch etwas strukturierter arbeiten will, kapseln wir die Funktionalität in eine eigene Klasse. Im folgenden Listing ist ein Teil von Clock.fx zu sehen:

public class Clock extends CustomNode {

public var radius: Number = 77; public var centerX: Number = 144; public var centerY: Number = 144;

public var hours: Number; public var minutes: Number; public var seconds: Number;

public override function create(): Node { return Group { content: [ Group { transforms: Translate { x: centerX y: centerY } content: [ // displays the number of every third hour for (i in [3, 6, 9, 12]) Text { transforms: Translate { x: -5, y: 5 } fill: Color.GREEN font: Font { size: 16 } x: radius * (( i + 0 ) mod 2 * ( 2 - i / 3)) y: radius * (( i + 1 ) mod 2 * ( 3 - i / 3)) content: "{i}" },  //Text

      // display a yellow point for the rest of the
      // hours on the clock
      for (i in \[1..12\] )
        if (i mod 3 != 0 ) then Circle {
           transforms: Rotate {
              angle: 30 \* i
           }
           centerX: radius
           radius: 3
           fill: Color.YELLOW
        } // if
        else \[ \],

        // clock's first center circle
        Circle {
          radius: 5
          fill: Color.DARKRED
        }, //Circle
        // the smaller center circle
        Circle {
          radius: 3
          fill: Color.RED
        }, //Circle
        // the seconds hand
        Line {
          transforms: Rotate {
            angle: bind seconds \* 6
          }
          endY: -radius - 3
          strokeWidth: 2
          stroke: Color.VIOLET
        },  //Line
        // the hour hand
        Path {
          transforms: Rotate {
             angle: bind (hours + minutes / 60) \* 30 - 90
          }
          fill: Color.YELLOW
          elements: \[
             MoveTo {
                x: 4,
                y: 4
             },
             ArcTo {
                x: 4
                y: -4
                radiusX: 1
                radiusY: 1
             },
             LineTo {
                x: radius - 15
                y: 0
             },
          \] //elements
        },  // Path
        // the minutes hand
        Path {
          transforms: Rotate {
             angle: bind minutes \* 6 - 90
          }
          fill: Color.GREEN
          elements: \[
             MoveTo {
                x: 4,
                y: 4
             },
             ArcTo {
                x: 4
                y: -4
                radiusX: 1
                radiusY: 1
             },
             LineTo {
                x: radius
                y: 0
             },
          \] // elements
        } // Path
   \] // 2. Group content
 } // Group

] // Group content };  // Group } // create()

} // class

Um nun das Drag-and-Drop des Applets zu ermöglichen, erweitert man den Stage um einen sogenannten AppletStageExtension.

stage = Stage { title: "JavaFX Test Clock" width: 300 height: 300 style: StageStyle.TRANSPARENT onClose: function() { //System.exit(0); } visible: true scene: Scene { fill: bind if (inBrowser) Color.WHITE else Color.TRANSPARENT content: [ Clock {}, // drag controls dragArea, dragClosers, statusText ] } extensions: [ AppletStageExtension { shouldDragStart: function(e): Boolean { return inBrowser and e.primaryButtonDown and dragArea.hover; } onDragStarted: function(): Void { inBrowser = false; } onAppletRestored: function(): Void { inBrowser = true; } useDefaultClose: false } ] }

Die Funktion shoudDragStart() gibt an, ob die Drag-Drop-Funktionalität angeboten werden soll, oder nicht. Anzumerken ist, dass das Property AppletStageExtension.useDefaultClose = false ist, da ein eigenes Close-Symbol erstellt wurde. Beim Betätigen dieses Buttons schließt sich das Applet und kehrt zum Browser zurück - falls dieser noch vorhanden ist.

In dem oberen Listing beinhaltet stage.scene.content noch den Node "dragArea":

var dragArea:Rectangle = Rectangle { x: 155 y: 30 width: 420 height: 25 fill: Color.RED
onMouseDragged:function(e:MouseEvent):Void { stage.x += e.dragX; stage.y += e.dragY; } };

Das ist der Bereich, in dem der Nutzer das Applet herum ziehen kann. In der onMouseDragged() Funktion wird immer die aktuelle Position der Stage gesetzt.

Was passiert, wenn ein Applet auf den Desktop verschoben wird und das Browser-Fenster geschlossen wird? Dann bietet Java die Möglichkeit eine Verknüpfung zu erstellen. Dabei speichert es ein paar XML-Daten im User-Verzeichnis und setzt eine Verlinkung, um die Daten per Java Webstart zu starten.

Der Inhalt der JNLP-XML-Datei sieht z.B. so aus:

JavaFXClock Hafid Haddouti JavaFXClock

Ein Beispiel ist hier zu finde.

Links: [1] JavaFX Tutorial: http://java.sun.com/javafx/1/tutorials/build-javafx-nb-app/

comment

Comments

arrow_back

Previous

JavaFX 1.0

Next

Prototype each(), IE und null
arrow_forward