Software Engineering

JavaFX

We will be using JavaFX for the ChessForge GUI assignment. JavaFX is a toolkit for building graphical user interfaces that contains a multitude of widgets and features. You can learn a lot about JavaFX from the Oracle tutorial. This guide contains a collection of simple examples which should guide you in the development of your GUI.

Remember: if you have any questions about how to use particular JavaFX classes, check the JavaFX API.

Getting Started

To start writing your JavaFX application, complete the following steps:

CodeAppearance
public class MyApplication extends Application {
  public void start(Stage stage) throws Exception {
    Button button = new Button("Push me!");

    Scene scene = new Scene(button);
    stage.setScene(scene);

    stage.sizeToScene();
    stage.show();    
  }
}

Listeners / Event Handlers

We react to events such as button presses or mouse clicks not by modifying the JavaFX component but by providing it a listener to call. Such listeners are also called handlers or callbacks. In the following program, the button prints a message to the terminal when pressed.

CodeAppearance
Button button = new Button("Push me!");

button.setOnAction(actionEvent -> {
    System.out.println("Hello!");
});

Scene scene = new Scene(button);
stage.setScene(scene);

stage.sizeToScene();
stage.show();

Parent Containers

JavaFX components such as buttons or text labels may be grouped together in order to control how they appear together in the window. Components are grouped by placing them in the same Parent. The JavaFX libraries include several types of Parent; the following are a few examples you may be interested in.

CodeAppearance
Button button = new Button("Push me!");
Text text = new Text("Important Information Here");

VBox vbox = new VBox();
vbox.getChildren().addAll(button, text);

Scene scene = new Scene(vbox);
stage.setScene(scene);

stage.sizeToScene();
stage.show();
Button button = new Button("Push me!");
Text text = new Text("Important Information Here");

HBox hbox = new HBox();
hbox.getChildren().addAll(button, text);

Scene scene = new Scene(hbox);
stage.setScene(scene);

stage.sizeToScene();
stage.show();
Button button = new Button("Push me!");
Text text = new Text("Important Information Here");

BorderPane borderPane = new BorderPane();
borderPane.setCenter(button);
borderPane.setBottom(text);

Scene scene = new Scene(borderPane);
stage.setScene(scene);

stage.sizeToScene();
stage.show();
Button button = new Button("Push me!");
Text text = new Text("Important Information Here");

GridPane gridPane = new GridPane();
gridPane.add(button, 1, 0);
gridPane.add(text, 0, 1);

Scene scene = new Scene(gridPane);
stage.setScene(scene);

stage.sizeToScene();
stage.show();

Images and Resources

JavaFX includes an ImageView class which can be used to display an image. The Java standard libraries include code to load most common types of image files. Key to this is knowing how to get the files you want to use.

It’s possible to access the contents of the filesystem using the File class, but this makes your Java program depend upon the filesystem layout of the user’s computer. For a more portable solution, we can refer to the contents of the classpath: the set of directories where Java normally looks for .class files. This way, it’s possible to package your .class files into a JAR along with your other resources; your application is contained within a single archive file instead of in many files throughout the disk.

To do this in IntelliJ, you merely need to mark the directory containing the resources you want as a “resources root”. Once you have done so, you can use the path of the file relative to that root. For instance, suppose a directory in your project is named images. To load a file images/sprites/frog.png, we would use the string /sprites/frog.png.

CodeAppearance
ImageView imageView = new ImageView("sprites/frog.png");
Button button = new Button("Ta da!");

VBox vbox = new VBox();
vbox.getChildren().addAll(imageView, button);
vbox.setAlignment(Pos.CENTER);

Scene scene = new Scene(vbox);
stage.setScene(scene);

stage.sizeToScene();
stage.show();

Effects

JavaFX components may be decorated with Effect objects to transform their appearance. As with Parents, a number of Effects exist in the API; check the documentation for the abstract class Effect to learn more. Here are examples of a few.

CodeAppearance
ImageView imageViewA = new ImageView("sprites/frog.png");
ImageView imageViewB = new ImageView(imageViewA.getImage());

Effect effect = new Glow(0.7);
imageViewB.setEffect(effect);

HBox hbox = new HBox();
hbox.getChildren().addAll(imageViewA, imageViewB);
hbox.setAlignment(Pos.CENTER);

Scene scene = new Scene(hbox);
stage.setScene(scene);

stage.sizeToScene();
stage.show();
ImageView imageViewA = new ImageView("sprites/frog.png");
ImageView imageViewB = new ImageView(imageViewA.getImage());

Effect effect = new ColorAdjust(-0.5, 0.5, -0.3, 0.2);
imageViewB.setEffect(effect);

HBox hbox = new HBox();
hbox.getChildren().addAll(imageViewA, imageViewB);
hbox.setAlignment(Pos.CENTER);

Scene scene = new Scene(hbox);
stage.setScene(scene);

stage.sizeToScene();
stage.show();
ImageView imageViewA = new ImageView("/sprites/frog.png");
ImageView imageViewB = new ImageView(imageViewA.getImage());

Effect effect = new DropShadow(5, 3, 3, Color.BLACK);
imageViewB.setEffect(effect);

HBox hbox = new HBox();
hbox.getChildren().addAll(imageViewA, imageViewB);
hbox.setAlignment(Pos.CENTER);

Scene scene = new Scene(hbox);
stage.setScene(scene);

stage.sizeToScene();
stage.show();

Chaining Effects

Effects can be chained by the setInput method. This method allows an Effect to execute the provided Effect before it is applied itself. That is, b.setInput(a) will cause the b to apply a first and then itself.

CodeAppearance
ImageView imageViewA = new ImageView("/sprites/frog.png");
ImageView imageViewB = new ImageView(imageViewA.getImage());

Glow glow = new Glow(0.7);
ColorAdjust colorAdjust = new ColorAdjust(0.2, 0.5, 0, 0);
glow.setInput(colorAdjust);
imageViewB.setEffect(glow);

HBox hbox = new HBox();
hbox.getChildren().addAll(imageViewA, imageViewB);
hbox.setAlignment(Pos.CENTER);

Scene scene = new Scene(hbox);
stage.setScene(scene);

stage.sizeToScene();
stage.show();