I made a JavaFX Scenebuilder "Application" and I need to fill my listView with things from my database. The problem is that I don't know how and I don't know where to look.
Is there someone who can help me out?
Here is the code with my connection to the database. That's the only thing I have. And the scene builder "Sample.fxml" file of course.
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
Connection Conn = null;
try {
Conn = DriverManager.getConnection("jdbc:mysql://localhost/hitdossier", "root", "");
System.out.println("Verbonden met de database");
} catch (SQLException e) {
System.out.println(e.getMessage());
System.out.println("Verbinding met de database is mislukt.");
}
Statement stmt = null;
ResultSet rs = null;
try {
stmt = Conn.createStatement();
rs = stmt.executeQuery("SELECT naam FROM artiest");
while (rs.next()) {
System.out.println(rs.getString(1));
}
} catch (SQLException e) {
}
primaryStage.setTitle("Eindopdracht Java Periode 4");
primaryStage.setScene(new Scene(root, 700, 650));
primaryStage.show();
}
This is my Controller.java
package sample;
import javafx.fxml.FXML;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ListView;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
public class Controller {
#FXML
private ComboBox<String> cboWeek;
}
I would go for the following code:
First define your listView and an observable list (assuming that you have a ListView in your fxml with the id "list"):
#FXML
ListView<String> list;
ObservableList<String> items = FXCollections.observableArrayList();
Then set the list view to the items list:
list.setItems(items);
in your while loop simply add the results to the items list:
items.add(rs.getString(1));
You could do the following (code not tested):
Main.java:
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Eindopdracht Java Periode 4");
primaryStage.setScene(new Scene(root, 700, 650));
primaryStage.show();
}
}
Controller.java (associated with a fxml that contains a ListView with id=list):
public class Controller implements Initializable{
#FXML
private ListView<String> list;
private ObservableList<String> items = FXCollections.observableArrayList();
#Override
public void initialize(URL location, ResourceBundle resources) {
list.setItems(items);
Connection Conn = null;
try {
Conn = DriverManager.getConnection("jdbc:mysql://localhost/hitdossier", "root", "");
System.out.println("Verbonden met de database");
} catch (SQLException e) {
System.out.println(e.getMessage());
System.out.println("Verbinding met de database is mislukt.");
}
Statement stmt = null;
ResultSet rs = null;
try {
stmt = Conn.createStatement();
rs = stmt.executeQuery("SELECT naam FROM artiest");
while (rs.next()) {
items.add(rs.getString(1));
System.out.println(rs.getString(1));
}
} catch (SQLException e) {
}
}
}
By implementing the initialize method you could load the contents whenever the scene is shown.
Related
The tableview only shows newly added data when I restart the program.
The steps I follow to add the new item are:
dialogCadastro
Confirm the registry
update the table
However, updating the table does not work.
This is my code:
public class ControllerTelaOperacoes implements Initializable {
#FXML
TableView<Item> tblItem;
#FXML
TableColumn<Item, String> colCodigoItem;
#FXML
TableColumn<Item, String> colDescricaoItem;
#FXML
TableColumn<Item, String> colValorItem;
#FXML
TableColumn<Item, String> colQuantidadeItem;
#FXML
TableColumn<Item, String> colFornecedorItem;
#FXML
TextField txtQuantidadeItem;
#FXML
TextField txtValorItem;
#FXML
TextField txtDescricaoItem;
// #FXML
// ComboBox cbxFornecedorItem;
#FXML
Button btnConfirmarEstoqueAtualizar;
#FXML
Button btnConfirmarEstoqueCadastro;
#FXML
TextField txtIDAtualizar;
#FXML
Button btnCadastrarItem;
#FXML
Button btnAtualizarItem;
#FXML
Button btnEfetuarVenda;
private static Scene dialogEstoqueCadastrar;
private static Scene dialogEstoqueAtualizar;
private static Scene dialogEfetuarVenda;
private String dados;
public String getDados() {
return dados;
}
public void setDados(String dados) {
this.dados = dados;
}
#FXML
public void CadastrarItem() throws IOException {
tblItem.refresh();
Parent fxmldialogEstoqueCadastro = FXMLLoader
.load(getClass().getResource("/views/dialogEstoqueCadastrar.fxml"));
dialogEstoqueCadastrar = new Scene(fxmldialogEstoqueCadastro);
Stage primaryStage = new Stage();
Image image = new Image("/img/iconeSistema.png");
primaryStage.setResizable(false);
primaryStage.getIcons().add(image);
primaryStage.setTitle("Cadastrar item");
primaryStage.setScene(dialogEstoqueCadastrar);
primaryStage.show();
}
#FXML
public void AtualizarItem() throws IOException {
tblItem.refresh();
Parent fxmldialogEstoqueAtualizar = FXMLLoader
.load(getClass().getResource("/views/dialogEstoqueAtualizar.fxml"));
dialogEstoqueAtualizar = new Scene(fxmldialogEstoqueAtualizar);
Stage primaryStage = new Stage();
Image image = new Image("/img/iconeSistema.png");
primaryStage.setResizable(false);
primaryStage.getIcons().add(image);
primaryStage.setTitle("Atualizar item");
primaryStage.setScene(dialogEstoqueAtualizar);
primaryStage.show();
}
#FXML
public void EfetuarVenda() throws IOException {
tblItem.refresh();
Parent fxmldialogEfetuarVenda = FXMLLoader.load(getClass().getResource("/views/dialogEfetuarVenda.fxml"));
dialogEfetuarVenda = new Scene(fxmldialogEfetuarVenda);
Stage primaryStage = new Stage();
Image image = new Image("/img/iconeSistema.png");
primaryStage.setResizable(false);
primaryStage.getIcons().add(image);
primaryStage.setTitle("Efetuar Venda");
primaryStage.setScene(dialogEfetuarVenda);
primaryStage.show();
}
// CONTROLE DE ESTOQUE
#Override
public void initialize(URL url, ResourceBundle rb) {
// conecta tabela com o bd
try {
Class.forName("com.mysql.jdbc.Driver");
Connection con;
con = DriverManager.getConnection("jdbc:mysql://127.0.0.1/bdprojetointegrador", "root", "");
System.out.println("TESTE TABELA 1");
Statement stmt = con.createStatement();
System.out.println("TESTE TABELA 2");
ResultSet rs = stmt.executeQuery("SELECT * FROM item");
System.out.println("TESTE TABELA 3");
while (rs.next()) {
ObservableList<Item> dados = FXCollections
.observableArrayList(new Item(rs.getString("codigo"), rs.getString("descricao"),
rs.getString("valor"), rs.getString("quantidade"), rs.getString("fornecedor_codigo")));
System.out.println("TESTE TABELA 4");
tblItem.getItems().addAll(dados);
colCodigoItem.setCellValueFactory(new PropertyValueFactory<>("codigo"));
colDescricaoItem.setCellValueFactory(new PropertyValueFactory<>("descricao"));
colValorItem.setCellValueFactory(new PropertyValueFactory<>("valor"));
colQuantidadeItem.setCellValueFactory(new PropertyValueFactory<>("quantidade"));
colFornecedorItem.setCellValueFactory(new PropertyValueFactory<>("fornecedor_codigo"));
System.out.println("TESTE TABELA 5");
}
stmt.close();
rs.close();
con.close();
System.out.println("TESTE 6");
} catch (
ClassNotFoundException e1) {
Alert classe = new Alert(AlertType.ERROR);
classe.setContentText("Classe não encontrada!");
classe.show();
} catch (SQLException e2) {
// ESTÁ CHAMANDO ESTA FUNÇÃO
Alert classe = new Alert(AlertType.ERROR);
classe.setContentText("Matricula já existente! ERRO: " + e2);
classe.show();
}
}
}
I'm writing an application with JavaFX, Scene Builder and SQlite
I have combobox with values(id) that goes from SQLite database.I have 2 textArias. I have a button "Add" that has a method void addCard(ActionEvent event). The method add text from textArias and apply it to particular columns in SQLite.
The problem is: when I try to add values to SQLite and click a button and then I open combobox, I don't see added ID, but when I close the window and open it again combobox display my added id.
It is very annoying to close and open window every time when I want to see the added result in combobox
Model class holds all logic
Controller Class operate between Model and view
Persistent Queries class holds all queries to/from SQLite
How to display new added ID after clicking on the button "Add"?
This video shows how my application work:
Video
Model class:
package src.card;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class Cards {
PersistentQueries pq = new PersistentQueries();
final ObservableList OPTIONS = FXCollections.observableArrayList();
Connection connection;
PreparedStatement pst = null;
ResultSet rs = null;
public Cards() {
try {
this.connection = DbConnection.getConnection();
} catch (SQLException ex) {
ex.printStackTrace();
}
if (this.connection == null) {
System.out.println("connection is not successful!");
System.exit(1);
}
}
public ObservableList getOPTIONS() {return OPTIONS;}
//add ID of cards to combobox
void fillCombobox() {
try {
pst = connection.prepareStatement(pq.getSqlSelectID());
rs = pst.executeQuery();
while (rs.next()) {
OPTIONS.add(rs.getString("ID"));
}
pst.close();
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
//check if database is connected
public boolean isDbConnected() {
return this.connection != null;
}
}
Controller Class:
package src.card;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import src.card.Cards;
import src.card.Context;
import src.card.DbConnection;
import src.card.PersistentQueries;
import java.net.URL;
import java.sql.*;
import java.util.ResourceBundle;
public class QuestController implements Initializable {
#FXML private TextArea ta_questText, ta_answerText;
#FXML private Label questId, error;
#FXML private ComboBox<String> combobox_question;
Cards cards = new Cards();
PersistentQueries pq = new PersistentQueries();
#Override
public void initialize(URL location, ResourceBundle resources) {
//register QuestController in Context Class
Context.getInstance().setQuestController(this);
cards.fillCombobox();
combobox_question.setItems(cards.getOPTIONS());
}
//adding cards to database
#FXML
void addCard(ActionEvent event) {
if (ta_questText.getText().equals("") ||
ta_answerText.getText().equals("")) {
error.setText("All fields are required!");
} else {
try {
error.setText("");
Connection conn = DbConnection.getConnection();
PreparedStatement stmt = conn.prepareStatement(pq.getSqlInsert());
stmt.setString(1, this.ta_questText.getText());
stmt.setString(2, this.ta_answerText.getText());
ta_questText.setText("");
ta_answerText.setText("");
stmt.execute();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
#FXML
void idList(ActionEvent event) {
questId.setText(combobox_question.getValue() + ".");
}
}
PersistentQueries Class
package src.card;
public class PersistentQueries {
private String sqlInsert = "INSERT INTO Cards(question, answer) VALUES
(?,?)";
private String sqlSelectID = "SELECT ID FROM Cards";
private String sqlSelect = "SELECT question and answer FROM Cards";
public String getSqlInsert() {
return sqlInsert;
}
public void setSqlInsert(String sqlInsert) {
this.sqlInsert = sqlInsert;
}
public String getSqlSelectID() {
return sqlSelectID;
}
public void setSqlSelectID(String sqlSelectID) {
this.sqlSelectID = sqlSelectID;
}
public String getSqlSelect() {
return sqlSelect;
}
public void setSqlSelect(String sqlSelect) {
this.sqlSelect = sqlSelect;
}
}
PROBLEM SOLVED!
in QuestController in the method #FXML void addCard(ActionEvent event) I added
cards.getOBS().clear();
It removes all objects from Observable list
then, I called method from Cards Class that reads all new data from SQLite and add it to Observable list
cards.fillCombobox();
and then I just close all connections:
pst.close();
rs.close();
conn.close();
My rewritten method looks like this:
/adding cards to database, update combobox and clear label text
#FXML void addCard(ActionEvent event) {
if (ta_questText.getText().equals("") || ta_answerText.getText().equals("")) {
error.setText("All fields are required!");
} else {
try {
error.setText("");
Connection conn = DbConnection.getConnection();
pst = conn.prepareStatement(pq.getSqlInsert());
pst.setString(1, this.ta_questText.getText());
pst.setString(2, this.ta_answerText.getText());
pst.execute();
pst = conn.prepareStatement(pq.getSqlSelectID());
rs = pst.executeQuery();
ta_questText.clear();
ta_answerText.clear();
cards.getOBS().clear();
questId.setText("");
cards.fillCombobox();
pst.close();
rs.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
a view from my work
public class LoginController implements Initializable {
Librarian l1=new Librarian();
#FXML
private TextField username;
#FXML
private PasswordField password;
#FXML
private Button loginButton;
#FXML
private Label status;
#FXML
private Label loginStatus;
#FXML
public void LibrarianLogin(ActionEvent event) {
try {
if(this.l1.isLogin(this.username.getText(), this.password.getText())) {
Stage stage = (Stage) this.loginButton.getScene().getWindow();
stage.close();
adminLogin();
}
else {
loginStatus.setText("Invalid");
}
}
catch(Exception locaException) {
}
}
public void adminLogin()
{
try {
Stage adminstage = new Stage();
FXMLLoader adminLoader = new FXMLLoader();
Pane adminroot = (Pane)adminLoader.load(getClass().getResource("/Librarian/admin.fxml").openStream());
AdminController adminController = (AdminController)adminLoader.getController();
Scene scene =new Scene(adminroot);
adminstage.setScene(scene);
adminstage.setTitle("Admin Dashboard");
adminstage.show();
}
catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void initialize(URL location, ResourceBundle resources) {
if(this.l1.isDatabaseConnected()){
this.status.setText("Connected to Database");
}
else{
this.status.setText("Not Connected");
}
}
Connection connection;
public Librarian(){
try {
this.connection=dbConnection.getConnection();
}
catch (SQLException ex){
ex.printStackTrace();
}
if(this.connection == null){
System.exit(1);
}
}
public boolean isDatabaseConnected(){
return this.connection != null;
}
public boolean isLogin(String username,String id)throws Exception {
PreparedStatement pr= null;
ResultSet rs= null;
String sql = "SELECT * FROM Librarian where username = ? and password = ?";
try {
pr=connection.prepareStatement(sql);
pr.setString(1,username);
pr.setString(2, id);
rs = pr.executeQuery();
}
catch (SQLException ex) {
return false;
}
finally {
pr.close();
rs.close();
}
}
return false;
}
when ever i retrieve data from database to text box in login form nothing happens when i click the login button. Even when i enter wrong credentials the label to set login invalid doesn't work.
I made different packages:
package for logging in
package for database
package for admins after logging in
Thanks in advance :)
I have two different controllers, but by getting a certain value at one of them I want to use it at the second controller's initializable.
This is the part where the first controller sends the region parameter to the other controler
public void enterlevel(String x) throws IOException{
FXMLLoader Loader=new FXMLLoader();
Loader.setLocation(getClass().getResource(x));
Loader.load();
regionalController reg=Loader.getController();
reg.getRegion(region);
//System.out.println(region);
Parent root = Loader.getRoot();
Stage primaryStage = new Stage();
Scene scene = new Scene(root);
primaryStage.setTitle("Ziga Ziga");
primaryStage.setScene(scene);
primaryStage.setMaximized(true);
primaryStage.setResizable(false);
primaryStage.show();
Stage stage = (Stage) loginButton.getScene().getWindow();
stage.close();
}
This is where the second controller gets it
public void getRegion(String region) {
System.out.println(region+" UO UO UO ");
regi=region;
}
And this is the initializable where I can't use the value as it starts
public void initialize(URL arg0, ResourceBundle arg1) {
System.out.println(regi);
try{
Class.forName("com.mysql.jdbc.Driver");
Connection con=DriverManager.getConnection("jdbc:mysql://localhost/bimbima","root","");
Statement stmt=con.createStatement();
ResultSet rs=stmt.executeQuery("SELECT * FROM `file` WHERE Region = '"+regi+"'");
while(rs.next()) {
filename=rs.getString("filename");
nameofSup=rs.getString("Name of Supervisor");
System.out.println(filename);
}
con.close();
}catch(Exception e){ System.out.println(e);}
}
Aside: surely your getRegion(...) method should be called setRegion(...), since it changes the value of a property, and doesn't return anything.
Just change the code in the second controller so that you only retrieve the values from the database when you know the region:
public void initialize(URL arg0, ResourceBundle arg1) {
}
public void setRegion(String region) {
regi=region;
try{
Class.forName("com.mysql.jdbc.Driver");
Connection con=DriverManager.getConnection("jdbc:mysql://localhost/bimbima","root","");
Statement stmt=con.createStatement();
ResultSet rs=stmt.executeQuery("SELECT * FROM `file` WHERE Region = '"+regi+"'");
while(rs.next()) {
filename=rs.getString("filename");
nameofSup=rs.getString("Name of Supervisor");
System.out.println(filename);
}
con.close();
} catch(Exception e) {
e.printStackTrace();
}
}
I wants to create 2 table view in scene builder and first table will retrieve data from a mysql table and after which the use choose one of the rows from the first table to view more data of that particular row. How should I do it?
Edit: the closest example i got from google is http://edu.makery.ch/blog/2012/11/16/javafx-tutorial-addressapp-1/
But the data is not retrieve from database. I had added my codes below and the error message that i gotten from eclipse.
public class MainApp extends Application {
private Stage primaryStage;
private BorderPane rootLayout;
private ObservableList<Food> foodData = FXCollections.observableArrayList();
#Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("Canteen Management System");
try {
// Load the root layout from the fxml file
FXMLLoader loader = new FXMLLoader(MainApp.class.getResource("view/RootLayout.fxml"));
rootLayout = (BorderPane) loader.load();
Scene scene = new Scene(rootLayout);
primaryStage.setScene(scene);
primaryStage.show();
} catch (IOException e) {
// Exception gets thrown if the fxml file could not be loaded
e.printStackTrace();
}
showPersonOverview();
}
public void showPersonOverview() {
try {
// Load the fxml file and set into the center of the main layout
// FXMLLoader loader = new FXMLLoader(MainApp.class.getResource("cams/order/view/OrderMenu.fxml"));
// AnchorPane overviewPage = (AnchorPane) loader.load();
// rootLayout.setCenter(overviewPage);
// FoodController controller = loader.getController();
FoodController controller = (FoodController) replaceSceneContent("cams/order/view/OrderMenu.fxml");
controller.setMainApp(this);
} catch (Exception ex) {//IOException e
Logger.getLogger(MainApp.class.getName()).log(Level.SEVERE, null, ex);
// Exception gets thrown if the fxml file could not be loaded
//e.printStackTrace();
}
}
private Initializable replaceSceneContent(String fxml) throws Exception {
FXMLLoader loader = new FXMLLoader();
InputStream in = MainApp.class.getResourceAsStream(fxml);
loader.setBuilderFactory(new JavaFXBuilderFactory());
loader.setLocation(MainApp.class.getResource(fxml));
AnchorPane page;
try {
page = (AnchorPane) loader.load(in);
} finally {
in.close();
}
Scene scene = new Scene(page, 1280, 800);
primaryStage.setScene(scene);
primaryStage.sizeToScene();
return (Initializable) loader.getController();
}
public ObservableList<Food> getPersonData() {
return foodData;
}
public Stage getPrimaryStage() {
return primaryStage;
}
public static void main(String[] args) {
launch(args);
}
}
public class FoodController implements Initializable{
#FXML
private TableView<Food> tblViewer = new TableView<Food>();
#FXML
private TableColumn<Food, String> foodPicture;
#FXML
private TableColumn<Food, String> foodName;
#FXML
private TableColumn<Food, Integer> foodPrice;
#FXML
private TableColumn<Food, Integer> foodID;
private MainApp mainApp;
#Override
public void initialize(URL url, ResourceBundle rb) {
// foodID.setCellValueFactory(new PropertyValueFactory<Food, Integer> ("id"));
// foodPrice.setCellValueFactory(new PropertyValueFactory<Food, Integer>("price"));
foodName.setCellValueFactory(new PropertyValueFactory<Food, String>("name"));
foodPicture.setCellValueFactory(new PropertyValueFactory<Food, String>("picture"));
tblViewer.getItems().setAll(getAllFoodInfo());
}
public List<Food> getAllFoodInfo(){
Connection conn;
List ll = new LinkedList();
Statement st;
ResultSet rs;
String url = "jdbc:mysql://localhost/cams";
String user = "root";
String pass = "admin";
String driver = "com.mysql.jdbc.Driver";
try{
Class.forName(driver);
conn = DriverManager.getConnection(url, user, pass);
st = conn.createStatement();
String recordQuery = ("Select * from food");
rs = st.executeQuery(recordQuery);
while(rs.next()){
Integer id = rs.getInt("id");
double price = rs.getDouble("price");
String name = rs.getString("name");
String picture = rs.getString("picture");
ll.add(new Food(id, price, name, picture));
System.out.println(id +","+ price +","+ name +","+ picture +" "+"added.");
}
}catch(ClassNotFoundException | SQLException ex){
Logger.getLogger(FoodController.class.getName()).log(Level.SEVERE, null, ex);
}
return ll;
}
public void setMainApp(MainApp mainApp) {
this.mainApp = mainApp;
// Add observable list data to the table
tblViewer.setItems(mainApp.getPersonData());
}
}
Exception in Application start method
Exception in thread "main" java.lang.RuntimeException: Exception in Application start >method
at >com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:403)
at com.sun.javafx.application.LauncherImpl.access$000(LauncherImpl.java:47)
at com.sun.javafx.application.LauncherImpl$1.run(LauncherImpl.java:115)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalStateException: Location is not set.
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2021)
at cams.order.main.MainApp.start(MainApp.java:37)
at com.sun.javafx.application.LauncherImpl$5.run(LauncherImpl.java:319)
at com.sun.javafx.application.PlatformImpl$5.run(PlatformImpl.java:215)
at com.sun.javafx.application.PlatformImpl$4$1.run(PlatformImpl.java:179)
at com.sun.javafx.application.PlatformImpl$4$1.run(PlatformImpl.java:176)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl$4.run(PlatformImpl.java:176)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$100(WinApplication.java:29)
at com.sun.glass.ui.win.WinApplication$3$1.run(WinApplication.java:73)
... 1 more