Я создал программу на Java и пытаюсь создать для нее пользовательский интерфейс с помощью JavaFX. JavaFX поставляется с программным обеспечением Scene Builder, которое позволяет редактировать файл FXML, на который ссылается Java для создания макета пользовательского интерфейса.
В Scene Builder я создал серию круговых форм. Вот упрощенная версия файла FXML с 4 кружками:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.shape.Circle?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
<children>
<Circle fx:id="nCircle_0_0" fill="DODGERBLUE" layoutX="100.0" layoutY="120.0" onMouseClicked="#btnClick" onMouseEntered="#circleHover" onMouseExited="#circleLeave" radius="20.0" stroke="BLACK" strokeType="INSIDE" />
<Circle fx:id="nCircle_0_1" fill="DODGERBLUE" layoutX="150.0" layoutY="120.0" onMouseClicked="#btnClick2" onMouseEntered="#circleHover" onMouseExited="#circleLeave" radius="20.0" stroke="BLACK" strokeType="INSIDE" />
<Circle fx:id="nCircle_0_2" fill="DODGERBLUE" layoutX="200.0" layoutY="120.0" onMouseEntered="#circleHover" onMouseExited="#circleLeave" radius="20.0" stroke="BLACK" strokeType="INSIDE" />
<Circle fx:id="nCircle_0_3" fill="DODGERBLUE" layoutX="250.0" layoutY="120.0" onMouseEntered="#circleHover" onMouseExited="#circleLeave" radius="20.0" stroke="BLACK" strokeType="INSIDE" />
</children>
</AnchorPane>
Чтобы контролировать внешний вид этих круговых форм, мне нужно создать переменные, ссылающиеся на них, в моем файле Controller.Java. Я также поместил имена переменных в 2D-массив, потому что мне нужно ссылаться на них из других 2D-массивов в моей Java-программе:
package sample;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
public class Controller {
@FXML
public Button btn;
public Circle nCircle_0_0, nCircle_0_1, nCircle_0_2, nCircle_0_3;
public Circle theCircles [] = {nCircle_0_0, nCircle_0_1, nCircle_0_2, nCircle_0_3};
public Circle [][] circleGrid = new Circle[2][2];
// get method for circleGrid
public Circle [][] getcircleGrid(){
return circleGrid;
}
public void makeCircleGrid(){
int count = 0;
for (int row = 0; row < 2; row++){
for (int col = 0; col < 2; col++){
//theCircles[count] = new Circle();
circleGrid[row][col] = theCircles[count];
count += 1;
}
}
}
protected void printCirclesGrid(Circle [][] theGrid){
for (int row =0; row < 2; row++){
System.out.print(row);
for (int col = 0; col < 2; col++){
System.out.print("\t" + theGrid [row][col]);
}
System.out.println();
}
}
public void circleHover(MouseEvent event){
Circle value = (Circle)event.getSource();
value.setStrokeWidth(4);
}
public void circleLeave(MouseEvent event){
Circle value = (Circle)event.getSource();
value.setStrokeWidth(1);
}
@FXML
public void btnClick(MouseEvent event) {
nCircle_0_3.setFill(Color.web("#ed4b00"));
}
@FXML
public void btnClick2(MouseEvent event) {
circleGrid[1][0].setFill(Color.web("#ed4b00"));
}
}
Существует также файл Main.java, который запускает JavaFX и загружается в файл FXML:
package sample;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 600, 600));
primaryStage.show();
Controller startUp = new Controller();
startUp.makeCircleGrid();
startUp.printCirclesGrid(startUp.getcircleGrid());
}
public static void main(String[] args) {
launch(args);
}
}
Проблема, с которой я столкнулся, заключается в том, что мне нужно хранить ссылки на круги в 2D-массиве, потому что мне нужно ссылаться на них и управлять ими из других мест в моей Java-программе. Я попытался поместить все имена переменных в двумерный массив, но Java видит их как нулевые.
Если вы запустите три файла, перечисленных выше, появится окно с 4 синими кружками. При нажатии на первый круг последний круг станет красным. Однако нажатие на второй круг приведет к ошибке java.lang.NullPointerException. (Если бы это сработало так, как я надеялся, он бы стал вторым последним красным кругом).
Мне сказали, что мне нужно инициализировать переменную Circle, сделав ее равной экземпляру объекта Circle перед помещением его в 2D-массив. Это позволит обойти проблему нулевых значений в двумерном массиве. Но я не вижу, как я могу инициализировать значения Circle в файле Controller.java, потому что объекты Circle были созданы в файле FXML, а не в файле Controller.java. Можно ли как-то хранить и ссылаться на объекты, созданные в файле FXML?