我有JavaFX项目,其中fxml和代码用于制作GUI。
如你所见,有2个JavaFX.TitledPane
。它们是以fxml创建的。在他们之后,我有一个JavaFX.Accordion
。我从JavaFX.TextField
获得了一些管道并生成它们。有一些不同类型的JavaFX.TitledPane
被放入手风琴。您可以在屏幕截图上看到不同的类型。
我有一个问题:Accordion中的每个TitledPane都有第一个ChoiceBox。这个ChoiceBox定义了TitledPane的类型。因此我们在#1屏幕截图上默认使用TitledPane。当用户从ComboBox中选择另一个项目时,我们需要重新创建TitledPane。此外,我们需要将数据保存在TitledPane的文本框中,并将其恢复到新的TitledPane中。请给我建议或部分代码,以正确的方式解决这个问题。
我有这样的Controller类:
public class Controller {
@FXML
TextField textFieldNonConservatismCoef;
@FXML
TextField textFieldDiffusionCoef;
@FXML
TextField textFieldFlowSpeed;
@FXML
TextField textFieldRiverDepth;
@FXML
TextField textFieldRiverWidth;
@FXML
TextField textFieldSubstance;
@FXML
TextField textFieldProportion;
@FXML
TextField textFieldLAC;
@FXML
TextField textFieldConcentration;
@FXML
TextField textFieldNumberOfPipes;
@FXML
Accordion accordionPlant;
public void fillAccordion(int numberOfPipes){
accordionPlant.getPanes().add(createTitledPaneCoastalConcentratedPipe(0));
accordionPlant.getPanes().add(createTitledPaneCoastalSpreadPipe(1));
}
//Create the first type of a TitledPane
protected TitledPane createTitledPaneCoastalConcentratedPipe(int index){
TilePane tile = new TilePane(Orientation.HORIZONTAL, 5, 5);
Label typeLabel = new Label("Тип выпуска");
ChoiceBox<String> choiceBoxTypeOfPipe = createChoiceBoxTypeOfPipes();
choiceBoxTypeOfPipe.getSelectionModel().select(0);
choiceBoxTypeOfPipe.setPrefWidth(choiceBoxTypeOfPipe.USE_COMPUTED_SIZE);
choiceBoxTypeOfPipe.setPrefHeight(choiceBoxTypeOfPipe.USE_COMPUTED_SIZE);
VBox typeContainer = new VBox(typeLabel,choiceBoxTypeOfPipe);
Label bankLabel = new Label("Берег");
bankLabel.setId("textWithTooltip");
Tooltip.install(bankLabel, new Tooltip("Берег, с которого производится выпуск"));
ChoiceBox<String> choiceBoxCoast = createChoiceBoxCoast();
choiceBoxCoast.getSelectionModel().select(0);
VBox bankContainer = new VBox(bankLabel, choiceBoxCoast);
Label labelCoordinateX = new Label("Точка выпуска (км)");
Tooltip.install(labelCoordinateX, new Tooltip("Координата x точки выпуска относительно положения контрольного створа"));
labelCoordinateX.setId("textWithTooltip");
TextField textFieldCoordinate = new TextField();
VBox coordinateContainer = new VBox(labelCoordinateX, textFieldCoordinate);
tile.getChildren().addAll(typeContainer, bankContainer, coordinateContainer);
TitledPane titledPane = new TitledPane("Параметры выпуска " + (index+1), tile);
return titledPane;
}
//Create the second type of a TitledPane
protected TitledPane createTitledPaneCoastalSpreadPipe(int index){
TilePane tile = new TilePane(Orientation.HORIZONTAL, 5, 5);
Label typeLabel = new Label("Тип выпуска");
ChoiceBox<String> choiceBoxTypeOfPipe = createChoiceBoxTypeOfPipes();
choiceBoxTypeOfPipe.getSelectionModel().select(1);
VBox typeContainer = new VBox(typeLabel,choiceBoxTypeOfPipe);
Label bankLabel = new Label("Берег");
bankLabel.setId("textWithTooltip");
Tooltip.install(bankLabel, new Tooltip("Берег, с которого производится выпуск"));
ChoiceBox<String> choiceBoxCoast = createChoiceBoxCoast();
choiceBoxCoast.getSelectionModel().select(0);
VBox bankContainer = new VBox(bankLabel, choiceBoxCoast);
Label labelCoordinateX = new Label("Точка выпуска (км)");
labelCoordinateX.setId("textWithTooltip");
Tooltip.install(labelCoordinateX, new Tooltip("Координата x точки выпуска относительно положения контрольного створа"));
TextField textFieldCoordinate = new TextField();
VBox coordinateContainer = new VBox(labelCoordinateX, textFieldCoordinate);
Label labelLength = new Label("Распределенная часть (м)");
labelLength.setId("textWithTooltip");
Tooltip.install(labelLength, new Tooltip("Длина распределенной части выпуска (м)"));
TextField textFieldLength = new TextField();
VBox lengthContainer = new VBox(labelLength, textFieldLength);
tile.getChildren().addAll(typeContainer, bankContainer, coordinateContainer, lengthContainer);
TitledPane titledPane = new TitledPane("Параметры выпуска " + (index+1), tile);
return titledPane;
}
//creates choiceBox of pipes
protected ChoiceBox<String> createChoiceBoxTypeOfPipes(){
return new ChoiceBox(FXCollections.observableArrayList("Береговой сосредоточенный",
"Береговой распределенный", "Русловой сосредоточенный", "Русловой рассеивающий",
"Русловой рассеивающий с двумя ветками выпуска"));
}
}
我不保存节点的实例,因为我不知道如何在重新创建后更改它们。我想我们需要了解标题窗格,其中选择框已更改,然后重新创建此标题窗格。但我们需要恢复以前的数据,我的方法无法恢复它们。所以,请。
解
感谢James_D,我找到了解决方案:我只需要ArrayList<Map<String, Node>>
每个Map
包含TextField
s和ChoiceBox
es。
protected TitledPane createTitledPanePipe(int index){
Map<String, Node> content = new HashMap<>();
/* Базовая часть всех труб */
TilePane tile = new TilePane(Orientation.HORIZONTAL, 5, 5);
Label typeLabel = new Label("Тип выпуска");
ChoiceBox<String> choiceBoxTypeOfPipe = createChoiceBoxTypeOfPipes();
choiceBoxTypeOfPipe.getSelectionModel().select("Береговой сосредоточенный");
content.put("choiceBoxTypeOfPipe", choiceBoxTypeOfPipe);
VBox typeContainer = new VBox(typeLabel,choiceBoxTypeOfPipe);
Label bankLabel = new Label("Берег");
bankLabel.setId("textWithTooltip");
Tooltip.install(bankLabel, new Tooltip("Берег, с которого производится выпуск"));
ChoiceBox<String> choiceBoxCoast = createChoiceBoxCoast();
content.put("choiceBoxCoast", choiceBoxCoast);
VBox bankContainer = new VBox(bankLabel, choiceBoxCoast);
Label labelCoordinateX = new Label("Точка выпуска (км)");
labelCoordinateX.setId("textWithTooltip");
Tooltip.install(labelCoordinateX, new Tooltip("Координата x точки выпуска относительно положения контрольного створа"));
TextField textFieldCoordinate = new TextField();
content.put("textFieldCoordinate", textFieldCoordinate);
VBox coordinateContainer = new VBox(labelCoordinateX, textFieldCoordinate);
tile.getChildren().addAll(typeContainer, bankContainer, coordinateContainer);
/*_______________________________________________________*/
/* Береговая распределенная труба */
Label labelLength = new Label();
labelLength.setId("textWithTooltip");
TextField textFieldLength = new TextField();
VBox lengthContainer = new VBox(labelLength, textFieldLength);
Label labelMiniPipes = new Label("Патрубки (м)");
labelMiniPipes.setId("textWithTooltip");
Tooltip.install(labelMiniPipes, new Tooltip("Расстояние между патрубками (м)"));
TextField textFieldMiniPipes = new TextField();
VBox miniPipesContainer = new VBox(labelMiniPipes, textFieldMiniPipes);
/* ___________________________________________________________ */
choiceBoxTypeOfPipe.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
switch (oldValue) {
case "Береговой распределенный":
content.keySet().remove("textFieldLength");
content.keySet().remove("textFieldMiniPipes");
tile.getChildren().remove(lengthContainer);
tile.getChildren().remove(miniPipesContainer);
break;
case "Русловой сосредоточенный":
content.keySet().remove("textFieldLength");
tile.getChildren().remove(lengthContainer);
break;
}
switch (newValue) {
case "Береговой распределенный":
content.put("textFieldLength", textFieldLength);
content.put("textFieldMiniPipes", textFieldMiniPipes);
labelLength.setText("Распределенная часть (м)");
Tooltip.install(labelLength, new Tooltip("Длина распределенной части выпуска (м)"));
tile.getChildren().addAll(lengthContainer, miniPipesContainer);
break;
case "Русловой сосредоточенный":
labelLength.setText("Протяженность (м)");
content.put("textFieldLength", textFieldLength);
Tooltip.install(labelLength, new Tooltip("Расстояние от берега до точки выпуска"));
tile.getChildren().addAll(lengthContainer);
break;
}
});
TitledPane titledPane = new TitledPane("Параметры выпуска " + index, tile);
this.dynamicComponents.add(content);
return titledPane;
}
目前尚不清楚实际问题是什么,或者为什么需要两种截然不同的方法。
为什么不这样做:
protected TitledPane createTitledPaneCoastalPipe(int index, boolean concentrate){
TilePane tile = new TilePane(Orientation.HORIZONTAL, 5, 5);
Label typeLabel = new Label("Тип выпуска");
ChoiceBox<String> choiceBoxTypeOfPipe = createChoiceBoxTypeOfPipes();
// remove this line:
// choiceBoxTypeOfPipe.getSelectionModel().select(1);
VBox typeContainer = new VBox(typeLabel,choiceBoxTypeOfPipe);
Label bankLabel = new Label("Берег");
bankLabel.setId("textWithTooltip");
Tooltip.install(bankLabel, new Tooltip("Берег, с которого производится выпуск"));
ChoiceBox<String> choiceBoxCoast = createChoiceBoxCoast();
choiceBoxCoast.getSelectionModel().select(0);
VBox bankContainer = new VBox(bankLabel, choiceBoxCoast);
Label labelCoordinateX = new Label("Точка выпуска (км)");
labelCoordinateX.setId("textWithTooltip");
Tooltip.install(labelCoordinateX, new Tooltip("Координата x точки выпуска относительно положения контрольного створа"));
TextField textFieldCoordinate = new TextField();
VBox coordinateContainer = new VBox(labelCoordinateX, textFieldCoordinate);
Label labelLength = new Label("Распределенная часть (м)");
labelLength.setId("textWithTooltip");
Tooltip.install(labelLength, new Tooltip("Длина распределенной части выпуска (м)"));
TextField textFieldLength = new TextField();
VBox lengthContainer = new VBox(labelLength, textFieldLength);
tile.getChildren().addAll(typeContainer, bankContainer, coordinateContainer);
choiceBoxTypeOfPipes.getSelectionModel().selectedIndexProperty().addListener(
(obs, oldIndex, newIndex) -> {
// may need different logic here: question is unclear
if (newIndex.intValue()==1) {
tile.getChildren().add(lengthContainer);
}
if (oldIndex.intValue()==1) {
tile.getChildren().remove(lengthContainer);
}
}
);
if (concentrate) {
choiceBoxTypeOfPipes.getSelectionModel().select(0);
} else {
choiceBoxTypeOfPipes.getSelectionModel().select(1);
}
TitledPane titledPane = new TitledPane("Параметры выпуска " + (index+1), tile);
return titledPane;
}
然后就是
public void fillAccordion(int numberOfPipes){
accordionPlant.getPanes().add(createTitledPaneCoastalPipe(0, true));
accordionPlant.getPanes().add(createTitledPaneCoastalPipe(1, false));
}
没有所有冗余代码,这不是你想做的吗?