是否可以在 JavaFX 中创建一个控制器数组?
Is it possible to create an array of Controllers in JavaFX?
我进行了很好的搜索,要么我没有使用正确的术语,要么这个问题还没有出现。我已经在 Java 编写代码几年了,最近几周我才开始玩 Java FX。
上下文:
我正在尝试创建一个实际上是测验的应用程序,但我不想让每个问题都有一个新的 Pane/Tab,而是让它们并排显示。
我已经为单个问题创建了一个 questionController,但我不确定创建许多 questionController 的最佳方法,这些 questionController 都是由 fx:id 唯一标识的。
我希望我的 GUI 可以缩放,这样用户就可以 select 每轮显示的问题数量。如果不手动设置使用不同数量的问题控制器创建视图,我似乎无法弄清楚如何做到这一点。
我尝试过的事情
- 添加控制器gridPane,
- 在 FXML 中导入控制器
但这不能缩放,因为我的按钮刚变成 button0 - buttonN
如果您需要更多信息,请告诉我。
问题Controller.java
public class QuestionController implements Initializable {
@FXML
private ComboBox<String> chordCombo;
@FXML
private Label questionField;
@FXML
private Button submitButton;
@FXML
private ToggleGroup answerGroup;
@FXML
private RadioButton toggle0, toggle1, toggle2, toggle3, toggle4;
@Override
public void initialize(URL fxmlFileLocation, ResourceBundle resources) {
submitButton.setOnAction((event) -> {
System.out.println("Submit Logic");
});
answerGroup.selectedToggleProperty().addListener(new ChangeListener<Toggle>() {
public void changed(ObservableValue<? extends Toggle> ov, Toggle old_toggle, Toggle new_toggle) {
if (answerGroup.getSelectedToggle() != null) {
System.out.println(answerGroup.getSelectedToggle().toString());
}
}
});
}
QuestionController.fxml
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="235.0" prefWidth="203.0" styleClass="layout" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="uk.co.temp.QuestionController">
<children>
<BorderPane layoutX="-11.0" layoutY="35.0" prefHeight="235.0" prefWidth="203.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<bottom>
<Button fx:id="submitButton" mnemonicParsing="false" text="Submit" BorderPane.alignment="CENTER">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding>
<BorderPane.margin>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</BorderPane.margin>
</Button>
</bottom>
<top>
<Label fx:id="questionField" text="Insert Question Here" BorderPane.alignment="CENTER">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding>
<BorderPane.margin>
<Insets left="10.0" right="10.0" top="10.0" />
</BorderPane.margin>
</Label>
</top>
<center>
<GridPane BorderPane.alignment="CENTER">
<columnConstraints>
<ColumnConstraints halignment="CENTER" hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<RadioButton fx:id="toggle0" mnemonicParsing="false" text="Answer A">
<toggleGroup>
<ToggleGroup fx:id="answerGroup" />
</toggleGroup></RadioButton>
<RadioButton fx:id="toggle1" mnemonicParsing="false" text="Answer B" toggleGroup="$answerGroup" GridPane.rowIndex="1" />
<RadioButton fx:id="toggle2" mnemonicParsing="false" text="Answer C" toggleGroup="$answerGroup" GridPane.rowIndex="2" />
<RadioButton fx:id="toggle3" mnemonicParsing="false" text="Answer D" toggleGroup="$answerGroup" GridPane.rowIndex="3" />
<RadioButton fx:id="toggle4" mnemonicParsing="false" text="Answer E" toggleGroup="$answerGroup" GridPane.rowIndex="4" />
</children>
<padding>
<Insets top="10.0" />
</padding>
</GridPane>
</center>
</BorderPane>
</children>
</AnchorPane>
我想你正在寻找这样的东西:
TilePane pane = new TilePane(); // or whatever you are putting the questions in...
int numQuestions = ... ;
QuestionController[] controllers = new QuestionController[numQuestions];
for (int questionNumber = 0 ; questionNumber < numQuestions ; questionNumber++) {
FXMLLoader loader = new FXMLLoader(getClass().getResource("path/to/QuestionController.fxml"));
pane.getChildren().add(loader.load());
controllers[questionNumber] = loader.getController();
}
显然,如果 TilePane
(或其他)在另一个 FXML 文件中定义并注入到另一个控制器中,您可以根据需要在该控制器中将相同的代码放入事件处理程序或初始化方法中。
我进行了很好的搜索,要么我没有使用正确的术语,要么这个问题还没有出现。我已经在 Java 编写代码几年了,最近几周我才开始玩 Java FX。
上下文:
我正在尝试创建一个实际上是测验的应用程序,但我不想让每个问题都有一个新的 Pane/Tab,而是让它们并排显示。
我已经为单个问题创建了一个 questionController,但我不确定创建许多 questionController 的最佳方法,这些 questionController 都是由 fx:id 唯一标识的。
我希望我的 GUI 可以缩放,这样用户就可以 select 每轮显示的问题数量。如果不手动设置使用不同数量的问题控制器创建视图,我似乎无法弄清楚如何做到这一点。
我尝试过的事情
- 添加控制器gridPane,
- 在 FXML 中导入控制器
但这不能缩放,因为我的按钮刚变成 button0 - buttonN
如果您需要更多信息,请告诉我。
问题Controller.java
public class QuestionController implements Initializable {
@FXML
private ComboBox<String> chordCombo;
@FXML
private Label questionField;
@FXML
private Button submitButton;
@FXML
private ToggleGroup answerGroup;
@FXML
private RadioButton toggle0, toggle1, toggle2, toggle3, toggle4;
@Override
public void initialize(URL fxmlFileLocation, ResourceBundle resources) {
submitButton.setOnAction((event) -> {
System.out.println("Submit Logic");
});
answerGroup.selectedToggleProperty().addListener(new ChangeListener<Toggle>() {
public void changed(ObservableValue<? extends Toggle> ov, Toggle old_toggle, Toggle new_toggle) {
if (answerGroup.getSelectedToggle() != null) {
System.out.println(answerGroup.getSelectedToggle().toString());
}
}
});
}
QuestionController.fxml
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="235.0" prefWidth="203.0" styleClass="layout" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="uk.co.temp.QuestionController">
<children>
<BorderPane layoutX="-11.0" layoutY="35.0" prefHeight="235.0" prefWidth="203.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<bottom>
<Button fx:id="submitButton" mnemonicParsing="false" text="Submit" BorderPane.alignment="CENTER">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding>
<BorderPane.margin>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</BorderPane.margin>
</Button>
</bottom>
<top>
<Label fx:id="questionField" text="Insert Question Here" BorderPane.alignment="CENTER">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding>
<BorderPane.margin>
<Insets left="10.0" right="10.0" top="10.0" />
</BorderPane.margin>
</Label>
</top>
<center>
<GridPane BorderPane.alignment="CENTER">
<columnConstraints>
<ColumnConstraints halignment="CENTER" hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<RadioButton fx:id="toggle0" mnemonicParsing="false" text="Answer A">
<toggleGroup>
<ToggleGroup fx:id="answerGroup" />
</toggleGroup></RadioButton>
<RadioButton fx:id="toggle1" mnemonicParsing="false" text="Answer B" toggleGroup="$answerGroup" GridPane.rowIndex="1" />
<RadioButton fx:id="toggle2" mnemonicParsing="false" text="Answer C" toggleGroup="$answerGroup" GridPane.rowIndex="2" />
<RadioButton fx:id="toggle3" mnemonicParsing="false" text="Answer D" toggleGroup="$answerGroup" GridPane.rowIndex="3" />
<RadioButton fx:id="toggle4" mnemonicParsing="false" text="Answer E" toggleGroup="$answerGroup" GridPane.rowIndex="4" />
</children>
<padding>
<Insets top="10.0" />
</padding>
</GridPane>
</center>
</BorderPane>
</children>
</AnchorPane>
我想你正在寻找这样的东西:
TilePane pane = new TilePane(); // or whatever you are putting the questions in...
int numQuestions = ... ;
QuestionController[] controllers = new QuestionController[numQuestions];
for (int questionNumber = 0 ; questionNumber < numQuestions ; questionNumber++) {
FXMLLoader loader = new FXMLLoader(getClass().getResource("path/to/QuestionController.fxml"));
pane.getChildren().add(loader.load());
controllers[questionNumber] = loader.getController();
}
显然,如果 TilePane
(或其他)在另一个 FXML 文件中定义并注入到另一个控制器中,您可以根据需要在该控制器中将相同的代码放入事件处理程序或初始化方法中。