Updated in: Aug 5, 2014 @ 12:50 by Narayan [This update is compatible with new Java 8 codes modified]
Hello, Today I’m going to show the demo of how to display the exact database data in JavaFX 2.0 from TableView. I call this TableView as Dynamic TableView because the tableview automatically manages the columns and rows.
Requirements of this demo:
Database Structure
This below give the structure of database table I used for sample.
1 2 3 4 5 6 7 8 |
Customer Table +----------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------------+--------------+------+-----+---------+----------------+ | col0 | int(11) | NO | PRI | NULL | auto_increment | | col1 | varchar(200) | NO | | NULL | | | col2 | int(4) | NO | | NULL | | +----------------+--------------+------+-----+---------+----------------+ |
JavaFX 2.0 SourceCode
Main GUIClass
This class consists all the GUI Components and the data are being extracted from database
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
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; /** * * @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.setOnCloseRequest(new EventHandler<WindowEvent>() { @Override public void handle(WindowEvent event) { Platform.exit(); System.exit(0); } }); stage.show(); } } |
Here I used ObservableList< ObservableList > ‘data’ for keeping the records so that I could add data of Rows and Columns.The above class makes a dynamic TableView extracted data from Database.
Database Connectivity Class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; /** * * @author Narayan */ public class DBConnect { private static Connection conn; private static String url = "jdbc:mysql://localhost/test"; private static String user = "root"; private static String pass = "rootp@$$"; public static Connection connect() throws SQLException{ try{ Class.forName("com.mysql.jdbc.Driver").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,user,pass); return conn; } public static Connection getConnection() throws SQLException, ClassNotFoundException{ if(conn !=null && !conn.isClosed()) return conn; connect(); return conn; } } |
In above class the url,user,pass may varies according to your mysql configuration.
Output:
Here you go the output depends upon the database queries.
All the source code are published in a github repository : https://github.com/privatejava/javafx-dynamic-tableview
Don’t hesitate on commenting your views.
Thanks for viewing Hava a 🙂 good day.
Hi duke,
Please make sure you have added this line in your code which helps to create new TableView Object. Otherwise the Null Pointer Exception would occur.
tableview = new TableView();
Thanks
for(int i=0;i<colcount;i++)
{
final int j=i;
col = new TableColumn(rs.getMetaData().getColumnName(i+1));
col.setCellValueFactory(new Callback<CellDataFeatures,ObservableValue>(){
@Override
public ObservableValue call(TableColumn.CellDataFeatures param)
{
return new SimpleStringProperty(param.getValue().get(j).toString());
}
});
System.out.println(“table header created”+col.getText());
tableview.getColumns().addAll(col);
System.out.println(“Column [“+i+”] “);
}
while(rs.next())
{
//Iterate Row
ObservableList 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 );
tableview.setItems(row);
}
i am getting java.lang.ClassCastException: java.lang.String cannot be cast to javafx.collections.ObservableList exeption can anyone help me please
Hi revanth,
I think you have some error on casting. Can you point out the line number or the code where the exceptio is causing.
Thanks
it is getting error at the number col.setCellValueFactory(new Callback(){ &
return new SimpleStringProperty(param.getValue().get(j).toString());
Hi sir actually my problem is when i am clicking on the item in the list the data from the database should be displayed in the table so for first item it is working for second one the table is not updating for ex:if i click on the first item the data is of three columns and for second item the data is of four columns i am getting array index out of bounds exceptions
so that is the problem i am facing
Thanks in advance
Hi revanth,
I doubt you are not updating/changing the observableList of the TableView. There are two ways. One is updating your existing observableList or making new ObsevableList everytime you want to update.
When you want whole table data and column(s) to be changed then you would probably need to use setItem() every time for update.
If you want to update only small rows update changes on table then you can simply update the items ObservableList of the TableView. For this you don’t need to use any explicit update command. Java FX automatically handles the update on ObservableList and refreshes the TableView.
Thanks
Hi,
Thanks for your post, very usefulf. Coming back on “revanth on August 2, 2012 – 6:22 pm ” comment
“it is getting error at the number col.setCellValueFactory(new Callback(){ &
return new SimpleStringProperty(param.getValue().get(j).toString());”
I have the same issue and not sure how to cast a SimpleStringProperty in a ObservableValue . Could you please help?
Thanks
Also, forgot to ask, what would be the equivalent if we manipulated Double instead of String?
Thanks
Are you sure that you have same code like i’ve posted in the blog
;
If you are working with some Double Data type then you can use like this. But the table column that you are working with must be same Double datatype. But I would rather suggest Number if you are working with numeric datatypes.
Thanks.
Thanks very much. It does work now, and thank you for the ObservableValue.
Perhaps a quick question regarding TableColumn, is it possible to display them horizontally or is there a way to transpose a TableView?
Thanks
@roddy,
I think you can’t do this.But you need to go deep if you want to do this.
🙂
Happy coding!
@roddy
You might want to post on the JavaFX forum. Jonathan Giles and colleagues may have plans for row headings in TableView. I would use them for crosstabs if they were available.
Thank you guys!
Hello, i m create dynamic tableview data from database h2, but i have error in showing data… jdbc driver connect so good. please help!
@eugene what is the problem actually??
Dear Narayan, i m understood with this problem. But how to create tableview with data froь jdbc connection and some column text (more than two coulmn) ?
If you want to add more column in the tableview then you can manipulate and add more Column using TableColumn Object and add them up in TableView.getColumns()
Thanks
hi!…
i am creating an enrollment system using javafx(as part of our thesis). How can you connect javafx to mysql without using any IDEs?..?.
i really need your help..
tnx..
Hi @gnohc,
We can easily connect to mysql database in our javafx project without even using the IDE. But first you must have mysql-connector jar file which must be kept in classpath while compiling your javafx sourcecode. All the packaging of your javafx files can be done from commandline using javafxpackager utility.
Thanks
Narayan
can you give the basic procedure for this..
i need the fundamental or basics steps…
thank you…!!!
hi gnohc,
Firstly you must have basic concept of how to compile javafx files. You can google for this. Now to compile your javafx classes which contains the codes of jdbc to mysql connector then here is step.
Suppose your class “DBConnect.java” has the code of jdbc to mysql then you need to add mysql java connector jar file from mysql website.
Here I’ve supposed that jfxrt.jar and mysql-connector-java-5.1.17-bin.jar is in your same directory or on CLASSPATH environment.
In above step i’ve compiled DBConnect.java using classpath library of mysql connector and javafx lib. This way you can make javafx + mysql using commandline.
Thanks
From database i am getting huge data(65000)rows.while displaying in table view its get problem.It displaying fine upto 200/300 then it stops & giving exception.without pagination can u help me?
Thanks in advance
Hi @salamat,
Usually the tableview support many thousands of rows so smoothly . I think there must be some mistake going on in your code may be.
Thanks
Dear Mr. Narayan,
How do you update the TableView back into the database. What I am trying is getting the recordset into the TableView and then manipulating it, editing, deleting some, or adding new records etc and after that I want to save this TableView data into the database table and effect only the changes that have taken place on the tableview into the database table. Typically using this in the master detail tables.
Nice sample code for students, but not for real life !
1. If you scroll up and down many times you will have memory issues because
youe construct rows each time they are displaid.
return new SimpleStringProperty(param.getValue().get(j).toString());
2. What about “huge” tables ?
Bye
Hi,
Nice work. But how would you modify this to register when a cell has been clicked on and output a message in response?
Any guidance? I’ve been trying to do this for days….
Hi,
Seems like a good example, but I wonder how to do in a slightly different case; I have data with many columns (it’s a restaurant Menu) and would like to display only three columns in a table (food name, price and category) and then the rest of the information displayed in textboxes when a row in the table is selected, but how would you go on choosing three specific columns and then get the rest of the information connected to this row (the rest of the columns) if there are no objects created?
Thank you very much in advance!
@Therese
I think it is not so hard to implement unless you use
tableView.getSelectionModel()
of TableView.Thanks
Narayan
Hello sir! I hope you can help me with this problem. How would you display HashSet values in a tableview. I have a small program that uses Hibernate 1-to-many annotation. I have no problem displaying data from the parent table into tableview but I don’t know how to display the child table data in the other columns of the same tableview. I tried googling for answers but I can’t find any. Thank you very much sir for any feedback.
Hello sir,
I have create tableview using javafx scene builder and now i want to load data from database consist of 3 column into tableview.
I have used your code and it runs successfully but now i want to load same data in my newly created fxml file.
I need your suggestion in which code i am missing or which line i have to adjust.
I am new to javafx.
Thank you very much for your help in advance.
@Rey
To add columns as per your need you can use this code:
TableColumn myNewCol = new TableColumn("New Col");
//Add your cell factory for this column
tableView.getColums().add(myNewCol);
Thanks
@Tarun, element inside FXML
To load up from FXML you need to first create
after that you can create a variable named “myTable” in your FXMLController with @FXML annoted .
Now use your normal Java knowledge for manipulating your tableview in initialize() function.
Thanks
Narayan
@ Narayan G. Maharjan
Thank you for your reply.
I have done this and now i am able to see tableview created in fxml file.
Now i have new question, if i wan to add image node to this fxml file from java how can i achieve this.
Image i = new Image(“file:C:\\Users\\Tarun\\Desktop\\Close-icon.png”);
close = new ImageView();
close.setImage(i);
close.setFitHeight(20);
close.setFitWidth(20);
close.setX(570);
close.setY(10);
Parent root = FXMLLoader.load(getClass().getResource(“table.fxml”));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
how can i add this node.
thank you for your help.
Kind Regards,
Tarun Patel
Hi tarun, You should use in this way.
<ImageView fitHeight="39.0" fitWidth="193.0" preserveRatio="true">
<image>
<Image url="@logo.png" />
</image>
</ImageView>
Thanks.
Narayan
Hi Sir,
How to set TableColum to right position
thx
Please use the cellFactory of TableColumn for setting the Alignment of every cells of the TableColumn. Small workthrough is here:
Thanks
Narayan
Gracias por la explicación, me gustaría saber como puedo personalizar los títulos de la tabla?
Thanks for the explanation, I would like to know how I can customize the titles of the table?
@Nelson
Have you tried
TableColumn col = new TableColumn("TABLE HEADER 1");
?Narayan G. Maharjan
Ya lo solucione. El código me quedó de está manera:
String[] titulos = {
“Codigo”,
“Nombre”,
“Precio”,
“Categoria”,
“Subcategoria”,
“Marca”
};
for (int i = 0; i < rs.getMetaData().getColumnCount(); i++ ) {
final int j = i;
col = new TableColumn(titulos[i]);
col.setCellValueFactory(new Callback<CellDataFeatures,ObservableValue>(){
public ObservableValue call(CellDataFeatures param) {
return new SimpleStringProperty((String)param.getValue().get(j));
}
});
tablaProducto.getColumns().addAll(col);
// col.setStyle(“-fx-background-color:red; -fx-arc-width:200px;”);
col.setMinWidth(60);
System.out.println(“Column [“+i+”] “);
}
Gracias de nuevo! do not speak English
To solve that error try instead return new SimpleStringProperty(param.getValue().get(j).toString()); line 50 put return new SimpleObjectProperty(param.getValue().get(j));
thank you for your best tutorial
Hi its working but how may i select specific columns from database, to table.
@Josua , It depends up on your SQL command like “SELECT id,name FROM CUSTOMER” then it will only show up the specific column.
Hi, can somebody help me to load data using a tableview that was created on an fxml file. I’ve tried but it shows me an empty table, I can see the rows but the data is not displayed. I tried using different things and now it shows me an error in this line> data.add(row);
Here is some of my code. Please help me, I’m a begginer
private ObservableList data;
@FXML private TableView table;
@FXML private TableColumn nameCol;
@FXML private TableColumn emailCol;
public void initialize(URL location, ResourceBundle resources) {
nameCol.setCellValueFactory(new PropertyValueFactory(“name”));
emailCol.setCellValueFactory(new PropertyValueFactory(“email”));
buildData();
}
public void buildData() {
Connection c ;
data = FXCollections.observableArrayList();
try{
c = DBConnect.connect();
String SQL = “SELECT * from USER”;
ResultSet rs = c.createStatement().executeQuery(SQL);
while(rs.next()){
//Iterate Row
ObservableList 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);
}
tableview.setItems(data);
}catch(Exception e){
e.printStackTrace();
System.out.println("Error on Building Data");
}
}
@Andre,
refer to this link : https://blog.ngopal.com.np/tiny-forum/?mingleforumaction=viewtopic&t=2.0
@Narayan
Thank you, you helped me with my problem 🙂
col.setCellValueFactory(new Callback<CellDataFeatures,ObservableValue>(){
public ObservableValue call(CellDataFeatures param) {
return new SimpleStringProperty(param.getValue().get(j).toString());
}
});
in this i recive java.lang.Null Point Exception
Pls Help me
Type your comment here
Hi Sagar,
Make sure that your param is not null and check param.getValue() is not null and finally check param.getValue().get() not null;
Dear Narayan Gopal Maharjan,
Your demo looks very useful with me, but could you make edit data on tableView with this case?