Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Excerpt

Med JavaFX er det lett å lage enkel 2D-grafikk, og med FXML så blir det enda enklere!

 

Figurer i FXML

Med FXML er det nokså enkelt å lage større figurer, som en sammensetning av enkle figur-elementer som sirkler, rektangler og streker. En enkel strekmann kan se ut som følger med FXML:

...

Code Block
languagejava
    @FXML
    void walk() {
        step = ! step;
        stickMan.setLayoutX(stickMan.getLayoutX() + 5);
        update();
    }

@FXML angir at walk-metoden deltar i håndtering av hendelser vha. FXML-automatikken

 

Code Block
languagejavafx
        <HBox>
            <Button text="Walk!" onAction="#walk"/>
        </HBox> 

onAction="#walk" angir at knappens action-hendelse skal trigge walk-metoden

Her er komplett Java- og FXML-kode:

StickMan2

Teknikken beskrevet over er brukt i en utvidelse av eksemplet over, hvor en strekmann "spaserer" mot høyre og blunker når brukeren klikker på en knapp. Bevegelsen mot høyre håndteres ved å øke x-koordinaten for hvert steg (klikk på knappen), med følgende linje i walk-metoden: stickMan.setLayoutX(stickMan.getLayoutX() + 5); Skritt-effekten håndteres ved å ha to sett med armer og ben og veksle mellom dem ved å slå dem av og på med kall til setVisible-metoden. Blunke-effekten håndteres ved å veksle mellom to farger med kall til setFill-metoden. Steg-logikken er fordelt mellom walk-metoden, som bare lar step-feltet veksle mellom true og false, og update-metoden, som kaller setVisible- og setFill-metodene med verdier avhengig av step-feltet.

Code Block
    void update() {
        if (step) {
            eye.setFill(Color.BLUE);
        } else {
            eye.setFill(Color.WHITE);
        }
        armsAndLegs1.setVisible(step);
        armsAndLegs2.setVisible(! step);
    }

Her er komplett Java- og FXML-kode:

Code Block
languagejava
collapsetrue
package trinn2;

import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.shape.Shape;
import javafx.stage.Stage;

public class StickMan2 extends Application {
    @Override
    public void start(Stage primaryStage) throws IOException {
        FXMLLoader fxmlLoader = new FXMLLoader();
        fxmlLoader.setController(this);
        Parent root = (Parent) fxmlLoader.load(this.getClass().getResourceAsStream("StickMan2.fxml"));
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }
    @FXML Node stickMan, armsAndLegs1, armsAndLegs2;
    @FXML Shape eye;
    
    boolean step = true;
    @FXML
    void initialize() {
        update();
    }
    void update() {
        if (step) {
            eye.setFill(Color.BLUE);
        } else {
            eye.setFill(Color.WHITE);
        }
        armsAndLegs1.setVisible(step);
        armsAndLegs2.setVisible(! step);
    }
    @FXML
    void walk() {
        step = ! step;
        stickMan.setLayoutX(stickMan.getLayoutX() + 5);
        update();
    }
    public static void main(String[] args) {
        launch(args);
    }
}
Code Block
languagejavafx
collapsetrue
<?xml version="1.0" encoding="UTF-8"?>
 
<?import javafx.scene.text.Text?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.layout.HBox?>

<?import javafx.scene.layout.Region?>
<?import javafx.scene.Group?>
<?import javafx.scene.shape.Circle?>
<?import javafx.scene.shape.Line?>

<BorderPane xmlns:fx="http://javafx.com/fxml"
     minWidth="400">
    <top>
        <HBox>
            <Button text="Walk!" onAction="#walk"/>
        </HBox>
    </top>
    <center>
        <Pane minWidth="400" minHeight="600">
            <Group fx:id="stickMan">
                <Circle layoutX="100" layoutY="20" radius="20" stroke="black" fill="white"/>
                <Circle fx:id="eye" layoutX="112" layoutY="20" radius="2" stroke="black" fill="blue"/>
                <Line layoutX="120" layoutY="20" startX="0" startY="-4" endX="3" endY="0" stroke="black"/>
                <Line layoutX="120" layoutY="20" startX="3" startY="0" endX="0" endY="1" stroke="black"/>
                <Line layoutX="100" layoutY="40" endX="0" endY="30" stroke="black"/>
                <Group fx:id="armsAndLegs1" layoutX="100" layoutY="50" visible="true">
                    <Line layoutY="0"  endX= "-5" endY="10" stroke="black"/>
                    <Line layoutY="0"  endX= "10" endY="10" stroke="black"/>
                    <Line layoutY="20" endX="-10" endY="15" stroke="black"/>
                    <Line layoutY="20" endX=  "5" endY="15" stroke="black"/>
                </Group>
                <Group fx:id="armsAndLegs2" layoutX="100" layoutY="50" visible="false">
                    <Line layoutY="0"  endX="-10" endY="10" stroke="black"/>
                    <Line layoutY="0"  endX=  "5" endY="10" stroke="black"/>
                    <Line layoutY="20" endX= "-5" endY="15" stroke="black"/>
                    <Line layoutY="20" endX= "10" endY="15" stroke="black"/>
                </Group>
            </Group>
        </Pane>
    </center>
</BorderPane>

StickMan3

Dette er en annen variant som bruker de samme teknikkene, og lar brukeren bruke piltastene for å flytte strekmannen. Her er komplett Java- og FXML-kode:

Code Block
languagejava
collapsetrue
package trinn2;

import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Shape;
import javafx.stage.Stage;

