2016-07-06 66 views
0

我正在处理需要VBoxes的“表格”表示的项目。我对应用程序的分层布局是GridPane - > VBox(在其中一个单元格) - > VBoxes(显示不同数据集在彼此之上) - >数据。我有两个场景。JavaFX:动态添加VBox不显示

数据显示在场景1上。用户可以通过表单添加数据并单击场景2上的按钮。然后,添加的数据应显示在现有数据下面,作为父视图中的VBox 1再次。

下面是代码,这将使它明确:

我的场景1 .fxml文件看起来如下(简体):

<GridPane fx:id="grid" fx:controller="application.Controller"> 
    [here: ColumnConstraints] 
    <children> 
    <VBox fx:id="parentBox" GridPane.columnIndex="0" GridPane.rowIndex="1"/> 
    <Button fx:id="goToScene2" text="+" onAction="#goToScene2"/> 
    </children> 
</GridPane> 

场景2只是有一个按钮和一个文本字段:

<GridPane fx:id="grid" fx:controller="application.AddDataController"> 
    [here: ColumnConstraints] 
    <children> 
    <Button fx:id="addData" text="add" onAction="#bAddData"/> 
    <TextField fx:id="data"/> 
    </children> 
</GridPane> 

我的场景1控制器(Controller)是这样的:

public class Controller implements Initializable { 
    @FXML Button goToScene2; 
    @FXML VBox parentBox; 

    @Override 
    public void initialize(URL location, ResourceBundle resources) { 
    } 

    public void addData(String s) { 
    Label lbl = new Label(s); 
    VBox dataBox = new VBox(); 
    dataBox.setPadding(new Insets(15, 5, 15, 5)); 
    dataBox.setSpacing(5); 
    dataBox.setMaxHeight(80); 
    dataBox.getChildren().add(lbl); 
    parentBox.getChildren().add(dataBox); 
    } 
} 

这是设计的,因为dataBox包含的元素多于标签,但在这种情况下,这与我看起来并不相关。

我的场景2控制器(addDataController)看起来是这样的:

@FXML Button addData; 
@FXML TextField data; 

@FXML protected void bAddData(){ 
    String content = data.getText();  
    FXMLLoader fxmlLoader = new FXMLLoader(); 
    Pane p = fxmlLoader.load(getClass().getResource("scn1.fxml").openStream()); 
    Controller cont = (Controller) fxmlLoader.getController(); 

    cont.addData(content); 
} 

所以,当一个人点击在场景2的附加数据按钮,触发的方法输入的数据传送到现场的控制器这是因为现在应该在场景1中显示新数据。

觉得这样的逻辑不工作(这里编辑),因为当我之前并添加数据后索要

System.out.println(parentBox.getChildren().size(); 

,它总是有一个单一的儿童,即使它应该有一个更多...

如果我人为地填充字符串数组并将所有从addData到(String s)的所有内容移动到Initialize(...),它都可以工作,并且数据在父VBox中显示为VBox。

我没有发布主类,因为加载控制器和场景变化不是问题。

非常感谢大家的帮助! :)

+1

我不相信你用来调用'AddData(content)'的'Controller const'实例与''Scene'正在使用的'Controller'的实例是同一个实例。 FXMLLoader正在创建一个不在场景图中的新实例。一个简单的修复可能是将主场景控制器传递到第二个场景。你的'goToScene'方法是什么样的? – OttPrime

+0

这实际上是我没有见过的方式。但是,所使用的Controller是在.fxml文件中定义的,所以我无法从任何其他类访问它。它从未在JavaFX代码中加载过。使控制器类静态也没有工作。 – s4inz

+0

对不起。 'goToScene'方法在主程序类中调用一个方法并传递一个String。该字符串在switch-case语句中处理,并触发'currentStage.setScene(newScene)'。 – s4inz

回答

0

只是提供更详细的信息,连同一个想法,我不知道如何实施。

这是我的主类:

@Override 
public void start(Stage primaryStage) { 
    currentStage = primaryStage; 
    Parent root = FXMLLoader.load(getClass().getResource("Scene1.fxml")); 
    scene1 = new Scene(root); 
} 

我能在这一点上加载控制器并作出通过控制器的吸?所以我在整个程序中只有一个实例。

我试着插入:

FXMLLoader fxmlLoader = new FXMLLoader(); 
fxmlLoader.load(getClass().getResource("Scene1.fxml").openStream()); 
Controller controller = (Controller) fxmlLoader.getController(); 

Parent root ... 

行之后。但是,这是两次加载.xml文件。我怎样才能很好地连接两个部分?

非常感谢您耐心等待!

编辑::::::::: 下面的代码为我工作:现在

@Override 
public void start(Stage primaryStage) { 
    currentStage = primaryStage; 
    FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("Scene1.fxml")); 
    Parent root =(Parent) fxmlLoader.load(); 
    controller = (Controller) fxmlLoader.getController(); 
} 

,我可以问的主类controller,它总是通过该单个实例。

谢谢你指点我正确的方向! :)