How to view database resultset in Java swing? My options are
jeditorpane
jtable.
After view that file i want to save the file either in .rtf or .pdf. how is this possible in Java desktop apps?
Note: Do not use third party API or libraries
Viewing your result - JTable is your best choice
Saving the results, well, unless you want to use a 3rd part library, you options are very limited, unless your very familiar with the various file formats you want to use.
Out of the box, I'd say CVS would be easy to achieve.
JTable will do best, here is the code for display ResultSet on JTable
public static void main(String[] args) throws Exception {
// The Connection is obtained
ResultSet rs = stmt.executeQuery("select * from product_info");
// It creates and displays the table
JTable table = new JTable(buildTableModel(rs));
JOptionPane.showMessageDialog(null, new JScrollPane(table)); // or can you other swing component
// Closes the Connection
}
The method buildTableModel:
public static DefaultTableModel buildTableModel(ResultSet rs)
throws SQLException {
ResultSetMetaData metaData = rs.getMetaData();
// names of columns
Vector<String> columnNames = new Vector<String>();
int columnCount = metaData.getColumnCount();
for (int column = 1; column <= columnCount; column++) {
columnNames.add(metaData.getColumnName(column));
}
// data of the table
Vector<Vector<Object>> data = new Vector<Vector<Object>>();
while (rs.next()) {
Vector<Object> vector = new Vector<Object>();
for (int columnIndex = 1; columnIndex <= columnCount; columnIndex++) {
vector.add(rs.getObject(columnIndex));
}
data.add(vector);
}
return new DefaultTableModel(data, columnNames);
}
it would be hard to export data to pdf or rtf without using 3rd party api
Related
I am using JTable in swing to display a MySQL table, although the table values are present in the row object (as in the output in screenshot) but jtable in the application is empty.
The output in the screenshot shoes the Object[] array but when I pass this in the addRow method, it doesn't show anything on the JTable GUI.
private void tableSubmitButtonActionPerformed(java.awt.event.ActionEvent evt) {
//fetch the name of the database to be created
String dbName = tableDBName.getText();
//fetch the root password
String password = new String(tableDBPass.getPassword());
// fetch table name
String tableName = tableTableName.getText();
DefaultTableModel tableModel = (DefaultTableModel)tableViewTable.getModel();
int rowCount = tableModel.getRowCount();
for(int i = 0; i<rowCount; i++){
tableModel.removeRow(0);
}
try{
// create connection
CreateConnection newCon = new CreateConnection();
Statement newStat = newCon.initiate(dbName, password);
// result set contains the data fetched from the MySQL table
ResultSet rs = newStat.executeQuery("select * from "+tableName);
// get column names and column count
ResultSetMetaData metaData = rs.getMetaData();
int n_columns = metaData.getColumnCount();
ArrayList<String> columnNames = new ArrayList<>();
for(int i = 1; i<=n_columns; i++){
columnNames.add(metaData.getColumnName(i));
}
while(rs.next()){
ArrayList row = new ArrayList(n_columns);
for(int i = 1; i<=n_columns; i++){
row.add(rs.getObject(i));
}
Object[] obj = row.toArray();
tableModel.addRow(obj);
System.out.println("table updated..: "+Arrays.toString(obj));
}
}catch(SQLException e){
System.out.println(e.getMessage());
}
}
Besides this I deleted all the rows that are initially present when you insert the JTable in the form.
DefaultTableModel tableModel = (DefaultTableModel)tableViewTable.getModel();
So you start with an empty TableModel, which means the model has no columns or rows.
So even though you invoke the addRow() method, your model has no columns so there is nothing to display in the JTable
ArrayList<String> columnNames = new ArrayList<>();
for(int i = 1; i<=n_columns; i++){
columnNames.add(metaData.getColumnName(i));
}
The above code does nothing. All it does is add some data to an ArrayList, but that ArrayList is never used.
What you want to do is:
Use a Vector, not an ArrayList
Then you need to create an empty DefaultTableModel with just the columns names. Read the API for the appropriate constructor.
Then in your logic that iterates through the ResultSet you want to:
Again use a Vector for each row of data
add the data to the Vector
invoke the addRow(...) method of the model. The model will also accept a Vector so there is no need to convert it to an array
After all the data is added to the model you then need to:
Use tableModelView.setModel(...) to replace the model in your table.
Now your table model will have both columns and rows of data.
I want to display column name row while accessing table. Here I tried this code... but only table displayed without column name.
using java eclipse and sqlite database
try
{
String query="Select * from client";
PreparedStatement pst=conn.prepareStatement(query);
ResultSet rs=pst.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
DefaultTableModel tm = (DefaultTableModel) table.getModel();
for(int i=1;i<=columnCount;i++)
{
tm.addColumn(rsmd.getColumnName(i));
}
while (rs.next())
{
String[] a = new String[columnCount];
for(int i = 0; i < columnCount; i++)
{
a[i] = rs.getString(i+1);
}
tm.addRow(a);
// tm.fireTableDataChanged();
rs.close();
pst.close();
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
You can use following code to get column names:
ResultSetMetaData metaData = rs.getMetaData();
int count = metaData.getColumnCount(); // get column count
for (int i = 1; i <= count; i++){
System.out.println(metaData.getColumnLabel(i));
}
ResultSet always contains the returned rows but not the column names.
To get the column names you can use below code.
ResultSetMetaData metadata = rs.getMetaData();
int columnCount = metadata.getColumnCount();
String column_names[] = new String[ columnCount ]; // define a array to store the column names
for (int i=0; i<=columnCount; i++) {
column_names[ i ] = metadata.getColumnLabel(i); // push column names into array
}
DefaultTableModel table_model = new DefaultTableModel( column_names, columnCount ); // create a table model based of the columns and column count
table=new JTable( table_model ); // create a new table with that model
String column_i = table.getModel().getColumnName(i);
Iterate through 'i'; as it represents the index of the column.
Cheers!
JScrollPane pane = new JScrollPane(table);
contentPane.add(table);
JscrollPane.add(table);
The above code is all confused:
First you create a scrollpane using the table (which is correct), but then you add the table to the content pane (which is incorrect). A table can only have a single parent so it gets removed from the scrollpane.
Then you try to add the table back to the scrollpane which won't work because you need to add the table to the viewport of the scrollpane, not the scrollpane directly.
So bottom line all you need is:
JScrollPane pane = new JScrollPane(table);
//contentPane.add(table);
//JscrollPane.add(table);
Edit:
First get the code working without the SQL. Use the above suggestion and then change your current code:
//table.setModel(DbUtils.resultSetToTableModel(rs));
table.setModel( new DefaultTableModel(5,5) );
This should display an empty table with 5 rows and 5 columns.
If you see the table then the problem is with your SQL, you are returning an empty ResultSet.
If you don't see the table then you have a problems somewhere else in your code.
I try to put my ResultSet data into a JTable with help of DefaultTableModel class. As a solution I found a solution on Stackoverflow but modified it a bit (not really relevant here):
public static DefaultTableModel buildTableModel(ResultSet rs) {
try {
ResultSetMetaData metaData = rs.getMetaData();
Vector<String> columnNames = new Vector<String>();
int columnCount = metaData.getColumnCount();
for (int column = 1; column <= columnCount;++column) {
columnNames.add(metaData.getColumnName(column));
}
Vector<Vector<Object>> data = new Vector<Vector<Object>>();
while (rs.next()) {
Vector<Object> vector = new Vector<Object>();
for (int columnIndex = 1; columnIndex <= columnCount;++columnIndex) {
vector.add(rs.getObject(columnIndex));
}
data.add(vector);
}
return new DefaultTableModel(data, columnNames);
} catch(SQLException e) {
e.printStackTrace();
return new DefaultTableModel(new Vector<>(), new Vector<>());
}
}
While I debugged this code I was able to see that:
ResultSet rs has data,
ColumnNames is populated,
RowCount is zero
and I think the issue is this line vector.add(rs.getObject(columnIndex));
It looks like my vector becomes empty because getObject() returns already no data.
Can someone help me with this or explains where the issue is? When I bind my generated DefaultTableModel to my JTable it is empty (no data is shown).
I recommend using the AbstractTableModel as a base. Some years ago, I found within the examples from Sun a class called JDBCAdapter.java. This class does, what you want. Search the web for this class and you will have something, that fulfills probably most of your needs. It might be a challenge, if your application should be able to write changes back to the DB, but just for displaying the table its fine.
I just found the issue short time ago: the problem was the fact that the cursor was set to last row because other methods iterated over the same ResultSet already and thus the cursor had to be set to first row again with first-method of ResultSet class.
I have developed below code,
try{
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/online_store","username","password");
if(con != null){
String query = "SELECT * FROM expense";
rs = stmt.executeQuery(query);
ResultSetMetaData rsmt = rs.getMetaData();
int c = rsmt.getColumnCount();
Vector column = new Vector(c);
for(int i = 1; i <= c; i++) { column.add(rsmt.getColumnName(i)); }
Vector data = new Vector(); Vector row = new Vector();
while(rs.next())
{
row = new Vector(c);
for(int i = 1; i <= c; i++)
{
row.add(rs.getString(i));
}
data.add(row);
}
expense_table.add(data);
// expense_table.getColumnName(null);
JOptionPane.showMessageDialog(null, "get details from database");
}
}catch(SQLException ex){
System.out.println(ex);
}
My existing table's name is expense_table. I need to display all the records from database in this table without change its structure/without creating new table.Everything is ok except showing data(rows) vector in table which is " expense_table.add(data);" line. Please tell me is there any method to to this.
I need to display all the records from database in this table without change its structure/without creating new table.
So then you don't need to access the column names from the ResultSet. You just need to add new rows of data to the JTable. So get rid of the logic that creates the "column" Vector.
//expense_table.add(data);
You can't add a Vector to a JTable. There is no method that allows you to do this so get rid of that statement.
Instead you need to add the data to the DefaultTableModel one row at a time:
//data.add(row);
DefaultTableModel model = (DefaultTableModel)expense_table.getModel();
model.addRow( row );
I'm populating data from my database into my JTable. After I add new data and press Refresh button, I want to remove the existing row displayed on table before retrieving the new data. How can I remove the existing row?
Here is the original table with data [a,1].
This is the table after I add new data [b,1] and press refresh button. The original data [a,1] is still shown in the table:
JButton refreshButton = new JButton("Refresh");
refreshButton.setBounds(188, 248, 101, 23);
panel.add(refreshButton);
refreshButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
DefaultTableModel model = new DefaultTableModel(data,columnNames);
int rowCount = model.getRowCount();
for (int x = 0; x <=rowCount; x++)
{
model.removeRow(x);
}
try
{
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/watchlist","root","root");
String sql = "SELECT * FROM watchlist";
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(sql);
ResultSetMetaData md = rs.getMetaData();
int columns = md.getColumnCount();
while (rs.next())
{
Vector row = new Vector(columns);
for (int i=1; i <= columns; i++)
{
row.addElement( rs.getObject(i) );
System.out.println( rs.getObject(i).toString());
}
data.addElement(row);
table.revalidate();
table.repaint();
panel.repaint();
} // end while
} // end try
catch (Exception e){
}
}
});
I think that I saw this question,
1) search for ResultsetTableModel / TableFromDatabase (better)
(if Database Connection (so hard and lazy action) isn't closed during Applications lifecycle)
a) replace JTable contents
b) works with embeded Db of database placed in intranet immediatelly
dis
all processes is durring EDT, then GUI waiting for SQL statement
for most code examples required to move Xxx.close to the finally block
2) most complex workaround you have to use SwingWorker, better and easiest way is to load data from Runnable#Thread
3) you can remove row(s) from TableModel,
You can either remove the row (see DefaultTableModel.removeRow)
or put the new data into a new table model, and replace the table's table model with JTable.setModel()
Upon refreshing button, call the following:
DefaultTableModel model = new DefaultTableModel(data,col);
model.removeRow(1); // first row in this case
In this case you need to manage to get the data , columns and the row count.Data is your actual data, col is the number of columns.
enter image description here
this method i used to populte data in any jTbale
it clear jtable (refresh ) jtable befor populte new data
this line cleare jatble befor populate data
mytable.setModel(new DefaultTableModel(null, colname));
public static void FilltableV(JTable mytable, String sql){
Connection con = null;
Statement Cmd = null;
ResultSet rs = null;
try {
con = DriverManager.getConnection("jdbc:mysql://localhost/alserg", "root", "");
sql="SELECT * FROM products";
Cmd=con.createStatement();
rs=Cmd.executeQuery(sql);
ResultSetMetaData rsmt=rs.getMetaData();
int colno =rsmt.getColumnCount();
Vector colname =new Vector();
DefaultTableModel mytab =new DefaultTableModel();
Vector rows =new Vector();
for(int i=1 ;i< colno;++i){
colname.addElement(rsmt.getColumnName(i));
mytab.setColumnIdentifiers(colname);
}
while (rs.next()){
rows= new Vector();
for (int j=1;j<colno;++j){
rows.addElement(rs.getString(j));
}
mytab.addRow(rows);
mytable.setModel(new DefaultTableModel(null, colname));
mytable.setModel(mytab);
}
} catch (SQLException ex) {
Logger.getLogger(products.class.getName()).log(Level.SEVERE, null, ex);
}
finally {
try {
rs.close();
Cmd.close();
con.close();
} catch (SQLException ex) {
Logger.getLogger(AlseragLang.class.getName()).log(Level.SEVERE, null, ex);
}
}
}