-1

Im looking at this problem from in a new way:

I have a simple FXML app that has a mainapp, a controller and a view. The view displays a gridpane consisting of three rows where each row contains a single label element. So the gridpane looks like this to the user:

row 1
row 2
row 3

There is also a button called Delete Selected Row that is clicked after the user selects a row. When the button is clicked, the element is temporarily removed, or hidden, from the gridpane. So if row 2 is selected and the button is clicked the user will see

row 1
row 3

The above view is created with Scene Builder that creates an XML file called AppOverview.fxml.

There is a MainApp that paints the scene that has the following code:

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);
  }
}

The controller in my app.view package contains listeners on the handleDeleteBtn button (and a couple other buttons) and handleSelectedGridPaneRow() to manage row selection in the gridpane:

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;
 }

}

My specific questions are:
1) Is this kind of spec achievable, ie, being able to dynamically manage a gridpane as described?
2) If yes, where and how would I access the gridpane? Presumably somewhere in the method 'handleDeleteBtn()' in AppController. What do I need to do to reference the gridpane in the Controller and then execute statements such as gridPane.getChildren().remove(0,2);?

Rusty
  • 93
  • 1
  • 14
  • 1
    I propose to shorten the description and add a minimal example. – DVarga May 03 '17 at 07:58
  • Possible duplicate of [What is a NullPointerException, and how do I fix it?](http://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – fabian May 03 '17 at 16:13
  • No, it doesn't answer my question. I guess its impossible to achieve what I am trying to do so I apologise for wasting peoples time. – Rusty May 03 '17 at 18:39

1 Answers1

0

I think the fact I got know answers to my post indicated that my approach was all wrong. Anyway the solution I have found works very well. Instead of trying to remove and restore rows in the gridpane, I just left the gridpane alone with the original 1 column and 3 row and instead changed the content of each cell according to the button being pressed. So I changed the names of the button handlers to something more reflective to what I was attempting, and added an extra to display another combination of rows:

@FXML
private void showRow1and2Btn(){
...
}

@FXML
private void showRow2and3Btn(){
...
} 

@FXML
private void showAll(){
...
} 

Then I declared three labels to show the contents of the rows I want:

  @FXML
  private Label label_0;

  @FXML
  private Label label_1;

  @FXML
  private Label label_2;

These labels are bound to three labels that I built in Scene Builder and which occupy the three rows in the gridpane.

I added this method to get the three gridpane rows populated according to my spec:

  private void setgridPaneRows(Label label, String str)
  {
    label.setText(str);
  }

Then its just a case of getting something into the button handlers so the desired effect is achieved, for example:

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");
}

In another application I have successfully extended this approach to adding a second column to the gridpane and populating these elements with different controls, so for example, I can make gridpane 1,0 contain a combo box for one input requirement and then contain a textfield for another kind of input requirement.

Rusty
  • 93
  • 1
  • 14