I am trying to represent a chessboard using JavaFX 11. Manually representing each square in FXML seemed tedious, so I opted to write some code in the controller (HelloController) that would represent each square for me. Here's what I have so far:
FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.GridPane?>
<VBox alignment="CENTER" spacing="20.0" xmlns:fx="http://javafx.com/fxml"
fx:controller="com.test.hellofx.HelloController">
<padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0"/>
</padding>
<Label fx:id="welcomeText"/>
<GridPane fx:id="chessBoard"/>
<Button text="Hello!" onAction="#setChessBoard"/>
</VBox>
Controller
package com.test.hellofx;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.StackPane;
public class HelloController {
@FXML
private Label welcomeText;
@FXML
private GridPane chessBoard = new GridPane();
// HelloController(){
// setChessBoard();
// onHelloButtonClick();
// }
@FXML
protected void onHelloButtonClick() {
welcomeText.setText("Welcome to JavaFX Application!");
// setChessBoard(chessBoard);
}
@FXML
public void setChessBoard() {
// System.out.println("Check");
for (int i = 1; i < 9; i++){
// Label letter = createLetterLabel(i);
// Label number = createNumberLabel(i);
chessBoard.add(createLetterLabel(i), i,0);
chessBoard.add(createLetterLabel(i), i,9);
chessBoard.add(createNumberLabel(i), 0, i);
chessBoard.add(createNumberLabel(i), 9, i);
}
// System.out.println("Check");
for (int i = 1; i < 9; i++){
for (int j = 1; j < 9; j++){
StackPane tile = new StackPane();
String tileColor;
if ((i + j) % 2 == 0) {
tileColor = "#f7f4cf";
} else {
tileColor = "#c68b6b";
}
tile.setStyle("-fx-background-color: "+tileColor+";");
chessBoard.add(tile, i, j);
}
}
}
private static Label createLetterLabel(int i){
char content = (char) ( ((int) 'a' ) + i - 1);
Label label = new Label();
label.setText(String.valueOf(content));
return label;
}
private static Label createNumberLabel(int i){
return new Label(String.valueOf(i));
}
}
package com.test.hellofx;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import java.io.IOException;
public class HelloApplication extends Application {
@Override
public void start(Stage stage) throws IOException {
// System.out.println("Check");
FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
Scene scene = new Scene(fxmlLoader.load(), 320, 240);
stage.setTitle("Hello!");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
With this current setup, the chessboard only gets initialized when the button is clicked. However, I would like the chessboard to be initialized upon running the program such that it appears without a button being clicked. I tried changing setChessBoard()
's signature and behavior to match this
public static GridPane setChessBoard(GridPane chessBoard)
and used that to initialize the chessboard like so
Gridpane chessBoard = setChessBoard(new Gridpane());
and though that runs, it does not display the chessboard (and the button hack does not work in this case since fxml does not seem to accept static methods)
What would be a better way to do this?