public class StickMan3 extends Application {
    @Override
    public void start(Stage primaryStage) throws IOException {
        FXMLLoader fxmlLoader = new FXMLLoader();
        fxmlLoader.setController(this);
        Parent root = (Parent) fxmlLoader.load(this.getClass().getResourceAsStream("StickMan3.fxml"));
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }
    @FXML Pane stickManPane;
    @FXML Node stickMan, armsAndLegs1, armsAndLegs2;
    @FXML Shape leftEye, rightEye;
    
    boolean step = true;
    KeyCode direction = KeyCode.DOWN;
    
    @FXML
    void initialize() {
        stickManPane.requestFocus();
        update();
    }
    void update() {
        if (direction == KeyCode.LEFT) {
            leftEye.setVisible(true);
            rightEye.setVisible(false);
        } else if (direction == KeyCode.RIGHT) {
            leftEye.setVisible(false);
            rightEye.setVisible(true);
        } else {
            leftEye.setVisible(true);
            rightEye.setVisible(true);
        }
        if (step) {
            leftEye.setFill(Color.BLUE);
            rightEye.setFill(Color.BLUE);
        } else
Code Block
languagejava
collapsetrue
package trinn2;
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.shape.Shape;
import javafx.stage.Stage;
public class StickMan2 extends Application {
    @Override
    public void start(Stage primaryStage) throws IOException {
        FXMLLoader fxmlLoader = new FXMLLoader(leftEye.setFill(Color.WHITE);
           fxmlLoader rightEye.setControllersetFill(thisColor.WHITE);
        }
    Parent root = (Parent) fxmlLoaderarmsAndLegs1.load(this.getClass().getResourceAsStream("StickMan2.fxml"));setVisible(step);
        armsAndLegs2.setVisible(! step);        
    }
    primaryStage.setScene(new Scene(root));

    @FXML
    void primaryStage.show();
    }keyPressed(KeyEvent keyEvent) {
        step = ! step;
    @FXML Node stickMan, armsAndLegs1, armsAndLegs2;
    @FXML Shape eye;
if (keyEvent.getCode() == KeyCode.LEFT) {
       
    boolean step = true;
 stickMan.setLayoutX(stickMan.getLayoutX() - 5);
     @FXML
   } else void initialize(if (keyEvent.getCode() == KeyCode.RIGHT) {
        update();
    }
    void update() {
stickMan.setLayoutX(stickMan.getLayoutX() + 5);
        } else if  if (step(keyEvent.getCode() == KeyCode.DOWN) {
            eyestickMan.setFillsetLayoutY(Color.BLUEstickMan.getLayoutY() + 5);
        } else {
            eye.setFill(Color.WHITE);
   if (keyEvent.getCode() == KeyCode.UP) {
     }
        armsAndLegs1.setVisible(stepstickMan.setLayoutY(stickMan.getLayoutY() - 5);
        armsAndLegs2.setVisible(! step);
 } else {
   }
    @FXML
    void walk() { return;
        step}
 = ! step;
      direction = stickMan.setLayoutX(stickMan.getLayoutX() + 5keyEvent.getCode();
        update();
    }
    public static void main(String[] args) {
        launch(args);
    }
}
Code Block
languagejavafx
collapsetrue
<?xml version="1.0" encoding="UTF-8"?>
 
<?import javafx.scene.text.Text?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.layout.HBox?>

<?import javafx.scene.layout.Region?>
<?import javafx.scene.Group?>
<?import javafx.scene.shape.Circle?>
<?import javafx.scene.shape.Line?>

<BorderPane xmlns:fx="http://javafx.com/fxml"
     minWidth="400">
    <top>
        <HBox>
            <Button text="Walk!" onAction="#walk"/>
        </HBox>
    </top>
    <center>
        <Pane<BorderPane xmlns:fx="http://javafx.com/fxml"
     minWidth="400" minHeight="600">
    <top>
        <Group fx:id="stickMan" <Button text="Start!" onKeyPressed="#keyPressed"/>
    </top>
    <center>
        <Circle<Pane layoutXfx:id="100stickManPane" layoutYminWidth="20400" radiusminHeight="20600" strokeonKeyPressed="black" fill="white"/#keyPressed">
            <Group fx:id="stickMan">
                <Circle fx:id="eye"  <Circle layoutX="112100" layoutY="20" radius="220" stroke="black" fill="bluewhite"/>
                <Line<Circle layoutXfx:id="120leftEye" layoutYlayoutX="2092" startXlayoutY="020" startYradius="-42" endXstroke="3black" endYfill="0" stroke="blackblue"/>
                <Line<Circle layoutXfx:id="120rightEye" layoutYlayoutX="20110" startXlayoutY="320" startYradius="02" endXstroke="0black" endYfill="1" stroke="black"blue"/>
                <Line layoutX="100" layoutY="40" endX="0" endY="30" stroke="black"/>
                <Group fx:id="armsAndLegs1" layoutX="100" layoutY="50" visible="true">
                    <Line layoutY="0"  endX= "-5" endY="10" stroke="black"/>
                    <Line layoutY="0"  endX= "10" endY="10" stroke="black"/>
                    <Line layoutY="20" endX="-10" endY="15" stroke="black"/>
                    <Line layoutY="20" endX=  "5" endY="15" stroke="black"/>
                </Group>
                <Group fx:id="armsAndLegs2" layoutX="100" layoutY="50" visible="false">
                    <Line layoutY="0"  endX="-10" endY="10" stroke="black"/>
                    <Line layoutY="0"  endX=  "5" endY="10" stroke="black"/>
                    <Line layoutY="20" endX= "-5" endY="15" stroke="black"/>
                    <Line layoutY="20" endX= "10" endY="15" stroke="black"/>
                </Group>
            </Group>
        </Pane>
    </center>
</BorderPane>