Nylig oppdatert til JavaFX 8, så vi må ha Java 8. Sjekk i terminalen:
$ java -version
java version "1.8.0_40"
Java(TM) SE Runtime Environment (build 1.8.0_40-b27)
Java HotSpot(TM) 64-Bit Server VM (build 25.40-b25, mixed mode)
Versjonen bør minimum være 1.8.0_40
import javax.swing.*;
import javax.swing.border.*;
public class HelloSwing {
public static void start() {
JFrame frame = new JFrame("myApp");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel label = new JLabel("Hello World!");
label.setBorder(new EmptyBorder(50, 50, 50, 50));
frame.add(label);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(HelloSwing::start);
}
}
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.text.Text;
import javafx.scene.layout.BorderPane;
import javafx.geometry.Insets;
public class HelloWorld extends Application {
public void start(Stage stage) {
Text text = new Text("Hello World!");
BorderPane pane = new BorderPane(text);
pane.setPadding(new Insets(50));
Scene scene = new Scene(pane);
stage.setTitle("myApp");
stage.setScene(scene);
stage.show();
}
// trengs vanligvis ikke:
public static void main(String[] args) {
launch(args);
}
}
public void init()
public void start(Stage primaryStage)
public void stop()
IMPLEMENTASJON MÅ VÆRE PUBLIC!
Google, søk med:
javafx 8 api klassenavn
public class ClickyApp extends Application {
@Override
public void start(Stage stage) {
Button button = new Button("Click me!");
button.setOnAction(this::handleButtonClick);
BorderPane pane = new BorderPane(button);
pane.setPadding(new Insets(50));
Scene scene = new Scene(pane);
stage.setTitle("Clicky app");
stage.setScene(scene);
stage.show();
}
public void handleButtonClick(ActionEvent event) {
new Alert(Alert.AlertType.INFORMATION,
"You clicked the button!").showAndWait();
}
}
* imports utelatt fra nå av, full kode her:
Lager GUI som lagres som FXML-kode. Denne FXML-koden kan du kan laste med Java-kode.
Ikke lenger støttet av Oracle (som lager Java), men firmaet Gluon har tatt over ansvaret.
Nedlasting:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.control.*?>
<BorderPane xmlns="http://javafx.com/javafx/8.0.40"
xmlns:fx="http://javafx.com/fxml/1"
fx:controller="FxmlExample">
<center>
<Button text="Click me!" onAction="#handleButtonClick" />
</center>
<padding>
<Insets bottom="50.0" left="50.0" right="50.0" top="50.0" />
</padding>
</BorderPane>
FXML-kode, kan enten skrives for hånd eller genereres med SceneBuilder:
* basert på ClickyApp-eksempelet
public class FxmlExample extends Application {
@Override
public void start(Stage stage) throws IOException {
URL fxml = FxmlExample.class.getResource("FxmlExample.fxml");
Parent pane = FXMLLoader.load(fxml);
Scene scene = new Scene(pane);
stage.setTitle("Clicky app");
stage.setScene(scene);
stage.show();
}
public void handleButtonClick(ActionEvent event) {
new Alert(Alert.AlertType.INFORMATION,
"You clicked the button!").showAndWait();
}
}
Så laster vi koden på denne måten med FXMLLoader.load():
De aller fleste elementer i JavaFX har en spesiell type variabler som er av klassen javafx.beans.property.Property
Properties kan vi legge lyttere på, så vi kan gjøre ting når de endrer seg.
Vi kan også koble Properties sammen med bind(), slik at når den ene endrer seg blir den andre oppdatert.
public class PropertyExample extends Application {
public void start(Stage stage) {
TextField field = new TextField();
Text text = new Text();
text.textProperty().bind(field.textProperty());
VBox box = new VBox(10, field, text);
box.setPadding(new Insets(20));
Scene scene = new Scene(box);
stage.setTitle("Property Example");
stage.setScene(scene);
stage.show();
}
}
Hvis vi vil gjøre ting i bakgrunnen i en JavaFX-applikasjon kan vi bruke javafx.concurrent.Task
Task har Properties som progress og value vi enkelt kan oppdatere fra innsiden.
Disse kan vi lytte til og bruke med bind() fra utsiden til å oppdatere GUI når det trengs.
public class HelloTask extends Application {
Button button;
ProgressBar progress;
@Override
public void start(Stage stage) {
GridPane grid = new GridPane();
grid.setAlignment(Pos.CENTER);
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(25, 25, 25, 25));
button = new Button("Click me!");
button.setOnAction(this::handleClick);
grid.add(button, 0, 0);
progress = new ProgressBar();
progress.setProgress(0);
grid.add(progress, 0, 1);
Scene scene = new Scene(grid);
stage.setTitle("Hello Task!");
stage.setScene(scene);
stage.show();
}
// ...
// ...
ExecutorService executor = Executors.newCachedThreadPool();
@Override
public void stop() {
executor.shutdown();
}
// ...
Vi må selv sette opp en bakgrunnsarbeider som kan ta imot oppgavene våre.
Det gjør vi enkelt med java.util.concurrent.Executors
Når programmet lukkes må vi også stoppe arbeideren.
// ...
public void handleClick(ActionEvent event) {
Task<String> task = new Task<String>() {
@Override
protected String call() throws Exception {
updateValue("Working...");
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
return "Interrupted!";
}
updateProgress(i + 1, 10);
}
return "Done!";
}
};
progress.progressProperty().bind(task.progressProperty());
button.textProperty().bind(task.valueProperty());
executor.submit(task);
}
}
Denne presentasjonen:
Kode fra presentasjonen: