Referring to a variable from outside static Connection method [duplicate] - java

This question already has answers here:
Non-static variable cannot be referenced from a static context
(15 answers)
Closed 1 year ago.
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 ?

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

Related

SQL connection busy although it's already closed

My SQL connection keeps saying it's busy even though all previous connections are closed.
The error below results. All others are either closed by the exiting of the JFrame or the .close() method. Does anyone see anything wrong with the class? (All other classes work as intended.)
SEVERE: null
org.sqlite.SQLiteException: [SQLITE_BUSY] The database file is locked (database is locked)
at org.sqlite.core.DB.newSQLException(DB.java:941)
at org.sqlite.core.DB.newSQLException(DB.java:953)
at org.sqlite.core.DB.execute(DB.java:854)
at org.sqlite.core.DB.executeUpdate(DB.java:895)
package teacherreviewproject;
//initialise imports
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
public class FeedbackForm extends javax.swing.JFrame {
//init. variables
String WWW;
String EBI;
int rating;
String teacher;
String studentUser;
String ratingraw;
String teacherQuery;
public FeedbackForm(String s) {
initComponents();
getTeachersNames();
this.studentUser = s;
}
private void getTeachersNames(){
//get the connection
Connection con = DBConnection.getConnection();
//set up query string
this.teacherQuery = "SELECT * FROM users WHERE type=2";
try {
//prepare statement
PreparedStatement teacherState = con.prepareStatement(teacherQuery);
//execute query
ResultSet teachResult = teacherState.executeQuery();
//clear previous items to avoid duplicates.
jComboBox_teachers.removeAllItems();
//create counter variable to get different teachers in RS
int i = 0;
//while loop
while(teachResult.next()){
//get username then add it to position i at combobox
String tempOption = teachResult.getString("username");
System.out.println(tempOption);
jComboBox_teachers.addItem(tempOption); //thanks mcalpine
//increment i
i++;
}
} catch (SQLException ex) {
Logger.getLogger(FeedbackForm.class.getName()).log(Level.SEVERE, null, ex);
}
Found the bug! I needed to make a close-if feature on my Connection class.
Here's the code, should anyone want it:
public class DBConnection{
public static Connection con = null;
public static Connection getConnection(){
//initialise connection
try{
//creates valid url to access DB with
String url = "jdbc:sqlite:" + System.getProperty("user.dir") + "/TeacherReviewIA.DB";
if(con == null){
con = (Connection) DriverManager.getConnection(url);
}else{
con.close();
con = (Connection) DriverManager.getConnection(url);
}
//as a debug measure and to show connection given
System.out.println(con);
}
catch(SQLException ex){
JOptionPane.showMessageDialog(null,ex,"WARNING",JOptionPane.WARNING_MESSAGE);
}
//allows code that called method to use connection given
return con;
}
}

call in a method from another class when jbutton is clicked

I intend to write a public method in one class and make the method work when a button is clicked in another JFrame. the class with the method is below:
package Pack.billing;
import Pack.First_Term_Arrears;
import Pack.myKIDS;
import java.sql.*;
import javax.swing.*;
import net.proteanit.sql.DbUtils;
public class Arrears {
Connection conn = null;
PreparedStatement pst = null;
ResultSet rs = null;
public Arrears(){
conn = myKIDS.connectKids();
}
public void display_all_Arrears(){
First_Term_Arrears ta = new First_Term_Arrears();
try{
String sql ="select ID,NAME,SURNAME,CLASS,OLD_ARREARS,FEES,PAID,NEW_ARREARS,DATE,CONTACT from All_Arrears";
pst=conn.prepareStatement(sql);
rs=pst.executeQuery();
ta.ArrearsTable.setModel(DbUtils.resultSetToTableModel(rs));
}catch(Exception e){
JOptionPane.showMessageDialog(null, e);
}
}
and this is the method I want to use:
public void display_all_Arrears(){
First_Term_Arrears ta = new First_Term_Arrears();
try{
String sql ="select ID,NAME,SURNAME,CLASS,OLD_ARREARS,FEES,PAID,NEW_ARREARS,DATE,CONTACT from All_Arrears";
pst=conn.prepareStatement(sql);
rs=pst.executeQuery();
ta.ArrearsTable.setModel(DbUtils.resultSetToTableModel(rs));
}catch(Exception e){
JOptionPane.showMessageDialog(null, e);
}
}
the button on the other jframe which I want it to perform this action is as follows:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
Arrears ar = new Arrears(); ar.first_term_arrears(); // TODO add your handling code here:
}
but nothing works. please what am I doing wrong. thank you
Are you calling the correct method? You say you want to call display_all_Arrears() on the Arrears instance you create in the button event handler, but instead it calls first_term_arrears() which is not an existing method on that class. Try
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
Arrears ar = new Arrears();
ar.display_all_Arrears();
}

Writing data into MySQL table with JavaFX

I have linked up a database to my Java application using the JDBC in Netbeans.
But whenever I try to write something from a TextField to a MySQL table, it doesn't work.
I have a pre-made class to make the database connection.
Here is my database class:
package testswitch;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Enumeration;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* #author Maarten
*/
public class Database {
public final static String DB_DRIVER_URL = "com.mysql.jdbc.Driver";
public final static String DB_DRIVER_PREFIX = "jdbc:mysql://";
private Connection connection = null;
public Database(String dataBaseName, String serverURL, String userName, String passWord) {
try {
// verify that a proper JDBC driver has been installed and linked
if (!selectDriver(DB_DRIVER_URL)) {
return;
}
if (serverURL == null || serverURL.isEmpty()) {
serverURL = "localhost:3306";
}
// establish a connection to a named Database on a specified server
connection = DriverManager.getConnection(DB_DRIVER_PREFIX + serverURL + "/" + dataBaseName, userName, passWord);
} catch (SQLException eSQL) {
logException(eSQL);
}
}
private static boolean selectDriver(String driverName) {
// Selects proper loading of the named driver for Database connections.
// This is relevant if there are multiple drivers installed that match the JDBC type.
try {
Class.forName(driverName);
// Put all non-prefered drivers to the end, such that driver selection hits the first
Enumeration<Driver> drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
Driver d = drivers.nextElement();
if (!d.getClass().getName().equals(driverName)) {
// move the driver to the end of the list
DriverManager.deregisterDriver(d);
DriverManager.registerDriver(d);
}
}
} catch (ClassNotFoundException | SQLException ex) {
logException(ex);
return false;
}
return true;
}
public void executeNonQuery(String query) {
try (Statement statement = connection.createStatement()) {
statement.executeUpdate(query);
} catch (SQLException eSQL) {
logException(eSQL);
}
}
public ResultSet executeQuery(String query) {
Statement statement;
try {
statement = connection.createStatement();
ResultSet result = statement.executeQuery(query);
return result;
} catch (SQLException eSQL) {
logException(eSQL);
}
return null;
}
private static void logException(Exception e) {
System.out.println(e.getClass().getName() + ": " + e.getMessage());
e.printStackTrace();
}
}
And here's my JavaFX controller.
What I want is that when the "handle" button is pressed, that the data filled in the TextField gets inserted into the database.
package testswitch;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import testswitch.Database;
/**
*
* #author Maarten
*/
public class gebruikerToevoegenController {
//TextFields
#FXML
private TextField FXVoornaam, FXTussenvoegsel, FXAchternaam, FXGebruikersnaam;
#FXML
private TextField FXWachtwoord, FXEmail, FXTelefoonnummer;
//Boolean checkbox positie
#FXML
private CheckBox ManagerPosition;
#FXML
private Button gebruikerButton;
public final String DB_NAME = "testDatabase";
public final String DB_SERVER = "localhost:3306";
public final String DB_ACCOUNT = "root";
public final String DB_PASSWORD = "root";
Database database = new Database(DB_NAME, DB_SERVER, DB_ACCOUNT, DB_PASSWORD);
public void handle(ActionEvent event) throws SQLException {
String query = "INSERT INTO testDatabase.Gebruikers (Voornaam) VALUES " + FXVoornaam.getText();
try {
database.executeQuery(query);
} catch (Exception e) {
}
}
}
Thanks in advance
The string in your SQL query doesn't seem to be properly quoted. It's best to use PreparedStatement for this scenario:
public class Database {
public PreparedStatement prepareStatement(String query) throws SQLException {
return connection.prepareStatement(query);
}
...
public void handle(ActionEvent event) throws SQLException {
String query = "INSERT INTO testDatabase.Gebruikers (Voornaam) VALUES (?);";
PreparedStatement statement = database.prepareStatement(query);
try {
statement.setString(1, FXVoornaam.getText());
statement.executeUpdate();
} catch (Exception e) {
// log info somewhere at least until it's properly tested/
// you implement a better way of handling the error
e.printStackTrace(System.err);
}
}
You have to add like this in JavaFx :
String query = "INSERT INTO testDatabase.Gebruikers (Voornaam) VALUES ('{FXVoornaam.getText()}') ";
String query = "INSERT INTO testDatabase.Gebruikers(Voornaam)
VALUES('" + FXVoornaam.getText() + "')";

Constructing and object of a class and calling it's methode in Java

Trying to program that can read a MySql database. Somehow I cannot call the methode connect(). It says:
Error: cannot find symbol"
connect.connnect();
_______^
What I'm trying to do is to have the connnect and getData method in different classes, so I can also use the connect class seperately for other projects.
Main:
import java.sql.*;
public class Main {
public static void main( String argv[]) {
Connect connect = new Connect();
Connect.connect();
GetData getdata = new GetData();
getdata.getdata();
}
}
Connect:
import java.sql.*;
public class Connect{
public Connection con;
public Statement st;
public ResultSet rs;
public connect(){
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/leichtathletik","root","");
st = con.createStatement();
}catch(Exception e1) {
System.out.println("Error: "+e1);
}
}
}
GetData:
import java.sql.*;
public class GetData {
public void getData() {
try {
String query = "select * läufer";
rs = st.esecuteQuery(query);
while (rs.next()) {
String vorname = rs.getString("vorname");
String nachname = rs.getString("nachname");
System.out.println(vorname+" "+nachname);
} // end of while
} catch(Exception e2) {
System.out.println("Error: "+e2);
}
}
}
The "connect"- method on the Connect class needs to have a type.
https://docs.oracle.com/javase/tutorial/java/javaOO/methods.html , can be helpful.
Further more, the youtuber (https://www.youtube.com/channel/UCiczh_Q-rC7VhMV0x6__dBw) can maybe help you get started with java.

java ResultSet and statement issue

i don't understand why my variable state cannot be resolved.
i'm in a java Mysql project.
Here is the Commands class code:
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
public class Commands {
public Commands() throws SQLException{
Connection conn = DbConn.getInstance();
Statement state = conn.createStatement();
}
public String getList(){
System.out.println("Here is a List of our Products:");
// Get list from db
ResultSet result = state.executeQuery("SELECT * FROM products");
ResultSetMetaData resultMeta = result.getMetaData();
// Display the List
System.out.println("List displayed");
return null;
}
}
Here is the DbConn class code:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DbConn {
private static String url = "jdbc:mysql://localhost:3306/myDB";
private static String user = "root";
private static String passwd = "";
private static Connection connect;
// create new instance if not exists
public static Connection getInstance(){
if(connect == null){
try {
connect = DriverManager.getConnection(url, user, passwd);
} catch (SQLException e) {
e.printStackTrace();
}
}
return connect;
}
}
My code is not finished yet, but the message come on this line:
ResultSet result = state.executeQuery("SELECT * FROM products");
My Eclipse editor says this message state cannot be resolved
Any idea?
That is a matter of scope. You define the variable here
public Commands() throws SQLException{
Connection conn = DbConn.getInstance();
Statement state = conn.createStatement();
}
And that is the only place the variable is visible - in the constructor. Define it in the class and initialize it in the constructor:
private Connection conn = null;
private Statement state = null;
public Commands() throws SQLException{
conn = DbConn.getInstance();
state = conn.createStatement();
}
Declare "State" outside of that constructor.
Connection conn = null;
Statement state = null;
public Commands() throws SQLException{
conn = DbConn.getInstance();
state = conn.createStatement();
}

Categories