0

grid stays null when user clicks the button that calls 'pressLookUp' User is suppose to go from an old stage to the new one in the fxml file. And before the new window is shown, I want to add in values to the grids children from the database using grid.add(node, colIndex, rowIndex)

Controller:

package login;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
import userGroups.User;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class studentOptionsController{
@FXML
private GridPane grid;//gridpane from ClassesToAdd

public void pressLookUp(ActionEvent event) throws IOException{
    Parent userOption = FXMLLoader.load(getClass().getResource("ClassesToAdd.fxml"));
    Scene classesToAddScene = new Scene(userOption);
    Stage app_stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
    app_stage.setScene(classesToAddScene);
    app_stage.show();

    Connection c = null;
    Statement stmt = null;
    try{
        c = DriverManager.getConnection("jdbc:sqlite:users.db");
        c.setAutoCommit(false);

        System.out.println("Opened database successfully");
        stmt = c.createStatement();

        ResultSet rs = stmt.executeQuery("SELECT * FROM Classes WHERE IDCLASSES= " + "5;");

        int currentIndex = 0;
        int currentRow = 0;
        //assusming all columns are NOT NULL
        while(rs.next()){
            Label currentLabel = new Label();
            currentLabel.setText(rs.getString("CLASSNAME"));
            System.out.println(currentLabel.getText());
            grid.add(currentLabel, 5, 0 );
            /*if (rs.getString("SUSERNAME") != null && rs.getString("STUDENTPASS") != null){
                String  username = rs.getString("SUSERNAME");
                System.out.println( "SUSERNAME = " + username );
                String password = rs.getString("STUDENTPASS");
                System.out.println("STUDENTPASS = " + password);
            }*/
        }
        rs.close();
        stmt.close();
        c.close();
    } catch ( Exception e ){
        System.err.println( e.getClass().getName() + ": " + e.getMessage() );
        //System.exit(0);
    }
    System.out.println("Operation done successfully");
}
}

FXML:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>

<GridPane fx:id="grid" prefHeight="400.0" prefWidth="850" 
xmlns="http://javafx.com/javafx/8.0.121" xmlns:fx="http://javafx.com/fxml/1" 
fx:controller="login.studentOptionsController">
  <columnConstraints>
      <ColumnConstraints percentWidth="11" />
      <ColumnConstraints percentWidth="11" />
      <ColumnConstraints percentWidth="11" />
      <ColumnConstraints percentWidth="11" />
      <ColumnConstraints percentWidth="11" />
      <ColumnConstraints percentWidth="11" />
      <ColumnConstraints percentWidth="11" />
      <ColumnConstraints percentWidth="11" />
       <ColumnConstraints percentWidth="12" /> <!-- This column for 'Add 
 Class' buttons ?-->
   </columnConstraints>
   <rowConstraints>
      <RowConstraints />
   </rowConstraints>
   <children>
  <Label maxHeight="Infinity" maxWidth="Infinity" style=" -fx-border-color:gray; " text="Class Name" GridPane.columnIndex="0" GridPane.rowIndex="0" />
  <Label maxHeight="Infinity" maxWidth="Infinity" style=" -fx-border-color:gray; " text="Size of Class" GridPane.columnIndex="1" GridPane.rowIndex="0" />
  <Label maxHeight="Infinity" maxWidth="Infinity" style=" -fx-border-color:gray; " text="Spots Taken" GridPane.columnIndex="2" GridPane.rowIndex="0" />
  <Label maxHeight="Infinity" maxWidth="Infinity" style=" -fx-border-color:gray; " text="Instructor" GridPane.columnIndex="3" GridPane.rowIndex="0" />
  <Label maxHeight="Infinity" maxWidth="Infinity" style=" -fx-border-color:gray; " text="CRN" GridPane.columnIndex="4" GridPane.rowIndex="0" />
  <Label maxHeight="Infinity" maxWidth="Infinity" style=" -fx-border-color:gray; " text="Days" GridPane.columnIndex="5" GridPane.rowIndex="0" />
  <Label maxHeight="Infinity" maxWidth="Infinity" style=" -fx-border-color:gray; " text="Time" GridPane.columnIndex="6" GridPane.rowIndex="0" />
  <Label maxHeight="Infinity" maxWidth="Infinity" style=" -fx-border-color:gray; " text="Subject" GridPane.columnIndex="7" GridPane.rowIndex="0" />
  <Button maxHeight="Infinity" maxWidth="Infinity" mnemonicParsing="false" onAction="#pressBack" style=" -fx-background-color:red; -fx-border-color:black" text="Back..." GridPane.columnIndex="8" GridPane.rowIndex="0" />
   </children>
