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 |
---|
language | javafx |
---|
collapse | true |
---|
| <?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.textlayout.TextPane?>
<?import javafx.scene.control.TextFieldGroup?>
<?import javafx.scene.controlshape.ButtonCircle?>
<?import javafx.scene.layoutshape.BorderPaneLine?>
<?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?>
<Pane xmlns:fx="http://javafx.com/fxml"
minWidth="400" minHeight="600">
<Group layoutY="50">
<Pane xmlns:fx="http://javafx.com/fxml"
minWidth="400" minHeight="600">
<Group layoutY="50">
<Circle layoutX="100" layoutY="20" radius="20" stroke="black" fill="white"/>
<Circle 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 layoutX="100" layoutY="50" visible="true">
<Line layoutY="0" endX="-10" 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= "10" endY="15" stroke="black"/>
</Group>
</Group>
</Pane>
|
| Code Block |
---|
| package trinn2;
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class StickMan1 extends Application {
@Override
public void start(Stage primaryStage) throws IOException {
Parent root = FXMLLoader.load(this.getClass().getResource("StickMan1.fxml"));
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
} |
Den komplette FXML-koden er vist til venstre. Import-linjene øverst trengs for å kunne bruke navn tilsvarende Java-klasser lenger ned i fila. F.eks. vil Circle egentlig referere til java-klassen javafx.scene.shape.Circle. Java-koden antar her at FXML-fila ligger i samme mappe som java-fila. |
...
Code Block |
---|
| @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 |
---|
| <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 |
---|
| 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 |
---|
language | javafx |
---|
collapse | true |
---|
| <?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.Group?>
<?import javafx.scene.shape.Circle?>
<?import javafx.scene.shape.Line?>
<BorderPane xmlns:fx="http://javafx.com/fxml"
minWidth="400">
<top>
<Button text="Walk!" onAction="#walk"/>
</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 |
---|
| 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() {
update();
}
void update() | Code Block |
---|
| 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 {
FXMLLoaderif fxmlLoader(direction == new FXMLLoader();
KeyCode.LEFT) {
fxmlLoaderleftEye.setControllersetVisible(thistrue);
Parent root = (Parent) fxmlLoaderrightEye.load(this.getClass().getResourceAsStream("StickMan2.fxml")setVisible(false);
} else if primaryStage.setScene(new Scene(root));
(direction == KeyCode.RIGHT) {
primaryStage.show( leftEye.setVisible(false);
}
@FXML Node stickMan, armsAndLegs1, armsAndLegs2;
rightEye.setVisible(true);
@FXML} Shapeelse eye;{
boolean step = leftEye.setVisible(true);
@FXML
void initializerightEye.setVisible(true) {;
update();}
}
voidif update(step) {
if (step) {leftEye.setFill(Color.BLUE);
eyerightEye.setFill(Color.BLUE);
);
} else {
} else { leftEye.setFill(Color.WHITE);
eyerightEye.setFill(Color.WHITE);
}
armsAndLegs1.setVisible(step);
armsAndLegs2.setVisible(! step);
}
@FXML
void walk( keyPressed(KeyEvent keyEvent) {
step = ! step;
if (keyEvent.getCode() == KeyCode.LEFT) {
step = ! step;
stickMan.setLayoutX(stickMan.getLayoutX() +- 5);
} update();else if (keyEvent.getCode() == KeyCode.RIGHT) {
}
public static void main(String[] args) {
stickMan.setLayoutX(stickMan.getLayoutX() + 5);
launch(args);
}
} | Code Block |
---|
language | javafx |
---|
collapse | true |
---|
| <?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>
} else if (keyEvent.getCode() == KeyCode.DOWN) {
stickMan.setLayoutY(stickMan.getLayoutY() + 5);
} else if (keyEvent.getCode() == KeyCode.UP) {
stickMan.setLayoutY(stickMan.getLayoutY() - 5);
} else {
return;
}
direction = keyEvent.getCode();
update();
}
public static void main(String[] args) {
launch(args);
}
} |
| Code Block |
---|
language | javafx |
---|
collapse | true |
---|
| <?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.Group?>
<?import javafx.scene.shape.Circle?>
<?import javafx.scene.shape.Line?>
<Pane xmlns:fx="http://javafx.com/fxml" minWidth="400 <Button text="Walk!" onAction="#walk"/>
</HBox>
</top>
<center>
<Pane minWidth="400" minHeight="600">
<Group<Pane fx:id="stickManstickManPane">
<Circle layoutX="100" layoutY="20" radius="20" stroke="black" fill="white"/ minWidth="400" minHeight="600" focusTraversable="true" onKeyPressed="#keyPressed">
<Group fx:id="stickMan">
<Circle fx:id="eye" <Circle layoutX="112100" layoutY="20" radius="220" stroke="black" fill="bluewhite"/>
<Line<Circle fx:id="leftEye" layoutX="12092" layoutY="20" startXradius="02" startYstroke="-4black" endXfill="3" endY="0" stroke="black"blue"/>
<Circle <Line fx:id="rightEye" layoutX="120110" layoutY="20" startXradius="3" startY="0" endX="02" endYstroke="1black" strokefill="blackblue"/>
<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>
Pane>
|
|