I've been trying to load a TableView with data queried from a database, but can't seem to get it to work.
This is my first attempt at trying to populate a TableView with database query items – in case my code seems mungled and far from good.
The FXML was done via JavaFX SceneBuilder.
This is the database query class:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.TableView;
public class StudentInfo {
static String JDBC_DRIVER = "org.h2.Driver";
static String DB_URL = "jdbc:h2:file:C:/WAKILI/WAKILIdb";
// Database credentials
static final String USER = "sa";
static final String PASS = "";
public static Connection conn = null;
#FXML
private TableView<StudentInfo> lovelyStudents;
private ObservableList data;
// Public static ObservableList<COA> getAllCOA(){
public void getAllstudentInfo() {
Statement st = null;
ResultSet rs;
String driver = "org.h2.Driver";
try {
Class.forName(driver);
conn = DriverManager.getConnection(DB_URL, USER, PASS);
st = conn.createStatement();
String recordQuery = ("SELECT id, KIWI FROM KIWI");
rs = st.executeQuery(recordQuery);
while (rs.next()) {
ObservableList row = FXCollections.observableArrayList();
for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) {
row.add(rs.getString(i));
System.out.println(row);
}
data.add(row);
}
lovelyStudents.setItems(data);
} catch (ClassNotFoundException | SQLException ex) {
// CATCH SOMETHING
}
}
}
This is the FXML script generated via JavaFX scene builder:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="700.0" xmlns:fx="http://javafx.com/fxml" fx:controller="wakiliproject.SampleController">
<children>
<TableView prefHeight="400.0" prefWidth="700.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columns>
<TableColumn prefWidth="75.0" text="Column X" />
</columns>
</TableView>
</children>
</AnchorPane>
Here is the best solution for the filling data to the tableView From the database.
import java.sql.Connection;
import java.sql.ResultSet;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.TableView;
import javafx.stage.Stage;
import javafx.util.Callback;
/**
*
* #author Narayan
*/
public class DynamicTable extends Application{
//TABLE VIEW AND DATA
private ObservableList<ObservableList> data;
private TableView tableview;
//MAIN EXECUTOR
public static void main(String[] args) {
launch(args);
}
//CONNECTION DATABASE
public void buildData(){
Connection c ;
data = FXCollections.observableArrayList();
try{
c = DBConnect.connect();
//SQL FOR SELECTING ALL OF CUSTOMER
String SQL = "SELECT * from CUSTOMer";
//ResultSet
ResultSet rs = c.createStatement().executeQuery(SQL);
/**********************************
* TABLE COLUMN ADDED DYNAMICALLY *
**********************************/
for(int i=0 ; i<rs.getMetaData().getColumnCount(); i++){
//We are using non property style for making dynamic table
final int j = i;
TableColumn col = new TableColumn(rs.getMetaData().getColumnName(i+1));
col.setCellValueFactory(new Callback<CellDataFeatures<ObservableList,String>,ObservableValue<String>>(){
public ObservableValue<String> call(CellDataFeatures<ObservableList, String> param) {
return new SimpleStringProperty(param.getValue().get(j).toString());
}
});
tableview.getColumns().addAll(col);
System.out.println("Column ["+i+"] ");
}
/********************************
* Data added to ObservableList *
********************************/
while(rs.next()){
//Iterate Row
ObservableList<String> row = FXCollections.observableArrayList();
for(int i=1 ; i<=rs.getMetaData().getColumnCount(); i++){
//Iterate Column
row.add(rs.getString(i));
}
System.out.println("Row [1] added "+row );
data.add(row);
}
//FINALLY ADDED TO TableView
tableview.setItems(data);
}catch(Exception e){
e.printStackTrace();
System.out.println("Error on Building Data");
}
}
#Override
public void start(Stage stage) throws Exception {
//TableView
tableview = new TableView();
buildData();
//Main Scene
Scene scene = new Scene(tableview);
stage.setScene(scene);
stage.show();
}
}
Here is the Reference
Thanks..
If Database contains different types of data, not only String, then column type assigning is better to make dynamic:
package sample;
import javafx.application.Application;
import javafx.beans.property.*;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Stage;
import java.sql.*;
import java.util.ArrayList;
import java.util.TimeZone;
//Author: Yerbol
//SQL database "sqlbase_schema" contains a Table "sqlbase_table" with 3 columns: "id" (Integer(INT(11))), "name" (String(VARCHAR(45))), "married" (Boolean(TINYINT(1)));
public class Main extends Application {
private TableView<Person> tableView = new TableView<>();
#Override
public void start(Stage primaryStage) throws SQLException, ClassNotFoundException {
//Show window
buildData();
Parent root = tableView;
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
}
public void buildData() throws ClassNotFoundException, SQLException {
Connection dbConnection;
//SQL Database connection params
String dbHost = "localhost";
String dbPort = "3306";
String dbUser = "root";
String dbPassword = "12345";
String dbName = "sqlbase_schema";
String dbTableName = "sqlbase_table";
String select = "SELECT * FROM " + dbTableName;
String connectionString = "jdbc:mysql://" + dbHost + ":" + dbPort +"/" + dbName+"?useLegacyDatetimeCode=false&&serverTimezone=" + TimeZone.getDefault().getID();
Class.forName("com.mysql.cj.jdbc.Driver");
//Connecting to Database
dbConnection = DriverManager.getConnection(connectionString, dbUser, dbPassword);
//Extracting data from Databasee
ResultSet resultSet = null;
try {
PreparedStatement preparedStatement = dbConnection.prepareStatement(select);
resultSet = preparedStatement.executeQuery();
} catch (SQLException e) {
e.printStackTrace();
}
ObservableList dbData = FXCollections.observableArrayList(dataBaseArrayList(resultSet));
//Giving readable names to columns
for(int i=0 ; i<resultSet.getMetaData().getColumnCount(); i++) {
TableColumn column = new TableColumn<>();
switch (resultSet.getMetaData().getColumnName(i+1)) {
case "id":
column.setText("ID #");
break;
case "name":
column.setText("Person Name");
break;
case "married":
column.setText("Marital Status");
break;
default: column.setText(resultSet.getMetaData().getColumnName(i+1)); //if column name in SQL Database is not found, then TableView column receive SQL Database current column name (not readable)
break;
}
column.setCellValueFactory(new PropertyValueFactory<>(resultSet.getMetaData().getColumnName(i+1))); //Setting cell property value to correct variable from Person class.
tableView.getColumns().add(column);
}
//Filling up tableView with data
tableView.setItems(dbData);
}
public class Person {
IntegerProperty id = new SimpleIntegerProperty(); //variable names should be exactly as column names in SQL Database Table. In case if you want to use <int> type instead of <IntegerProperty>, then you need to use getter/setter procedures instead of xxxProperty() below
StringProperty name = new SimpleStringProperty();
BooleanProperty married = new SimpleBooleanProperty();
public IntegerProperty idProperty() { //name should be exactly like this [IntegerProperty variable name (id) + (Property) = idProperty] (case sensitive)
return id;
}
public StringProperty nameProperty() {
return name;
}
public BooleanProperty marriedProperty() {
return married;
}
public Person(int idValue, String nameValue, boolean marriedValue) {
id.set(idValue);
name.set(nameValue);
married.set(marriedValue);
}
Person(){}
}
//extracting data from ResulSet to ArrayList
private ArrayList dataBaseArrayList(ResultSet resultSet) throws SQLException {
ArrayList<Person> data = new ArrayList<>();
while (resultSet.next()) {
Person person = new Person();
person.id.set(resultSet.getInt("id"));
person.name.set(resultSet.getString("name"));
person.married.set(resultSet.getBoolean("married"));
data.add(person);
}
return data;
}
public static void main(String[] args) {
launch(args);
}
}
In this example SQL database "sqlbase_schema" contains a Table "sqlbase_table" with 3 columns: "id" (Integer(INT(11))), "name" (String(VARCHAR(45))), "married (Boolean(TINYINT(1)));
public TableView queryToTable(String sql) {
TableView result = new TableView();
ObservableList data = FXCollections.observableArrayList();
jdbcTemplate.query(sql, (rs)->{
for(int i=0 ; i<rs.getMetaData().getColumnCount(); i++){
final int j = i;
TableColumn col = new TableColumn(rs.getMetaData().getColumnName(i+1));
col.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<ObservableList,String>,ObservableValue<String>>(){
public ObservableValue<String> call(TableColumn.CellDataFeatures<ObservableList, String> param) {
return new SimpleStringProperty(param.getValue().get(j).toString());
}
});
result.getColumns().addAll(col);
}
while(rs.next()){
ObservableList<String> row = FXCollections.observableArrayList();
for(int i=1 ; i<=rs.getMetaData().getColumnCount(); i++)
row.add(rs.getString(i));
data.add(row);
}
return null;
});
return result;
}
Related
I am trying to pass the login string from 1 class to another. Here is the class that it is entered:
package myFlight;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Connection;
import javafx.application.Application;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.stage.Window;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.layout.BorderPane;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.event.ActionEvent;
public class Login extends myFlightMain{
#FXML
private TextField UserPassword;
#FXML
public Label loginLbl;
public String enteredPassword;
//When Login is pressed gets the entered email and password, Sends them to check Login, also authenticates if admin.
public void Login(ActionEvent event) {
String enteredEmail = UserEmail.getText();
String enteredPassword = UserPassword.getText();
VerifyLogin(enteredEmail, enteredPassword);
BookFlightsController callClass = new BookFlightsController();
callClass.usersEmail(enteredEmail);
UserPassword.setText("");
}
//Changes to register scene using Register button on Login screen
public void loginRegisterButton(ActionEvent event) {
try {
Parent root = FXMLLoader.load(getClass().getResource("Register.fxml"));
Stage stage = (Stage)((Node)event.getSource()).getScene().getWindow();
Scene scene = new Scene(root, 600, 400);
stage.setScene(scene);
stage.show();
} catch (Exception e) {
}
}
public void forgotPasswordButton(ActionEvent event) {
try {
Parent root = FXMLLoader.load(getClass().getResource("ForgotPassword.fxml"));
Stage stage = (Stage)((Node)event.getSource()).getScene().getWindow();
Scene scene = new Scene(root, 600, 400);
stage.setScene(scene);
stage.show();
} catch (Exception e) {
}
}
/*public void ReturnToLogin(ActionEvent event) {
try {
Parent root = FXMLLoader.load(getClass().getResource("/myFlight/Views/Login.fxml"));
Stage stage = (Stage)((Node)event.getSource()).getScene().getWindow();
Scene scene = new Scene(root, 600, 400);
stage.setScene(scene);
stage.show();
} catch (Exception f) {
}
}*/
public void VerifyLogin(String enteredEmail, String enteredPassword) {
try {
Connection conn = DBConnector.getConnection();
//queries the database and gets the password from the Login table
PreparedStatement CheckLogin = (PreparedStatement) conn
.prepareStatement("SELECT Password FROM Login WHERE CustomerEmail ='" + enteredEmail + "' ");
//queries the database and checks the admin table for a yes or no
PreparedStatement adminCheck = (PreparedStatement) conn
.prepareStatement("SELECT Admin FROM Login WHERE CustomerEmail ='" + enteredEmail + "' ");
ResultSet rs = CheckLogin.executeQuery();
ResultSet res = adminCheck.executeQuery();
if (res.next() && rs.next()) {
String admin = res.getString("Admin");
String psw = rs.getString("Password");
//if username and password match and admin is set to yes, sends to Admin UI
if (admin.equals("Yes") && psw.equals(enteredPassword)) {
AdminLoginComplete();
}
//if username and password match and admin is set to no, it sends user to Customer UI
else if (psw.equals(enteredPassword) && admin.equals("No")) {
LoginComplete();
}
}
} catch (Exception e) {
}
}
//Loads Admin UI
public void AdminLoginComplete() {
try {
Stage login = new Stage();
Parent root1 = FXMLLoader.load(getClass().getResource("Admin.fxml"));
Scene returnToLogin = new Scene(root1, 800, 600);
returnToLogin.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
login.setScene(returnToLogin);
login.show();
} catch (Exception f) {
}
}
//Loads Customer UI
public void LoginComplete() {
try {
Stage login = new Stage();
Parent root = FXMLLoader.load(getClass().getResource("CustomerInterface.fxml"));
Scene returnToLogin = new Scene(root, 800, 600);
returnToLogin.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
login.setScene(returnToLogin);
login.show();
} catch (Exception f) {
}
}
//Sets the Login label after register is complete
public void registerComplete() {
loginLbl.setText("Registration Successful");
}
}
Here is the class I am trying to pass it to:
package myFlight;
import java.awt.Label;
import java.net.URL;
import java.util.LinkedList;
import java.util.List;
import java.util.ResourceBundle;
import java.util.logging.Logger;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.*;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
public class BookFlightsController implements Initializable {
#FXML
private TableView<flightTable> table;
#FXML
private TableColumn<flightTable, Integer> colFlightID;
#FXML
private TableColumn<flightTable, String> colFromCity;
#FXML
private TableColumn<flightTable, String> colToCity;
#FXML
private TableColumn<flightTable, String> colFlightDate;
#FXML
private TableColumn<flightTable, String> colFlightTime;
#FXML
private TableColumn<flightTable, Integer> colSeats;
private String userEmail;
private String enteredUserEmail;
public List<flightTable> getAllFlightInfo() {
List ll = new LinkedList();
try {
Connection conn = DBConnector.getConnection();
PreparedStatement pst = conn.prepareStatement("select * from Flight");
ResultSet rs = pst.executeQuery();
while (rs.next()) {
int flightID = rs.getInt("FlightID");
String fromCity = rs.getString("FromCity");
String toCity = rs.getString("ToCity");
String flightDate = rs.getString("FlightDate");
String flightTime = rs.getString("FlightTime");
int numberOfSeats = rs.getInt("numberOfSeatsTotal");
PreparedStatement ps = conn.prepareStatement("select " +flightID + " from BookedFlights");
ResultSet rst = ps.executeQuery();
int numberOfPassengers = 0;
if (rst.next()) {
++numberOfPassengers;
}
int seatsLeft = numberOfSeats - numberOfPassengers;
ll.add(new flightTable(flightID, fromCity, toCity, flightDate, flightTime, seatsLeft));
}
} catch (Exception e) {
}
return ll;
}
#Override
public void initialize(URL location, ResourceBundle resources) {
}
public void handle(ActionEvent event) {
colFlightID.setCellValueFactory(new PropertyValueFactory<flightTable, Integer>("flightID"));
colFromCity.setCellValueFactory(new PropertyValueFactory<flightTable, String>("fromCity"));
colToCity.setCellValueFactory(new PropertyValueFactory<flightTable, String>("toCity"));
colFlightDate.setCellValueFactory(new PropertyValueFactory<flightTable, String>("flightDate"));
colFlightTime.setCellValueFactory(new PropertyValueFactory<flightTable, String>("flightTime"));
colSeats.setCellValueFactory(new PropertyValueFactory<flightTable, Integer>("seatsLeft"));
table.getItems().setAll(getAllFlightInfo());
}
public void bookAFlight(ActionEvent event) {
flightTable selectedFlight = table.getSelectionModel().getSelectedItem();
int selectedFlightId = selectedFlight.getFlightID();
String selectedFromCity = selectedFlight.getFromCity();
String selectedToCity = selectedFlight.getToCity();
String selectedFlightDate = selectedFlight.getFlightDate();
String selectedFlightTime = selectedFlight.getFlightTime();
}
}
I also have this getter and setter setup if it would help:
package myFlight;
public class Loginset {
private String userEmail;
public Loginset() {
}
public Loginset(String userEmail){
this.userEmail = userEmail;
}
public String getUserEmail() {
return userEmail;
}
public void setUserEmail(String userEmail) {
this.userEmail = userEmail;
}
}
I have tried various ways of passing it and have not been able to get it. I need to use the email in the
public void bookAFlight(ActionEvent event) {
flightTable selectedFlight = table.getSelectionModel().getSelectedItem();
int selectedFlightId = selectedFlight.getFlightID();
String selectedFromCity = selectedFlight.getFromCity();
String selectedToCity = selectedFlight.getToCity();
String selectedFlightDate = selectedFlight.getFlightDate();
String selectedFlightTime = selectedFlight.getFlightTime();
}
You can create an observer that is a behavioral design pattern. It specifies communication between objects: observable and observers. An observable is an object which notifies observers about the changes in its state.
For example, you can create an interface to define this behavior design:
public interface OnChangeLoginStatus {
void onChangeLoginStatus(String userEmail);
}
In your Login class
import myFlight.OnChangeLoginStatus;
private static ArrayList<OnChangeLoginStatus> listeners = new ArrayList<>();
public static void addOnChangeLoginStatusListener(OnChangeLoginStatus newListener) {
listeners.add(newListener);
}
private static void notifyAllListeners(String userEmail) {
for (OnChangeLoginStatus listener : listeners) {
listener.onChangeLoginStatus(userEmail);
}
}
public void VerifyLogin(String enteredEmail, String enteredPassword) { ...
try{...
notifyAllListeners(enteredEmail); // allways when you call this method, all listeners will be informed about entered email or about whatever you want . . .
}...
}
in your BookFlightsController class
import myFlight.Login;
import myFlight.OnChangeLoginStatus;
private static String userEmailFromLoginClass;
public void initialize() {
Login.addOnChangeLoginStatusListener(new OnChangeLoginStatus() {
#Override
public void onChangeLoginStatus(String userEmail) {
userEmailFromLoginClass = userEmail;
}
});
}
And an another approach and option for Login.addOnChangeLoginStatusListener method in your BookFlightsController class, you can use a lambda expression to improve code readability if you want . . .
Login.addOnChangeLoginStatusListener(
userEmail -> userEmailFromLoginClass = userEmail
);
Since I am on mobile I found it difficult to look into your code. But from what ever I understood, dependency injection is what is required.
Inject the instance to whose method you want to pass on the login credentials in the class from where you want to pass on the credentials.
Let me clarify the question. So I decided to create a TreeView just like in PhpMyAdmin (xampp) that shows all Databases. I successfully managed to get the Databases and Tables in the Treeview, but not the content of the Tables in the TableView. So basically the first thing I want to do is, that if I click on a Table, the column headers should show up in the Table next to the Treeview. I managed to write some code, but it does not do what it is supposed to do. Please help me I am trying to learn this programming language (JavaFX).
This is the Controller class
package sample;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.control.cell.PropertyValueFactory;
import java.net.URL;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ResourceBundle;
public class Controller implements Initializable {
Statement statement;
Statement statementDatabase;
Statement stmntTables;
Statement stmntUse;
Statement stmntCols;
ResultSet resultDatabase;
ResultSet resultTables;
ResultSet resultUse;
ResultSet resultCols;
#FXML
TreeView <String> treeView;
#FXML
TableView<String> tableView;
#Override
public void initialize(URL url, ResourceBundle resourceBundle) {
try {
statement = DatabaseConnection.getInstance().getConnection().createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet result = statement.executeQuery("SHOW DATABASES");
TreeItem<String> root = new TreeItem<>("Datenbanken");
while(result.next()) {
TreeItem<String> node = new TreeItem<>(result.getString(1));
root.getChildren().add(node);
Statement statement2 = DatabaseConnection.getInstance().getConnection().createStatement();
ResultSet subResult = statement2.executeQuery("SHOW TABLES FROM " + result.getString(1));
while(subResult.next())
{
TreeItem<String> node2 = new TreeItem<>(subResult.getString(1));
node.getChildren().add(node2);
}
}
result.beforeFirst();
treeView.setRoot(root);
root.setExpanded(true);
ShowDatabase();
UseDatabase();
} catch (Exception e){
e.printStackTrace();
}
}
public void ShowDatabase() {
try {
statementDatabase = DatabaseConnection.getInstance().getConnection().createStatement();
resultDatabase = statementDatabase.executeQuery("SHOW DATABASES");
System.out.println("All Databases displayed!");
} catch (SQLException e) {
System.out.println("Databases could not be displayed!");
e.printStackTrace();
}
}
public void UseDatabase() {
try {
while (resultDatabase.next()) {
stmntUse = DatabaseConnection.getInstance().getConnection().createStatement();
resultUse = stmntUse.executeQuery("USE " + resultDatabase.getString(1));
//System.out.println(resultDatabase.getString(1));
ShowTables();
//System.out.println(resultTables.getString(1));
ShowColumns();
}
System.out.println("Database injected!");
System.out.println("All Tables displayed!");
System.out.println("All Columns displayed!");
} catch (SQLException e) {
System.out.println("Database ejected!");
e.printStackTrace();
}
}
public void ShowTables() {
try {
while (resultDatabase.next()) {
stmntTables = DatabaseConnection.getInstance().getConnection().createStatement();
// System.out.println(resultDatabase);
resultTables = stmntTables.executeQuery("SHOW TABLES FROM " + resultDatabase.getString(1));
// System.out.println(resultTables.getString(1));
}
} catch (SQLException e) {
System.out.println("Tables could not be displayed!");
e.printStackTrace();
}
}
public void ShowColumns() {
try {
while (resultTables.next()) {
stmntCols = DatabaseConnection.getInstance().getConnection().createStatement();
resultCols = stmntCols.executeQuery("SHOW COLUMNS FROM " + resultTables.getString(1));
System.out.println(resultCols);
FillTable(resultCols);
}
} catch (SQLException e) {
System.out.println("Columns could not be displayed!");
e.printStackTrace();
}
}
public void FillTable(ResultSet res) {
TableColumn<String, String>col = new TableColumn<String, String>();
try {
col.setCellValueFactory(new PropertyValueFactory<>(res.getString(1)));
} catch (SQLException e) {
e.printStackTrace();
}
tableView.getColumns().add(col);
}
}
and this is the Database Connection
package sample;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DatabaseConnection {
private static DatabaseConnection instance;
private Connection connection;
private static String ip = "localhost";
public static void setIp(String ip) {
DatabaseConnection.ip = ip;
}
private DatabaseConnection() throws SQLException
{
try {
Class.forName("com.mysql.cj.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://" + ip + ":" + 3306, "root", "");
System.out.println("Successfully connected to " + ip + "!");
} catch (Exception exc) {
//exc.printStackTrace();
System.out.println("Connection failed to " + ip + "!");
getConnection().close();
}
}
public Connection getConnection() {
return connection;
}
public static DatabaseConnection getInstance() throws SQLException {
if (instance == null) {
instance = new DatabaseConnection();
} else if (instance.getConnection().isClosed()) {
instance = new DatabaseConnection();
}
return instance;
}
}
Here is some code that should get you going. You will probably need a listener on the TreeView to change the table data and headers as you click on different items in the TreeView. This code simulates getting the headers from the database as List<String> and get the data from the database as List<List<String>>.
import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
/**
* JavaFX App
*/
public class App extends Application {
#Override
public void start(Stage primaryStage) {
ObservableList<ObservableList<String>> data = FXCollections.observableArrayList();
final List<List<String>> databaseData = getTableDataFromDBAsListOfList();//Get data from excel file
//Add database data to an observable list
for(int i = 0; i < databaseData.size(); i++)
{
data.add(FXCollections.observableArrayList(databaseData.get(i)));
}
TableView<ObservableList<String>> tableView = new TableView();
tableView.setItems(data);
//Create the table columns, set the cell value factory and add the column to the tableview.
List<String> tableHeaders = getTableHeadersFromDBAsList();
for (int i = 0; i < tableHeaders.size(); i++) {
final int curCol = i;
final TableColumn<ObservableList<String>, String> column = new TableColumn<>(tableHeaders.get(i));
column.setCellValueFactory(param -> new ReadOnlyObjectWrapper<>(param.getValue().get(curCol)));
tableView.getColumns().add(column);
}
StackPane root = new StackPane(tableView);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch();
}
public List<String> getTableHeadersFromDBAsList()
{
List<String> returnList = new ArrayList();
returnList.add("Header1");
returnList.add("Header2");
returnList.add("Header3");
returnList.add("Header4");
return returnList;
}
public List<List<String>> getTableDataFromDBAsListOfList()
{
List<List<String>> returnList = new ArrayList();
List<String> dataRow1 = new ArrayList();
dataRow1.add("Data 1 1");
dataRow1.add("Data 1 2");
dataRow1.add("Data 1 3");
dataRow1.add("Data 1 4");
List<String> dataRow2 = new ArrayList();
dataRow2.add("Data 2 1");
dataRow2.add("Data 2 2");
dataRow2.add("Data 2 3");
dataRow2.add("Data 2 4");
returnList.add(dataRow1);
returnList.add(dataRow2);
return returnList;
}
}
I need to display some database values from our db. I have the connection and everything working just fine, just once I set the query to something that actually has data in it, it breaks. It throws multiple NPEs on lines 63 and 65 of main.java, but I have no idea how to debug this because of how complex the line its on is. If anyone could offer some help it would be greatly appreciated.
Line 63:col.setCellValueFactory(new Callback<CellDataFeatures<ObservableList, String>, ObservableValue>() {
Line 65: return new SimpleStringProperty(param.getValue().get(j).toString());
Main.java
import java.sql.Connection;
import java.sql.ResultSet;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.TableView;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
import javafx.util.Callback;
public class main extends Application {
private ObservableList<ObservableList> data;
private TableView tableview;
public static void main(String[] args) {
launch(args);
}
public void buildData() {
Connection c;
data = FXCollections.observableArrayList();
try {
c = dbConnector.connect();
String SQL = "SELECT dbo.tbHardwareSite.SerialNo, dbo.tbHardwareSite.Hostname, dbo.tbHardwareSite.WinDomain, dbo.tbHardwareSite.Memory, dbo.tbHardwareSite.SwitchRouterConfig, dbo.tbHardwareSite.PurchaseDate, \n" +
" dbo.tbHardwareSite.InstallDate, dbo.tbHardwareSite.Notes, dbo.tbHardwareSite.IDTag AS Expr1, dbo.tbHardwareSite.ExpDate, dbo.tbHardware.HardwareName, dbo.tbHardware.HardwareDesc, dbo.tbHardware.ModelNo, \n" +
" dbo.tbManufacturers.MftrName, dbo.tbCustomers.CustomerID, dbo.tbSites.SiteName\n" +
"FROM dbo.tbHardwareSite INNER JOIN\n" +
" dbo.tbHardware ON dbo.tbHardwareSite.HardwareID_FK = dbo.tbHardware.HardwareID INNER JOIN\n" +
" dbo.tbSites ON dbo.tbHardwareSite.SiteID_FK = dbo.tbSites.SiteID INNER JOIN\n" +
" dbo.tbCustomers ON dbo.tbSites.CustomerID_FK = dbo.tbCustomers.CustomerID INNER JOIN\n" +
" dbo.tbManufacturers ON dbo.tbHardware.ManufacturerID_FK = dbo.tbManufacturers.MftrID INNER JOIN\n" +
" dbo.tbContacts ON dbo.tbSites.LocationContactID_FK = dbo.tbContacts.ContactID\n" +
"WHERE (dbo.tbCustomers.CustomerID = 247)";
ResultSet rs = c.createStatement().executeQuery(SQL);
/**
* ********************************
* TABLE COLUMN ADDED DYNAMICALLY *
*********************************
*/
for (int i = 0; i < rs.getMetaData().getColumnCount(); i++) {
final int j = i;
TableColumn col = new TableColumn(rs.getMetaData().getColumnName(i + 1));
col.setCellValueFactory(new Callback<CellDataFeatures<ObservableList, String>, ObservableValue<String>>() {
public ObservableValue<String> call(CellDataFeatures<ObservableList, String> param) {
return new SimpleStringProperty(param.getValue().get(j).toString());
}
});
tableview.getColumns().addAll(col);
System.out.println("Column [" + i + "] ");
}
while (rs.next()) {
//Iterate Row
ObservableList<String> row = FXCollections.observableArrayList();
for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) {
//Iterate Column
row.add(rs.getString(i));
}
data.add(row);
}
//FINALLY ADDED TO TableView
tableview.setItems(data);
System.out.println(data);
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void start(Stage stage) throws Exception {
//TableView
tableview = new TableView();
buildData();
//Main Scene
Scene scene = new Scene(tableview);
stage.setScene(scene);
stage.setOnCloseRequest(new EventHandler<WindowEvent>() {
#Override
public void handle(WindowEvent event) {
Platform.exit();
System.exit(0);
}
});
stage.show();
}
}
Here is dbConnector.java, which only handles the database connection
public class dbConnector {
private static Connection conn;
private static String url = "jdbc:sqlserver://10.9.32.46:1433;database=TechTracker;integratedSecurity=true";
String driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
public static Connection connect() throws SQLException {
try{
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver").newInstance();
}catch(ClassNotFoundException cnfe){
System.err.println("Error: "+cnfe.getMessage());
}catch(InstantiationException ie){
System.err.println("Error: "+ie.getMessage());
}catch(IllegalAccessException iae){
System.err.println("Error: "+iae.getMessage());
}
conn = DriverManager.getConnection(url);
return conn;
}
public static Connection getConnection() throws SQLException, ClassNotFoundException{
if(conn !=null && !conn.isClosed())
return conn;
connect();
return conn;
}
}
I was unable to enter the error log as it was over the character limit. Its a bunch of NullPointerExceptions on line 63 and 65 as I said.
I'm working on a program with which I can search through a database and display the results.
I'm stuck at the displaying part at the moment. My SQL query already works and returns the results. I'm using a PreparedStatement to fill my ResultSet. However I don't know how I can return the data of the ResultSet to a JTable which I want to use to display the data. Can anyone explain to me in detail how to do this or if there is a better way instead of a JTable I'm not seeing?
I'm using the MVC model and the DAO pattern, but I'm still pretty new to programming.
So far from researching it I found the best solution to be to make a custom table class, but from there on I don't know how to progress.
My custom table class:
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.Vector;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
public class ResultSetTable {
public static TableModel resultSetToTableModel(ResultSet rs) {
try {
ResultSetMetaData metaData = rs.getMetaData();
int numberOfColumns = metaData.getColumnCount();
Vector columnNames = new Vector();
//Spaltennamen
for (int column = 0; column < numberOfColumns; column++) {
columnNames.addElement(metaData.getColumnLabel(column + 1));
}
//Alle Zeilen
Vector rows = new Vector();
while (rs.next()) {
Vector newRow = new Vector();
for (int i = 1; i <= numberOfColumns; i++) {
newRow.addElement(rs.getObject(i));
}
rows.addElement(newRow);
}
return new DefaultTableModel(rows, columnNames);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
And the relevant part of my View class:
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.JTextField;
import dbconnect.dao.impl.BTRDaoImpl;
public class View extends JFrame{
public View() {
JTable table = new JTable(new ResultSetTable(BTRDaoImpl.resultset);
this.setSize(600, 400);
setResizable(false);
}
My BTRDaoImpl class with the sql query and resultset:
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import mvc.View;
import dao.BTRbDao;
import business.BTRBean;
public class BTRDaoImpl extends AbstractDao implements BTRDao {
private Connection dbConnection = null;
private PreparedStatement preparedStatement = null;
public void sqlquery() {
try {
String btrname = View.searchbbtrname.getText();
String btrplz = View.searchbtrplz.getText();
btrname = btrname.trim().toUpperCase();
btrplz = btrplz.trim().toUpperCase();
if (btrplz.isEmpty()) {
String btrResult = "SELECT BBSTBBNR, BBSTNABE, BBSTPLZ FROM BP.TBBBST WHERE BBSTNABEG = ?";
dbConnection = AbstractDao.getConnection();
preparedStatement = dbConnection.prepareStatement(btrResult);
preparedStatement.setString(1, btrname);
} else {
String btrResult = "SELECT BBSTBBNR, BBSTNABE, BBSTPLZ FROM BP.TBBBST WHERE BBSTNABEG = ? AND BBSTPLZ = ?";
dbConnection = AbstractDao.getConnection();
preparedStatement = dbConnection.prepareStatement(btrResult);
preparedStatement.setString(1, btrname);
preparedStatement.setString(2, btrplz);
}
} catch (SQLException e1) {
System.out.println("An error with the SQL query occured: ");
e1.printStackTrace();
}
}
public Collection<BtrBean> getBTR() throws SQLException,
IOException {
sqlquery();
final Collection<BtrBean> result = new ArrayList<BtrBean>();
ResultSet resultset = null;
try {
resultset = preparedStatement.executeQuery();
// while loop to get data
while (resultset.next()) {
BtrBean btr = new BtrBean();
int btrid = resultset.getInt(1);
String btrplz = resultset.getString(3);
String btrname = resultset.getString(2);
btr.setBetriebnr(btrid);
btr.setBetriebplz(btrplz);
btr.setBetriebname(btrname);
result.add(btr);
// System.out.println("BTR-ID: " + btrid + " BTR PLZ: " + btrplz + " BTR: " + btrname);
}
} catch (SQLException e) {
e.printStackTrace();
System.out.println("An error processing the SQL occured: ");
e.printStackTrace();
} catch (NullPointerException npe) {
System.out.println("NullPointerException: ");
npe.printStackTrace();
} finally {
if (preparedStatement != null) preparedStatement.close();
closeConnection(resultset);
}
return result;
}
}
My BTRBean class:
public class BetriebBean {
private String betriebname;
private int betriebnr;
private String betriebplz;
public BetriebBean() {
}
public BetriebBean(String betriebname, int betriebnr, String betriebplz) {
super();
this.betriebname = betriebname;
this.betriebnr = betriebnr;
this.betriebplz = betriebplz;
}
public String getBetriebname() {
return betriebname;
}
public void setBetriebname(String betriebname) {
this.betriebname = betriebname;
}
public int getBetriebnr() {
return betriebnr;
}
public void setBetriebnr(int betriebnr) {
this.betriebnr = betriebnr;
}
public String getBetriebplz() {
return betriebplz;
}
public void setBetriebplz(String betriebplz) {
this.betriebplz = betriebplz;
}
}
//edit:
My whole View.class:
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.JTextField;
public class View extends JFrame{
private static final long serialVersionUID = 1L;
public static final String SEARCH = "SEARCH";
private JLabel searchbtrlabel = new JLabel("BTR name:");
public static JTextField searchbtrname = new JTextField(10);
private JLabel searchbtrlabel = new JLabel("PLZ:");
public static JTextField searchbtrplz = new JTextField(10);
private JButton searchbutton = new JButton();
public View() {
this.setTitle("BTR search TBBBST");
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setLayout(new FlowLayout());
this.add(searchbtrlabel);
this.add(searchbtrname);
this.add(searchbtrplzlabel);
this.add(searchbtrplz);
searchbutton.setText("Search");
searchbutton.setActionCommand(View.SEARCH);
this.add(searchbutton);
JTable table = new JTable();
this.add(table);
this.setSize(600, 400);
setResizable(false);
//this.pack();
}
public JTextField getSearchbtrname() {
return searchbetriebname;
}
public JTextField getSearchbbtrplz() {
return searchbetriebplz;
}
public JButton getSearchbutton() {
return searchbutton;
}
}
My Controller class:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Observable;
import java.util.Observer;
import mvc.Model;
import dbconnect.dao.impl.BTRDaoImpl;
public class Controller implements Observer, ActionListener{
private Model model;
#SuppressWarnings("unused")
private View view;
public Controller(Model model, View view) {
this.model = model;
this.view = view;
model.addObserver(this);
view.getSearchbutton().addActionListener(this);
view.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
switch (e.getActionCommand()) {
case View.SEARCH:
model.search();
view.table.setModel(ResultSetToTable.buildTableModel(BTRDaoImpl.resultset));
break;
default:
System.out.println("Error : " + e.getActionCommand());
break;
}
}
#Override
public void update(Observable o, Object arg) {
// TODO Auto-generated method stub
}
}
Firstly, include rs2xml.jar in your libraries. You can find it here
In whatever action to populate your MySQL query in your JTable use following general idea:
public void sqlquery() {
try {
String btrResult = "SELECT BBSTBBNR, BBSTNABE, BBSTPLZ FROM BP.TBBBST WHERE BBSTNABEG = ?";
preparedStatement = dbConnection.prepareStatement(btrResult);
dbConnection.setString(1, btrname);
ResultSet rs =dbConnection.executeQuery();
Ur_table_name.setModel(DbUtils.resultSetToTableModel(DbUtils.resultSetToel(rs)); //this line of code will show it in your JTable
}catch(Exception e){
}
What is your question? Try being more specific than "[...] but from there on I don't know how to progress." What do you want to do? Are the results from your query visible in the table?
Using the answer from Paul Vargas over here Most simple code to populate JTable from ResultSet, you could start with something like this (using Java 8):
import java.sql.*;
import java.util.Vector;
import javax.swing.*;
import javax.swing.table.*;
public class ResultSetToTable {
public static void main(final String[] arguments) {
SwingUtilities.invokeLater(() -> {
try {
new ResultSetToTable().createAndShowGui();
} catch (SQLException e) {
e.printStackTrace();
}
});
}
private void createAndShowGui() throws SQLException {
final JFrame frame = new JFrame("Stack Overflow");
frame.setBounds(100, 100, 800, 600);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
final JPanel panel = new JPanel();
final TableModel tableModel = buildTableModel(getData("Audi"));
final JTable table = new JTable(tableModel);
panel.add(new JScrollPane(table));
frame.getContentPane().add(panel);
frame.setVisible(true);
}
private ResultSet getData(final String btrName) throws SQLException {
final String url = "jdbc:h2:/Freek/TBBBST";
final Connection connection = DriverManager.getConnection(url, "me", "123");
final String sql = "SELECT BBSTBBNR, BBSTNABE, BBSTPLZ " +
"FROM BP.TBBBST " +
"WHERE BBSTNABEG = ?";
final PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, btrName);
return preparedStatement.executeQuery();
}
/**
* See https://stackoverflow.com/a/10625471/1694043
*/
public static TableModel buildTableModel(final ResultSet resultSet)
throws SQLException {
int columnCount = resultSet.getMetaData().getColumnCount();
// Column names.
Vector<String> columnNames = new Vector<>();
for (int columnIndex = 1; columnIndex <= columnCount; columnIndex++) {
columnNames.add(resultSet.getMetaData().getColumnName(columnIndex));
}
// Data of the table.
Vector<Vector<Object>> dataVector = new Vector<>();
while (resultSet.next()) {
Vector<Object> rowVector = new Vector<>();
for (int columnIndex = 1; columnIndex <= columnCount; columnIndex++) {
rowVector.add(resultSet.getObject(columnIndex));
}
dataVector.add(rowVector);
}
return new DefaultTableModel(dataVector, columnNames);
}
}
For older versions of Java, you should be able to use this version of the main method:
public static void main(final String[] arguments) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
try {
new ResultSetToTable().createAndShowGui();
} catch (SQLException e) {
e.printStackTrace();
}
}
});
}
Edit: connecting controller and table
To make the table available outside the view, you need to convert the table variable in the View() constructor into a field (like you have done with searchbtrname) and create a getTable getter method for it (like you have done with getSearchbtrname). In the Controller.actionPerformed method you can now change view.table into view.getTable().
I get an error highlight with this code at:
ResultSet rs = stmt.executeQuery(sql);
'executeQuery' gets "red error highlight" in netbeans
How do I get it to work properly and get the application to work and populate the JavaFx TableView with data from the database.
Here's the rest of the Code:
The Controller Class:
import java.beans.Statement;
import java.net.URL;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.LinkedList;
import java.util.List;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
public class TesterUIController implements Initializable {
static String JDBC_DRIVER = "org.h2.Driver";
static String DB_URL = "jdbc:h2:file:C:/MyBeautifulCherrishabledb";
static final String USER = "sa";
static final String PASS = "";
public static Connection conn = null;
#FXML
private TableView<dataClass> Table;
#FXML
private Button TestButton;
#FXML
private TableColumn<dataClass, Integer> colKey;
#FXML
private TableColumn<dataClass, String> colSalesNo;
public static void main(String[] args) {
System.out.println("Main has run");
}
#Override
public void initialize(URL fxmlFileLocation, ResourceBundle resources) {
TestButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
System.out.println("Button Pressed");
colKey.setCellValueFactory(new PropertyValueFactory<dataClass, Integer>("Key"));
colSalesNo.setCellValueFactory(new PropertyValueFactory<dataClass, String>("SalesNo"));
Table.getItems().setAll(gobbledyGook());
}
});
}
public class dataClass {
private IntegerProperty Key;
public void setKey(int value) {
KeyProperty().set(value);
}
public int getKey() {
return KeyProperty().get();
}
public IntegerProperty KeyProperty() {
if (Key == null) {
Key = new SimpleIntegerProperty(this, "Key");
}
return Key;
}
private StringProperty SalesNo;
public void setSalesNo(String value) {
SalesNoProperty().set(value);
}
public String getSalesNo() {
return SalesNoProperty().get();
}
public StringProperty SalesNoProperty() {
if (SalesNo == null) {
SalesNo = new SimpleStringProperty(this, "SalesNo");
}
return SalesNo;
}
}
private List<dataClass> gobbledyGook() {
Statement stmt = null;
List ll = new LinkedList();
try {
// STEP 2: Register JDBC driver
Class.forName(JDBC_DRIVER);
// STEP 3: Open a connection
System.out.println("Connecting to a selected database...");
conn = DriverManager.getConnection(DB_URL, USER, PASS);
System.out.println("Connected database successfully...");
// STEP 4: Execute a query
System.out.println("Creating statement...");
stmt = (Statement) conn.createStatement();
String sql = "SELECT id, LovelyGuy FROM LOVELYPEOPLE";
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
int Key = rs.getInt(1);
double saleNo = rs.getDouble(2);
NumberFormat formatter = new DecimalFormat("###########");
String SalesNo = formatter.format(saleNo);
System.out.println(Key + ", " + SalesNo); //key + ", " + saleNo);
dataClass roww = new dataClass();
roww.setKey(Key);
roww.setSalesNo(SalesNo);
ll.add(roww);
}
} catch (ClassNotFoundException | SQLException ex) {
Logger.getLogger(TesterUIController.class.getName()).log(Level.SEVERE, null, ex);
}
return ll;
}
}
The main Class
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class TesterUI extends Application {
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("TesterUI.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
The FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="600.0" prefWidth="700.0" xmlns:fx="http://javafx.com/fxml" fx:controller="testerui.TesterUIController">
<children>
<Button fx:id="TestButton" layoutX="14.0" layoutY="14.0" mnemonicParsing="false" text="Button" />
<Pane layoutY="35.0" prefHeight="565.0" prefWidth="700.0">
<children>
<TableView fx:id="Table" layoutX="14.0" layoutY="14.0" prefHeight="226.0" prefWidth="672.0">
<columns>
<TableColumn prefWidth="75.0" text="Column X" fx:id="colKey" />
<TableColumn prefWidth="75.0" text="Column X" fx:id="colSalesNo" />
</columns>
</TableView>
</children>
</Pane>
</children>
</AnchorPane>
Update:
The ErrorStackTrace:
ResultSet rs = stmt.executeQuery(sql);
symbol: method executeQuery(String)
location: variable stmt of type Statement
Note: C:\Users\Revilo\Downloads\GitHub\Tables\Tablas-JavaFX--FXML--master\src\TesterUI\src\testerui\TesterUIController.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 error
you have imported
import java.beans.Statement;
You should use
import java.sql.Statement;