0

I am new to java and started doing a javaFX project. In this project, I receive a variable from a previous frame, and use it to execute an SQL query in order to render the table based on that particular variable. Here is my code:

package financials;

import java.net.URL;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ResourceBundle;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;

import javax.swing.JOptionPane;

/**
 * FXML Controller class
 *
 * @author param
 */
public class theControl implements Initializable {
    @FXML
    private Label test;

    /**
     * Initializes the controller class.
     */
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        Statement st;
        Connection con = null;    
    }

    /**
     *
     * @param name
     */
    public void previous(String name) {
        System.out.println(name);
    }
       
    public static Connection ConnectDB() {
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            Connection con = DriverManager.getConnection("jdbc:mysql://localhost/database", "root", "Password");
            
            return con;
        } catch(Exception ae) {
            JOptionPane.showMessageDialog(null, ae);

            return null;
        }
    }

    public static ObservableList<RenderNow> getListAccount() {
        Connection con = ConnectDB();
        ObservableList<RenderNow> list = FXCollections.observableArrayList();
        try {
            PreparedStatement pst = con.prepareStatement("SELECT * FROM lines WHERE Code=? ");
            pst.setString(1, name); //This is where I am having trouble
            ResultSet rs = pst.executeQuery();
            while (rs.next()) {
                list.add(new SBRender(rs.getString("Account1"), rs.getString("Account2"), rs.getString("Account3"), rs.getString("Account4"), rs.getString("Account5")));
            }         
        } catch(Exception ae) {
            JOptionPane.showMessageDialog(null, ae);

            return null;                          
        }

        return list;  
    }
}

The problem is that the variable name is not being recognized in the pst.setString line. The error I am getting is that variable 'name' is not found. I tried a different approach where I used name to set the text of Label test, and then later tried to get the variable in the public static Connection ConnectDB() method.

Something like:

public class theControl implements Initializable {
    @FXML
    private Label test;

    /**
     * Initializes the controller class.
     */
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        Statement st;
        Connection con = null;
    }

    /**
     *
     * @param name
     */
    public void previous(String name) {
        System.out.println(name);
        test.setText(name); //Where i set the text of label 'text'
    }
   
    public static Connection ConnectDB() {
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            Connection con = DriverManager.getConnection("jdbc:mysql://localhost/database", "root", "Password");
            
            return con;
        } catch(Exception ae) {
            JOptionPane.showMessageDialog(null, ae);

            return null;
        }
    }

    public static ObservableList<RenderNow> getListAccount() {
        String name2 = test.getText(); //Where I try and get the text from label 'text'
        Connection con = ConnectDB();
        ObservableList<RenderNow> list = FXCollections.observableArrayList();
        try {
            PreparedStatement pst = con.prepareStatement("SELECT * FROM lines WHERE Code=? ");
            pst.setString(1, name2); //This is where I am having trouble
            ResultSet rs = pst.executeQuery();
            while (rs.next()) {
                list.add(new SBRender(rs.getString("Account1"), rs.getString("Account2"), rs.getString("Account3"), rs.getString("Account4"), rs.getString("Account5")));
            }
        } catch(Exception ae) {
            JOptionPane.showMessageDialog(null, ae);

            return null;                           
        }

        return list;  
    }
}

However, this attempt returns an error non-static variable test cannot be referenced from a static context. My understanding is that since the label test is not static, static Connection is unable to get the text. Is there any work around for this ?

0009laH
  • 1,960
  • 13
  • 27
theboss12k
  • 125
  • 8
  • 1
    for the future: the most direct way to find a solution for language issues (both compile- and runtime) is to type the error message into your favorite search engine (that's how I found the duplicate, there are many more, even here on stackoverflow :) and work through the results . – kleopatra Jul 29 '21 at 09:56
  • @kleopatra, Thank you so much for your feedback. I will try and avoid static methods in the future. But, to my limited knowledge, I felt that `Connection` can only be `static`. Is there any other way ? And with regards to naming conventions, most of my naming is done by my IDE. However, I will try and follow java naming conventions next time :) – theboss12k Jul 29 '21 at 16:30

1 Answers1

1

In your first case, the variable was not set. It's only available on the method where you have your print method.

In the second case, you are not using the object. The test variable is in one object, so not accessible by static method which are not depending of object.

I suggest you to ad new parameter to your static method, and use like this:

// create new static method which require the name in parameters
public static ObservableList<RenderNow> getListAccountWithName(String name) {
    Connection con = ConnectDB(); // get DB thanks to static method
    ObservableList<RenderNow> list = FXCollections.observableArrayList();
    try {
        PreparedStatement pst = con.prepareStatement("SELECT * FROM lines WHERE Code = '?'");
        pst.setString(1, name); // now you can use name value
        ResultSet rs = pst.executeQuery();
        while (rs.next()) {
            list.add(new SBRender(rs.getString("Account1"), rs.getString("Account2"), rs.getString("Account3"), rs.getString("Account4"), rs.getString("Account5")));
        }
    } catch(Exception ae) {
        JOptionPane.showMessageDialog(null, ae);
        return null;                           
    }

    return list;  
}

And now, you can call it from the object like:

ObservableList<RenderNow> accounts = getListAccountWithName(test.getText());
// now what you have what you are looking for
Elikill58
  • 4,050
  • 24
  • 23
  • 45
  • Thank you so much for helping me ! I am really new to Java, and javaFX in particular, so could you please tell me if I should replace `getListAccount()` with `getListAccountWithName(String name)` and even if I do, how can I insert the variable into the `preparedStatement`. Once again, thank you so much for helping me out ! – theboss12k Jul 29 '21 at 16:27
  • 1
    Such as the method `getListAccountWithName` will have a variable named `name`, you can use it in the setString method from preparedStatement. I will add complete code in my answer. Just, when the getListAccount method was called ? – Elikill58 Jul 29 '21 at 16:50
  • Thank you so much for your quick response. The `getListAccount` is called as soon as the page, that is the `theControl` is loaded. There is no action performed by the user to call `getListAccount` – theboss12k Jul 29 '21 at 16:53
  • 1
    No problem x) I just edit the message. Does that help you ? – Elikill58 Jul 29 '21 at 16:58
  • Your answer really did help a lot, so thank you for that. But, the issue that I am facing is that if I add `String name` to the `getListAccountWithName` method, then when I use ` listm=theControl.getAccountWithName();` in order to retrieve the list and display it in a table (in a different file), then I am getting an error `method getSBAccount in class ConnectToSBController cannot be applied to given types; required: String found: no arguments reason: actual and formal argument lists differ in length` . I am really sorry if it is super confusing ! – theboss12k Jul 29 '21 at 17:06
  • Yes, you are calling the method but without any arguments. You need to use the method with the name, such as I show at the end of my answer – Elikill58 Jul 29 '21 at 17:11
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/235425/discussion-between-elikill58-and-theboss12k). – Elikill58 Jul 29 '21 at 17:17
  • So finally, such as I answer to your question, can you accept it ? – Elikill58 Jul 29 '21 at 18:58