</GridPane>

Output on system:

Opened database successfully
java.lang.NullPointerException: null
Operation done successfully
Michael Lin
  • 11
  • 1
  • 5
  • 1
    There is no button (or any other control) in the FXML associated with `pressLookUp()`. How is that even getting called? – James_D Mar 27 '18 at 12:40
  • Its a button from a previous stage from a separate FXML. The stage change itself works – Michael Lin Mar 27 '18 at 12:44
  • OK, but is there an element in *that* FXML file with `fx:id=grid`? Otherwise `grid` will only be initialized in the controller that is created when you load the FXML file you posted; it will not be initialized in the controller that is created when you load the other FXML file. (And of course, `pressLookUp()` is called on the controller that is created when you load the other FXML file.) – James_D Mar 27 '18 at 12:46
  • It's basically a really bad idea to use the same class for controllers for two different FXML files; it's too difficult to keep track of which fields are initialized in which controllers, and which fields are still null. I would recommend using different controller classes for each FXML file. Either way, you need to call the method on the correct controller using techniques like the ones in https://stackoverflow.com/q/14187963 – James_D Mar 27 '18 at 12:50
  • The Gridpane in the fxml file has fx:id=grid. The pressLookUp method has to be in the same file because it is suppose to add controls to the next stage. If you put it in another controller, I don't see how that would work. – Michael Lin Mar 27 '18 at 13:01
  • The previous fxml/stage doesn't have anything with fx:id=grid. I just need to know how to make the variable not null. And when I debug the lines with breakpoints, under this it always shows grid as null for some reason – Michael Lin Mar 27 '18 at 13:05
  • But if the two are in different FXML files, then they are in different controllers already. Simply making both controllers the same class doesn't help at all; it just makes it more confusing. – James_D Mar 27 '18 at 13:06
  • I don't understand? The only relevant method that would theoretically go in a separate controller class would be the onAction="#pressBack" function. I don't know how you can load from the database from the 2nd controller – Michael Lin Mar 27 '18 at 13:10
  • pressLookUp is only suppose to add elements to an existing gridpane in a separate stage given in the fxml file. – Michael Lin Mar 27 '18 at 13:12
  • You already have two controllers (because you call `FXMLLoader.load(...)` twice, which you must be doing because you have two FXML files). You have to solve the problem of communicating between them whether you make both of these controllers the same class, or different classes. It will be easier to solve this problem if you make them different classes. I can't show you how to do that, because you haven't posted the relevant code. I recommend you create and post a [MCVE] (or search for similar questions on this site; there are many). – James_D Mar 27 '18 at 13:12
  • Edited the Controller to include the whole java file. When I tried commenting out the other FXMLLoader.load it still didn't solve the problem. – Michael Lin Mar 27 '18 at 13:34

1 Answers1

-1

No clue why this works but it does.

public void pressLookUp(ActionEvent event) throws IOException{
    FXMLLoader loader = new FXMLLoader(getClass().getResource("ClassesToAdd.fxml"));
    Parent userOption = loader.load();
    grid = loader.getRoot();
    Scene classesToAddScene = new Scene(userOption);
    Stage app_stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
    app_stage.setScene(classesToAddScene);
    app_stage.show();
    Connection c = null;
    Statement stmt = null;
    try{
        c = DriverManager.getConnection("jdbc:sqlite:users.db");
        c.setAutoCommit(false);

        System.out.println("Opened database successfully");
        stmt = c.createStatement();

        ResultSet rs = stmt.executeQuery("SELECT * FROM Classes WHERE IDCLASSES= " + "5;");

        int currentIndex = 0;
        int currentRow = 0;
        //assusming all columns are NOT NULL
        while(rs.next()){
            Label currentLabel = new Label();
            currentLabel.setText(rs.getString("CLASSNAME"));
            System.out.println(currentLabel.getText());
            grid.add(currentLabel, 0, 1 );
        }
        loader.setRoot(grid);
        rs.close();
        stmt.close();
        c.close();
    } catch ( Exception e ){
        System.err.println( e.getClass().getName() + ": " + e.getMessage() );
        System.exit(0);
    }
    System.out.println("Operation done successfully");
}
Michael Lin
  • 11
  • 1
  • 5