我以一种新的方式看待这个问题:
我有一个简单的FXML应用程序,它有一个mainapp,一个控制器和一个视图。视图显示由三行组成的网格窗格,其中每行包含一个标签元素。所以gridpane对用户来说是这样的:
row 1
row 2
row 3
在用户选择行后,还会有一个名为“删除所选行”的按钮。单击该按钮时,会从网格窗格中临时删除或隐藏该元素。因此,如果选择了第2行并单击了该按钮,则用户将看到
row 1
row 3
上面的视图是使用Scene Builder创建的,它创建了一个名为AppOverview.fxml
的XML文件。
有一个MainApp
绘制具有以下代码的场景:
public class MainApp extends Application {
private Stage primaryStage;
private BorderPane rootLayout;
//Constructor
public MainApp() {}
@Override
public void start(Stage primaryStage)
{
this.primaryStage = primaryStage;
primaryStage.initStyle(StageStyle.UNDECORATED);
initRootLayout();
showAppOverview();
}
// Initializes the root layout.
public void initRootLayout() {
try {
// Load root layout from fxml file.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(MainApp.class.getResource("view/RootLayout.fxml"));
rootLayout = (BorderPane) loader.load();
// Show the scene containing the root layout.
Scene scene = new Scene(rootLayout);
primaryStage.setScene(scene);
primaryStage.show();
} catch (IOException e) {
System.out.println("Error in MainApp:initRootLayout()");
System.exit(0);
}
}
// Shows the app overview inside the root layout.
public void showAppOverview() {
try {
// Load overview.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(MainApp.class.getResource("view/AppOverview.fxml"));
AnchorPane appOverview = (AnchorPane) loader.load();
// Set overview into the center of root layout.
rootLayout.setCenter(appOverview);
// Give the controller access to the main app.
AppController controller = loader.getController();
controller.setMainApp(this);
} catch (IOException e) {
System.exit(0);
}
}
// Returns the main stage.
public Stage getPrimaryStage(){
return primaryStage;
}
public static void main(String[] args) {
launch(args);
}
}
我的app.view包中的控制器包含handleDeleteBtn
按钮(以及其他几个按钮)和handleSelectedGridPaneRow()
上的侦听器,以管理网格窗格中的行选择:
public class AppController {
//Reference to MainApp
private MainApp mainApp;
@FXML
private void handleRestoreBtn(){
System.out.println("You are restoring the hidden row");
}
@FXML
private void handleDeleteBtn(){
System.out.println("You are hiding the selected row");
}
@FXML
private void handleExitBtn(){
System.exit(0);
}
@FXML
private void handleSelectedGridPaneRow(){
System.out.println("You have selected a row to hide");
}
public AppController(){}
// Initialize the <code>AppController</code> instance.
@FXML
private void initialize(){}
public void setMainApp(MainApp mainApp)
{
this.mainApp = mainApp;
}
}
我的具体问题是:
1)这种规格是否可以实现,即能够如上所述动态管理网格窗格?
2)如果是,我将在何处以及如何访问网格窗格?大概在AppController
中'handleDeleteBtn()'方法的某个地方。我需要做什么来引用Controller中的gridpane,然后执行gridPane.getChildren().remove(0,2);
等语句?
答案 0 :(得分:0)
我认为事实上我知道我的帖子的答案表明我的方法都是错的。无论如何,我发现的解决方案非常有效。我没有尝试删除和恢复网格窗格中的行,而是将网格窗格单独留在原始的1列和3行中,而是根据按下的按钮更改每个单元格的内容。因此,我将按钮处理程序的名称更改为更能反映我正在尝试的内容,并添加了额外的内容以显示另一行的组合:
@FXML
private void showRow1and2Btn(){
...
}
@FXML
private void showRow2and3Btn(){
...
}
@FXML
private void showAll(){
...
}
然后我声明了三个标签来显示我想要的行的内容:
@FXML
private Label label_0;
@FXML
private Label label_1;
@FXML
private Label label_2;
这些标签绑定到我在Scene Builder中构建的三个标签,它们占据了网格窗格中的三行。
我添加了这个方法,以根据我的规范填充三个网格窗格行:
private void setgridPaneRows(Label label, String str)
{
label.setText(str);
}
然后只是在按钮处理程序中获取内容以便实现所需效果的情况,例如:
private void showRow1and2Btn()
{
setgridPaneRows(label_0,"Label 0");
setgridPaneRows(label_1,"Label 1");
setgridPaneRows(label_2,null);
}
@FXML
private void showRow2and3Btn(){
setgridPaneRows(label_0,"Label 1");
setgridPaneRows(label_1,"Label 2");
setgridPaneRows(label_2,null);
}
@FXML
private void ShowAllBtn(){
setgridPaneRows(label_0,"Label 0");
setgridPaneRows(label_1,"Label 1");
setgridPaneRows(label_2,"Label 2");
}
在另一个应用程序中,我成功地扩展了这种方法,将第二列添加到gridpane并使用不同的控件填充这些元素,例如,我可以使gridpane 1,0包含一个输入需求的组合框,然后包含另一种输入要求的文本字段。