How to display Column Headers from a Mysql database in JavaFX TableView? - java

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;
}
}

Related

Passing login Email from one class to another

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.

Display SQL Server data in a JavaFX Tableview

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.

JavaFX TreeTableView is slow when expand the nodes?

we use a TreeTabelView to view products with subproducts. But when we click on the triangle to expand a node, than there is a very big delay (about 1000 ms).
Here is the code:
package controller;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.control.cell.TreeItemPropertyValueFactory;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import loginPackage.DBConnection;
import model.Product;
import model.ProductType;
import java.net.URL;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
public class ShowSetsController implements Initializable{
#FXML
private TreeTableView TTVShowSets;
#FXML
private TreeTableColumn tcShowSetsProductName, tcShowSetsDescription;
#FXML
private TextField tfSearch;
#Override
public void initialize(URL location, ResourceBundle resources) {
TTVShowSets.setVisible(true);
tcShowSetsProductName.setCellValueFactory(new TreeItemPropertyValueFactory<>("productTypeName"));
tcShowSetsDescription.setCellValueFactory(new TreeItemPropertyValueFactory<>("productTypeDescription"));
List<Product> setHeaders = null;
try {
setHeaders = DBConnection.getInstance().getHighestSetHeaders();
} catch (SQLException e) {
e.printStackTrace();
e.printStackTrace();
}
TTVShowSets.setRoot(null);
TreeItem<Product> root = new TreeItem<>(new Product(-1,null,null,null, null, null));
for (int i = 0; i < setHeaders.size(); i++){
TreeItem<Product> cache = new TreeItem<>(setHeaders.get(i));
try {
this.printSetsTree(setHeaders.get(i), cache);
} catch (SQLException e) {
e.printStackTrace();
}
root.getChildren().add(cache);
}
TTVShowSets.setShowRoot(false);
TTVShowSets.setRoot(root);
}
public void printSetsTree(Product head, TreeItem<Product> father) throws SQLException {
List<Product> listOfChildren = DBConnection.getInstance().getProductsChildrenByProductID(head);
for(int i = 0; i < listOfChildren.size(); i++) {
listOfChildren.get(i).setIsChild(true);
listOfChildren.get(i).setSelected(null);
TreeItem<Product> child = new TreeItem<>(listOfChildren.get(i));
father.getChildren().add(child);
Product childProduct = listOfChildren.get(i);
printSetsTree(childProduct,child);
}
}
#FXML
private void serachProduct(KeyEvent event) throws SQLException {
TTVShowSets.setVisible(true);
TTVShowSets.setRoot(null);
KeyCode keycode = event.getCode();
String search = tfSearch.getText();
if(keycode == KeyCode.BACK_SPACE && search.length() > 0){
search = search.substring(0,search.length()-1);
}
else search += event.getText();
TreeItem<Product> root = new TreeItem<>(new Product(-1, null, null, null, null, null)); //empty root element
List<Product> listHeaders = DBConnection.getInstance().getHighestSetHeaders();
for (Product listHeader : listHeaders){
TreeItem<Product> parent = new TreeItem<>(listHeader);
List<Product> childs = DBConnection.getInstance().getProductsByProductTypeIdWhichAraNotInaSet(listHeader.getProducttypeID());
for(Product child : childs){
if (listHeader.getProductTypeName().toLowerCase().contains(search.toLowerCase())){
child.setIsChild(true);
TreeItem<Product> cache = new TreeItem<>(child);
printSetsTree(child, cache);
parent.getChildren().add(cache);
}
}
if (parent.getChildren().size() > 0 && listHeader.getProductTypeName().toLowerCase().contains(search.toLowerCase())){
root.getChildren().add(parent);
}
else TTVShowSets.setVisible(false);
}
TTVShowSets.setShowRoot(false);
TTVShowSets.setRoot(root);
}
#FXML
public void refreshTTV(){
TTVShowSets.refresh();
}
}
Maybe the implementation is false or the Database request are too slow, but we don't think that that is the reason because the TreeTableView is loaded with all nodes by initializing the pane? Thanks for your time and help!

Display ResultSet of a SQL query in a JTable (Java)

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().

Unexpected type required variable found value

public class example
{
public ArrayList<Integer> ToFill = new ArrayList<>();
public void Alter(int Value , int Position)
{
ToFill.get(Position) = Value ; // this line has an error
}
}
For some reason this code gives compilation Error ,could anyone explain why?
ToFill.get(Position) returns a value where the left-hand side of the assignment must be a variable. Instead, use set(index, element) as follows:
ToFill.set(Position, Value);
However, what you are doing is only valid if you are using arrays, for example:
Integer[] array = ...
array[Position] = Value;
As a side note, always use Java naming convention:
toFill instead of ToFill
alter instead of Alter
position instead of Position.
value instead of Value.
#FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
label.setText("Hellow Word!");
if (event.getSource() = btnInsert) { //ERROR
insertRecors();
}
package operator;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Stage;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.net.URL;
import java.sql.*;
import java.util.ResourceBundle;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
public class Pyti implements Initializable {
private Label label;
//внести значение
#FXML
private TextField tfId;
#FXML
private TextField tfTitle;
//таблица
#FXML
private TableView<Books> tvBooks;
#FXML
private TableColumn<Books, Integer> colId;
#FXML
private TableColumn<Books, String> colTitle;
///
#FXML
private Button behaind;
#FXML
private Button glavnaia;
///
#FXML
private Button btnInsert;
#FXML
private Button btnUpdate;
#FXML
private Button btnDelete;
#FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
label.setText("Hellow Word!");
if (event.getSource() = btnInsert) {
insertRecors();
}
}
#Override
public void initialize(URL url, ResourceBundle rd) {
{
showBooks();
}
glavnaia.setOnAction(event -> {
openNewScene("/vhod.fxml");
});
behaind.setOnAction(event -> {
openNewScene("/operator.fxml");
});
}
private void openNewScene(String window) {
glavnaia.getScene().getWindow().hide();
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource(window));
try {
loader.load();
} catch (IOException e) {
e.printStackTrace();
}
Parent root = loader.getRoot();
Stage stage = new Stage();
stage.setScene(new Scene(root));
stage.show();
}
public Connection getConnection() {
Connection conn;
try {
conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mysor", "root", "12345");
return conn;
} catch (Exception ex) {
System.out.println("Error: " + ex.getMessage());
return null;
}
}
public ObservableList<Books> getBooksList() {
ObservableList<Books> bookList = FXCollections.observableArrayList();
Connection conn = getConnection();
String query = "SELECT * FROM books";
Statement st;
ResultSet rs;
try {
st = conn.createStatement();
rs = st.executeQuery(query);
Books books;
while (rs.next()) {
books = new Books(rs.getInt("id"), rs.getString("title"));
bookList.add(books);
}
} catch (Exception ex) {
ex.printStackTrace();
}
return bookList;
}
public void showBooks() {
ObservableList<Books> list = getBooksList();
colId.setCellValueFactory(new PropertyValueFactory<Books, Integer>("id"));
colTitle.setCellValueFactory(new PropertyValueFactory<Books, String>("title"));
tvBooks.setItems(list);
}
private void insertRecors() throws SQLException {
String query = "INCERT INTO books VALUES (" + tfId.getText() + "," + tfTitle.getText() + ")";
executeQuery(query);
showBooks();
}
private void executeQuery(String query) throws SQLException {
Connection conn = getConnection();
Statement st;
try {
st = conn.createStatement();
st.executeUpdate(query);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}

Categories