I am working on a dictionary project in Java on Netbeans. I have two classes here:
"dictionary.java" where the main method is
"DictionaryGuiController.java" where GUI code is constructed with javafx platform
I connected the database and project with JDBC driver and using these codes in main method:
Connection conn = null;
Statement statement = null;
ResultSet rs = null;
try {
conn = DriverManager.getConnection("jdbc:mysql://localhost/world", "root", "root");
statement = conn.createStatement();
rs = statement.executeQuery("SELECT * FROM country");
while (rs.next()) {
System.out.println(rs.getString("code") + ":" + rs.getString("name"));
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
}
Here I created a connection object as conn to create statements and executing the SQL query.
I want to retrieve data from a sample database in Mysql called "world". With this code I am able to retrieve data in a small project that has only one class and main method. But in this project when I run the program I see the GUI interface but I can not see any results in the console, it keeps saying:
Executing C:\Users\Bar\Documents\NetBeansProjects\Dictionary\dist\run414351490\Dictionary.jar using platform C:\Program Files\Java\jdk1.7.0_45\jre/bin/java
and program never stops until program exits.
Here is the complete code of the classes:
Dictionary.java:
package dictionary;
import java.io.IOException;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import java.sql.*;
public class Dictionary extends Application {
#Override
public void start(Stage stage) throws IOException {
Parent root = FXMLLoader.load(getClass().getResource("DictionaryGui.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
/**
* The main() method is ignored in correctly deployed JavaFX application.
* main() serves only as fallback in case the application can not be
* launched through deployment artifacts, e.g., in IDEs with limited FX
* support. NetBeans ignores main().
*
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
Connection conn = null;
Statement statement = null;
ResultSet rs = null;
try {
conn = DriverManager.getConnection("jdbc:mysql://localhost/world", "root", "root");
statement = conn.createStatement();
rs = statement.executeQuery("SELECT * FROM country");
while (rs.next()) {
System.out.println(rs.getString("code") + ":" + rs.getString("name"));
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
}
}
}
DictionaryGuiController.java:
package dictionary;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
public class DictionaryGuiController implements Initializable {
#FXML
private TextField searchfield;
#FXML
private Button buttonsearch;
#FXML
private TextArea listview;
/**
* Initializes the controller class.
*/
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
#FXML
private void handleButtonAction(ActionEvent event) {
listview.setText(searchfield.getText());
}
}
What could be the problem? Any help would be appreciated.
Two quick things that it could be. First, is your instance of MySQL already running? Secondly, I tend to do all my database connection stuff outside the main method. So I will have a method in the controller class called initDB() or connectToDB() and I put the code in there.
The convention I've seen for the main() method in JavaFX programs is that launch() is the only method called. I could be wrong, but check those two things and see if you have any luck.
Related
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
When I run my program I got compilation error like this:
com/mycompany/sistemcatatpoinkeaktifan/KemahasiswaanController.java:[65,20] cannot find symbol
symbol: method next()
location: variable rs of type javax.xml.transform.Result
com/mycompany/sistemcatatpoinkeaktifan/KemahasiswaanController.java:[66,51] cannot find symbol
symbol: method getInt(java.lang.String)
location: variable rs of type javax.xml.transform.Result
com/mycompany/sistemcatatpoinkeaktifan/KemahasiswaanController.java:[66,71] cannot find symbol
symbol: method getString(java.lang.String)
location: variable rs of type javax.xml.transform.Result
com/mycompany/sistemcatatpoinkeaktifan/KemahasiswaanController.java:[66,102] cannot find symbol
symbol: method getInt(java.lang.String)
location: variable rs of type javax.xml.transform.Result
4 errors
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.mycompany.sistemcatatpoinkeaktifan;
import java.net.URL;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ResourceBundle;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Menu;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javax.xml.transform.Result;
public class KemahasiswaanController implements Initializable {
#FXML
private TextField inputKegiatan;
#FXML
private Button buttonCreate;
#FXML
private Button buttonUpdate;
#FXML
private Button buttonDelete;
#FXML
private TableView<Menu> tvMenu;
#FXML
private TableColumn<Menu, Integer> colnomor;
#FXML
private TableColumn<Menu, String> coljenisKegiatan;
#FXML
private TableColumn<Menu, Integer> colpoin;
public Connection getConnection(){
try{
Class.forName("org.sqlite.JDBC");
Connection conn = DriverManager.getConnection("jdbc:sqlite:E:\\Documents\\Sem 5\\RPL\\punya maria\\SistemCatatPoinKeaktifanMaria\\db\\database.db");
return conn;
} catch (Exception e){
System.out.println(e.getMessage());
return null;
}
}
public ObservableList<Menu> getMenuList(){
ObservableList<Menu> menuList = FXCollection.observableArrayList();
Connection conn = getConnection();
String query = "SELECT JenisKegiatan, Poin FROM KemahasiswaanNatasha";
Statement st;
Result rs;
ObservableList<Menu> MenuList = null;
try{
st = conn.createStatement();
rs = (Result) st.executeQuery(query);
Menu KegiatanKemahasiswaan;
while(rs.next()){
KegiatanKemahasiswaan = new Menu(rs.getInt("nomor"), rs.getString("jenisKegiatan"), rs.getInt("poin"));
MenuList.add(KegiatanKemahasiswaan);
}
}catch(SQLException ex){
ex.printStackTrace();
}
return MenuList;
}
public void ShowMenu(){
ObservableList<Menu> list = getMenuList();
colnomor.setCellValueFactory(new PropertyValueFactory<Menu, Integer>("nomor"));
coljenisKegiatan.setCellValueFactory(new PropertyValueFactory<Menu, String>("Kegiatan"));
colpoin.setCellValueFactory(new PropertyValueFactory<Menu, Integer>("Poin"));
tvMenu.setItems(list);
}
#Override
public void initialize(URL url, ResourceBundle rb) {
ShowMenu();
}
private static class FXCollection {
private static ObservableList<Menu> observableArrayList() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public FXCollection() {
}
}
}
The problem is that you have declared rs to be of the type javax.xml.transform.Result instead of java.sql.ResultSet, and the methods you're trying to call (like next(), getInt(String) and getString(String) do not exist in javax.xml.transform.Result.
The line
Result rs;
should be
ResultSet rs;
and
rs = (Result) st.executeQuery(query);
should be
rs = st.executeQuery(query);
In addition, your code could be further improved by learning about try-with-resources, as you're currently leaking the connection, statement and result set.
how to solve this problem and what is wrong in this code?
i know that the question has been asked before but i cant solve the problem
private void cb_categoriesPopupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent evt) {
cb_categories.removeAllItems();
try {
String sql_c = "SELECT * FROM inventory.categories";
cc.pst = cc.c.prepareStatement(sql_c);
cc.rs = cc.pst.executeQuery();
while (cc.rs.next()) {
String c_name = cc.rs.getString("CategoryName");
cb_categories.addItem(c_name);
}
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
} finally {
try {
cc.rs.close();
cc.pst.close();
} catch (Exception e) {
}
}
}
Your ResultSet and PreparedStatement are not declared in method scope, so I have to assume that you've declared them elsewhere.
That's a big mistake.
You should declare the Statement and ResultSet in method scope.
You make an attempt to close your resources, but you should wrap them in individual try/catch blocks. You cannot risk one being closed and not the other.
There are other things I'd criticize about your code (e.g. SELECT *, mingling UI and database code together in a single class), but that's enough to start.
Start with an interface:
package persistence;
import java.util.List;
/**
* Created by Michael
* Creation date 8/20/2017.
* #link https://stackoverflow.com/questions/45787151/com-mysql-jdbc-exception-jdbc4-mysqlnontransientconnectionexception-no-operatio/45787321?noredirect=1#comment78532554_45787321
*/
public interface CategoryDao {
List<String> findAllCategories();
}
Then write a concrete implementation:
package database;
import database.util.DatabaseUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.sql.DataSource;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Michael
* Creation date 8/20/2017.
* #link https://stackoverflow.com/questions/45787151/com-mysql-jdbc-exception-jdbc4-mysqlnontransientconnectionexception-no-operatio/45787321?noredirect=1#comment78532554_45787321
*/
public class CategoryDaoImpl implements CategoryDao {
private static final Log LOGGER = LogFactory.getLog(CategoryDaoImpl.class);
private static String SELECT_CATEGORIES = "SELECT CategoryName from inventory.Categories ";
private DataSource dataSource;
public CategoryDaoImpl(DataSource dataSource) {
this.dataSource = dataSource;
}
#Override
public List<String> findAllCategories() {
List<String> categories = new ArrayList<>();
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = this.dataSource.getConnection().prepareStatement(SELECT_CATEGORIES);
rs = ps.executeQuery();
while (rs.next()) {
categories.add(rs.getString("CategoryName"));
}
} catch (SQLException e) {
LOGGER.error(String.format("Exception caught while selecting all category names"), e);
} finally {
DatabaseUtils.close(rs);
DatabaseUtils.close(ps);
}
return categories;
}
}
This is something that you can test with JUnit off to the side. Get it running perfectly, then give a reference to your UI code. It'll keep the UI and database code separate. You can use this DAO in any application without worrying about Swing or web UI.
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() + "')";
package myproj;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import javax.swing.table.DefaultTableModel;
import myproj.util.DBUtil;
/**
*
* #author PEARL
*/
public class DATAENTRY extends javax.swing.JFrame {
/**
* Creates new form DATAENTRY
*/
public DATAENTRY() {
try {
initComponents();
DBUtil util = new DBUtil();
Connection con = util.getConnection();
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("select * from bk_det inner join bk_rep on bk_det.rm_id = bk_rep.rm_id inner join bk_sec on bk_rep.rm_id = bk_sec.rm_id inner join mut_det on bk_sec.rm_id = mut_det.rm_id inner join rm_det on mut_det.rm_id = rm_det.rm_id inner join soil_det on rm_det.rm_id = soil_det.rm_id");
ResultSetMetaData rsmetadata = rs.getMetaData();
int columns = rsmetadata.getColumnCount();
DefaultTableModel dtm = new DefaultTableModel();
Vector columns_name = new Vector();
Vector data_rows = new Vector();
for(int i=1; i< columns; i++){
columns_name.addElement(rsmetadata.getColumnName(i));
}
dtm.setColumnIdentifiers(columns_name);
while(rs.next()){
data_rows = new Vector();
for(int j=1; j< columns; j++){
data_rows.addElement(rs.getString(j));
}
dtm.addRow(data_rows);
}
MyTable.setModel(dtm);
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, ex.getMessage());
Logger.getLogger(Demo.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void main(String arg[]){
}
}
i want to display the records from my sql database to my jtable in netbeans gui but am able to display the compile and running the windows form successfully but it doesnot display the respected form please help
This is because you need to call DATAENTRY() in the main class
Your main method is empty, so it won't do anything.
public static void main(String arg[]){
}
Did you know that your main method is completely empty? Everything in your program happens from main. You would want to instantiate your DATAENTRY object from there.
DATAENTRY da = new DATAENTRY();
It may also be the case that other things break as well; be wary and conscious of any stack traces.
There's nothing in your main method. Java starts running code from the main method.
Add this
public static void main(String arg[]){
DATAENTRY de = new DATAENTRY() ;
de.pack();
de.setVisible(true)
}
Also class name DATAENTRY and all the stuff which you've done in constructor is not a proper standard. You should follow java code standards. Google it.
Class name can be like DataEntryFrame
call initialize component after constructing frame like deFrame.intilizeComponents()
put separate method for updating table content like fillupTable()
finally call fillupTable method with an event or in main method.