Fetching column name with table from database - java

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.

Related

tableModel.addRow() not showing anything in JTable but row object has values

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.

Add vector to existing jTable to show records in database

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

Using PreparedStatement to sort records in MySQL

Im trying to write a code in which when a user will click an a "Sort by Name" button, my program will sort the records of my Database and put them in a JTable,combining 2 DB Tables with INNER JOIN. I have managed to do this by using a resultSet and selecting for example Ascending Order. But because I dont want to have 2 buttons, one for the ASC and one for the DESC, I thought of using preparedStatement and an showInputDialog in which the user will select if he wants to have an ASC or a DESC ordering and execute the order. Also, I remembered that some programs I've seen used a feature in which the first time you clicked the button it sorted DESC and if you pressed it again would order by ASC(havent managed to find in on the WEB).About my first thought, I tried to do it but I could get past this one
ResultSetMetaData mdsort = rssort.getMetaData();
I should have an ResultSet variable(rssort) to use getMetaData() but if I selected to make the program with my PreparedStatement i would get an error there. Any suggestions??
try{
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/test1?user=me&password=12345");
Statement stmtsort = conn.createStatement();
ResultSet rssort = stmtsort.executeQuery("SELECT * FROM consoles INNER JOIN hardware ON consoles.id=hardware.id ORDER BY consoles.name ASC");
// ERROR HERE!!! needs resultset,not preparedStatement
ResultSetMetaData mdsort = rssort.getMetaData();
columnCount = mdsort.getColumnCount();
String[] colssort = new String[columnCount];
for (i=1;i<= columnCount;i++)
{
colssort[i-1] = mdsort.getColumnName(i);
}
DefaultTableModel model = new DefaultTableModel(colssort,0);
while (rssort.next())
{
Object[] rowsort = new Object[columnCount];
for (i = 1 ; i <= columnCount ; i++)
{
rowsort[i-1] = rssort.getObject(i);
}
model.addRow(rowsort);
}
JTable table = new JTable(model);
model.fireTableDataChanged();
table.setCellSelectionEnabled(true);
table.setColumnSelectionAllowed(true);
table.setFillsViewportHeight(true);
table.setSurrendersFocusOnKeystroke(true);
table.setBounds(218,59,529,360);
frame.getContentPane().add(table);
model.fireTableDataChanged();
conn.close();
stmtsort.close();
rssort.close();
} catch (SQLException case1)
{case1.printStackTrace();
} catch (Exception case2)
{case2.printStackTrace();}
}
});
UPDATE
OK I managed to fix this issue with the getMetaData() but now the thing is that I dont use any ResultSet variables/instances and cant use next() method to create my DB.
String name = "SELECT * FROM consoles INNER JOIN hardware ON consoles.id=hardware.id ORDER BY consoles.name ?";
PreparedStatement psname = conn.prepareStatement(name);
String strin = JOptionPane.showInputDialog(null,"ASC or DESC order ? : ");
psname.setString(1,strin);
psname.executeUpdate();
ResultSetMetaData mdsort = psname.getMetaData();
int columnCount = mdsort.getColumnCount();
.
.
.
// error coming up here,because i deleted the ResultSet
while (psname.next())
.
.
.
Better make a bit more complex TableModel.
That is more optimal.
Keep the data from the ResultSet in an original TableModel.
Use a wrapping TableModel to sort, and maybe filter.
Use the ResultSetMetaData for the column type, if it is Number (Integer, BigDecimal, ...) then use that type instead of Object for the column type: gives a right aligned column.
Maybe first do an internet search for ResultSetTableModel; other peoply must have done it already.
try{
conn = DriverManager.getConnection("jdbc:mysql://localhost/test1?user=me&password=12345");
String strin = JOptionPane.showInputDialog(null,"ASC or DESC order ? : ");
stmtsortname = conn.createStatement();
rssortname = stmtsortname.executeQuery("SELECT * FROM consoles INNER JOIN hardware ON consoles.id=hardware.id ORDER BY consoles.name "+strin);
mdsortname = rssortname.getMetaData();
columnCount = mdsortname.getColumnCount();
String[] colssortname = new String[columnCount];
for (i=1;i<= columnCount;i++)
{
colssortname[i-1] = mdsortname.getColumnName(i);
}
model = new DefaultTableModel(colssortname,0);
while (rssortname.next())
{
Object[] rowsortname = new Object[columnCount];
for (i = 1 ; i <= columnCount ; i++)
{
rowsortname[i-1] = rssortname.getObject(i);
}
model.addRow(rowsortname);
}
table = new JTable(model);
model.fireTableDataChanged();
table.setCellSelectionEnabled(true);
table.setColumnSelectionAllowed(true)
table.setFillsViewportHeight(true);
table.setSurrendersFocusOnKeystroke(true);
table.setBounds(146,59,763,360);
frame.getContentPane().add(table);
model.fireTableDataChanged();
conn.close();
stmtsortname.close();
rssortname.close();
} catch (SQLException case1)
{
case1.printStackTrace();
}
catch (Exception case2)
{
case2.printStackTrace();
}
}
});

How to view database resultset in Java swing

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

How to remove rows in JTable before populating new data into the table?

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

Categories