JTable in Swing

hi,

Good Morning,

I am using NetBeans and MS-Access to develop a simple project.

I am using JTable to store all the records from my MS-Access Database.

When I run the project all the records are stored in JTable .No Problem.

But when I insert new records ,they are not added to the JTable.But when I run the project again the recently inserted records are stored in the JTable.

Need I refresh my table?

Is any method to refresh?

or chance of any mistake in my coding?

[522 byte] By [myque-ans@soona] at [2007-10-2 10:31:37]
# 1

You can make use of the addRow(...) method from DefaultTableModel. The changes in the model will be reflected in the view. Something like this:

DefaultTableModel model = new DefaultTableModel(...);

table.setModel(model);

// insert

model.addRow(...);

> or chance of any mistake in my coding?

We don't know what went wrong with your code because you didn't post a simple executable demo program.

ajneoa at 2007-7-13 2:15:50 > top of Java-index,Desktop,Core GUI APIs...
# 2

hi,

Thank you so much for your reply.

My coding is below.But I didnot use the method of model.addRow().I am using

jTable m_table = new JTable();

m_table.addColumn(column);

column is created by me and i am using DefaultTableCellRenderer .Because I am new to java I donot know how to implement your reply in my coding.So please help me to solve.

import java.awt.*;

import java.awt.event.*;

import java.util.*;

import java.sql.*;

import javax.swing.*;

import javax.swing.event.*;

import javax.swing.table.*;

public class ss extends JFrame

{

protected JTable m_table;

protected StockTableData m_data;

protected JLabel m_title;

public ss()

{

super("Stocks Table");

setSize(600, 340);

m_data = new StockTableData();

getContentPane().add(m_title, BorderLayout.NORTH);

m_table = new JTable();

m_table.setAutoCreateColumnsFromModel(false);

m_table.setModel(m_data);

for (int k = 0; k < StockTableData.m_columns.length;k++) {

DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();

renderer.setHorizontalAlignment(StockTableData.m_columns[k].m_alignment);

TableColumn column = new TableColumn(k, StockTableData.m_columns[k].m_width,renderer,null);

m_table.addColumn(column);

}

JTableHeader header = m_table.getTableHeader();

header.setUpdateTableInRealTime(false);

JScrollPane ps = new JScrollPane();

ps.getViewport().add(m_table);

getContentPane().add(ps,BorderLayout.CENTER);

WindowListener wndCloser = new WindowAdapter()

{

public void windowClosing(WindowEvent e)

{

System.exit(0);

}

};

addWindowListener(wndCloser);

setVisible(true);

}

public static void main(String argv[]) {

new StocksTable();

}

}

class StockData

{

public String m_code;

public String m_name;

public String m_ic;

public String m_address;

public String m_phone;

public StockData(String symbol,String name, String last, String open, String change)

{

m_code = symbol;

m_name = name;

m_ic = last;

m_address = open;

m_phone = change;

}

}

class ColumnData

{

public String m_title;

public intm_width;

public intm_alignment;

public ColumnData(

String title, int width,

int alignment)

{

m_title = title;

m_width = width;

m_alignment = alignment;

}

}

class StockTableData extends AbstractTableModel

{

static final public

ColumnData m_columns[] = {

new ColumnData(

"SCODE", 100, JLabel.LEFT ),

new ColumnData(

"NAME", 150, JLabel.LEFT ),

new ColumnData(

"IC", 100, JLabel.RIGHT ),

new ColumnData(

"ADDRESS", 100, JLabel.RIGHT ),

new ColumnData(

"PHONE", 100, JLabel.RIGHT ),

};

protected Vector m_vector;

public StockTableData() {

m_vector = new Vector();

setDefaultData();

}

public void setDefaultData() {

try {

m_vector.removeAllElements();

Connection con;

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

String url = "jdbc:odbc:SERTS";

String user = "root";

String pw = "";

con = DriverManager.getConnection(url,user,pw);

Statement s = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);

String tofirst="SELECT * from [Student-File]";

ResultSet results;

results = s.executeQuery(tofirst);

boolean hasData = false;

while (results.next())

{

if (!hasData)

{

m_vector.removeAllElements();

hasData = true;

}

String scode = results.getString(1);

String sname = results.getString(2);

String address = results.getString(3);

String ic = results.getString(4);

String phone = results.getString(5);

m_vector.addElement(new StockData(scode,sname,address,ic,phone));

}

results.close();

s.close();

con.close();

}

catch (ClassNotFoundException e)

{

System.out.println (e.getMessage());

System.exit(0);

}

catch (SQLException e)

{

System.out.println (e.getMessage());

System.exit(0);

}

}

public int getRowCount() {

return m_vector==null ? 0 : m_vector.size();

}

public int getColumnCount() {

return m_columns.length;

}

public String getColumnName(int column) {

return m_columns[column].m_title;

}

public boolean isCellEditable(int

nRow, int nCol) {

return false;

}

public Object getValueAt(int

nRow, int nCol) {

if (nRow < 0 || nRow

>= getRowCount())

return "";

StockData row =

(StockData)m_vector.elementAt(nRow);

switch (nCol) {

case 0: return row.m_code;

case 1: return row.m_name;

case 2: return row.m_ic;

case 3: return row.m_address;

case 4: return row.m_phone;

}

return "";

}

public String getTitle() {

return "Stock Quotes";

}

}

Thank you so much.

myque-ans@soona at 2007-7-13 2:15:50 > top of Java-index,Desktop,Core GUI APIs...
# 3
Do you have to use AbstractTableModel?This thread (reply #3 and #8) shows examples of working with database data using the DefaultTableModel. http://forum.java.sun.com/thread.jspa?threadID=701180
ajneoa at 2007-7-13 2:15:50 > top of Java-index,Desktop,Core GUI APIs...
# 4

Hi,

I say good morning after my long holidays.

I followed the thread given by you.I followed the coding and I used it for my NetBeans Project.

When I click a button all records from my database are stored in my table.It is working well.

But I have the same broblem again that when i add a new record it is not reflected when I click the button.But I run the project again,the record is reflected.

I think I try to change the coding to NetBeans I got the problems like this.

Because from a GUI environment in NetBeans I got the jInternalFrame

and jPanel in to that.In the jPanel I pushed the jTable.

my class is

public class table

{

private DefaultTableModel model;

private Object[] ColumnNames="Scode", "Name","Ic","Address","Phone"};

public table()

{

model = new DefaultTableModel(columnNames, 0);

JTable table = new JTable(model);

JScrollPane scrollPane = new JScrollPane(table);

jPanel3.add(scrollPane);

jInternalFrame3.setVisible(true);

try {

Vector data = new Vector();

Vector row = null;

Connection con;

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

String url = "jdbc:odbc:SERTS";

String user = "root";

String pw = "";

con = DriverManager.getConnection(url,user,pw);

Statement st = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);

String sql = "SELECT * FROM [Student-File]";

ResultSet rs = st.executeQuery(sql);

ResultSetMetaData md = rs.getMetaData();

int columns = md.getColumnCount();

while (rs.next())

{

row = new Vector(columns);

for (int x = 1; x <= columns; x++ )

{

row.addElement(rs.getObject(x));

}

data.addElement(row);

}

rs.close();

st.close();

model.setRowCount(0);

for (int x = 0; x < data.size(); x++)

{

model.addRow((Vector)data.elementAt(x));

}

} catch (Exception e) { e.printStackTrace(); }

}

}

When I click the button this work should be done so I create a object to

the class table like this.

private void jButton5ActionPerformed(java.awt.event.ActionEvent evt) {

new table();

}

please tell me a way to solve this.

Thank you so much

Meena.

myque-ans@soona at 2007-7-13 2:15:50 > top of Java-index,Desktop,Core GUI APIs...
# 5
> But I have the same broblem again that when i add a new record it is not reflected when I click the button.The posted code is not compilable and not related to adding new record.Please post a simple executable demo program that demonstrates the behavior.
ajneoa at 2007-7-13 2:15:50 > top of Java-index,Desktop,Core GUI APIs...
# 6

You don't create a new table when you change the data, you create a new TableModel. eg.

DefaultTableModel model = new JTableModel();

table.setModel( model );

Here is a working example that will query you database and display information about the different tables in the database:

http://forum.java.sun.com/thread.jspa?forumID=31&threadID=619826

camickra at 2007-7-13 2:15:50 > top of Java-index,Desktop,Core GUI APIs...
# 7

Hi,

Good Evening.

Thank you so much for your reply and thread given by you.

Now I change the coding and Implement your reply

DefaultTableModel model = new JTableModel();

table.setModel( model );

But I still have the problem of my addition,deletion,updation are not reflected in my table .

My new coding is

public class table

{

public table()

{

JTable table = new JTable();

JScrollPane scrollPane = new JScrollPane(table);

jPanel3.add(scrollPane);

jInternalFrame3.setVisible(true);

try {

Vector data = new Vector();

Vector row = null;

Connection con;

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

String url = "jdbc:odbc:SERTS";

String user = "root";

String pw = "";

con = DriverManager.getConnection(url,user,pw);

Statement st = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);

String sql = "SELECT * FROM [Student-File]";

ResultSet rs = st.executeQuery(sql);

ResultSetMetaData md = rs.getMetaData();

int columns = md.getColumnCount();

Vector columnNames = new Vector(columns);

for (int i = 1; i <= columns; i++)

{

columnNames.addElement( md.getColumnName(i) );

}

while (rs.next())

{

row = new Vector(columns);

for (int x = 1; x <= columns; x++ )

{

row.addElement(rs.getObject(x));

}

data.addElement(row);

}

rs.close();

st.close();

[b]DefaultTableModel model = new DefaultTableModel(data, columnNames);

table.setModel(model);[/b] //hte new change.

} catch (Exception e) { e.printStackTrace(); }

}

}

private void jButton5ActionPerformed(java.awt.event.ActionEvent evt)

{

new table();

}

Is any problem in my coding?

please help me.

Thank you so much.

Meena.

myque-ans@soona at 2007-7-13 2:15:50 > top of Java-index,Desktop,Core GUI APIs...
# 8
You don't create a new table every time. You create the table once. Then you create a new TableModel when you want to update the table.
camickra at 2007-7-13 2:15:50 > top of Java-index,Desktop,Core GUI APIs...
# 9

> You don't create a new table every time. You create

> the table once. Then you create a new TableModel when

> you want to update the table.

You don't create a new table model everytime you want to update the table. You simply update the model. (I am guessing this is probably what you meant...just wanted to clarify for other people).

To get a new row to appear immediately the getRowCount() which is inherited from TableModel needs to return an accurate row count. I would venture to guess you are not updating your row count when you add a new record.

Make sure you override getRowCount() and make sure it returns the correct number of rows. So when you add a record, increment your row count (or just use the size of whatever data structure is holding your data...an ArrayList is probably the most common for a TableModel).

mjparmea at 2007-7-13 2:15:50 > top of Java-index,Desktop,Core GUI APIs...
# 10

> You don't create a new table model everytime you want to update the

> table. You simply update the model. (I am guessing this is probably

> what you meant...just wanted to clarify for other people).

No. I was suggesting that if you replace all the data in the table model then it is easier to replace the entire TableModel.

If you clear all the rows and then add the rows back in one at a time the table needs to repaint itself every time a row is added.

If you create a new TableModel and replace the old one then the table only repaints itself once.

In the entire scheme of things it probably doesn't make a real big difference. My main point was that the table should only ever be created once.

camickra at 2007-7-13 2:15:50 > top of Java-index,Desktop,Core GUI APIs...
# 11

Hi,

Thank you so much for your reply.

But I am still confused with jTbale and TableModel.I am afraid of JTable.

So I carefully read the Documentation.

Now I come to my problem.I do not know how can I create JTable only once.Because my instance of class table i,e new table()is in actionPerformed method of a Button.So when I click the button a table is created automatically.So I give up.

I am in NetBeans.You are a king in Java.So you know NetBeans is a GUI Envoronment.So I draw a table and put it in Scrollpane which in a JPanel and in JInternalFrame.Now I add the following coding .

But I wonder my coding is working.All insertion,deletion are reflected.

please tell my coding is ok or I broke some basic concept?

If your answer is OK then only I continue my remaining work in JTable or I have to enhance my coding.

private void jButton5ActionPerformed(java.awt.event.ActionEvent evt) {

try {

Vector data = new Vector();

Vector row = null;

Connection con;

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

String url = "jdbc:odbc:SERTS";

String user = "root";

String pw = "";

con = DriverManager.getConnection(url,user,pw);

Statement st = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);

String sql = "SELECT * FROM [Student-File]";

ResultSet rs = st.executeQuery(sql);

ResultSetMetaData md = rs.getMetaData();

int columns = md.getColumnCount();

Vector columnNames = new Vector(columns);

for (int i = 1; i <= columns; i++)

{

columnNames.addElement( md.getColumnName(i) );

}

while (rs.next())

{

row = new Vector(columns);

for (int x = 1; x <= columns; x++ )

{

row.addElement(rs.getObject(x));

}

data.addElement(row);

}

DefaultTableModel model = new DefaultTableModel(data, columnNames);

jTable1.setModel(model);

} catch (Exception e) { e.printStackTrace(); }

Serts_RegStd_View.setVisible(true);

}

Thank you so much,

Meena.

myque-ans@soona at 2007-7-13 2:15:50 > top of Java-index,Desktop,Core GUI APIs...
# 12

> My main point was that

> the table should only ever be created once.

Absolutely.

> No. I was suggesting that if you replace all the data

> in the table model then it is easier to replace the

> entire TableModel.

I am used to working with models that change gradually over time (showing statistics based on realtime events coming from a server side process written in C). So it never really dawned on me that someone would just want to replace the model with a new model all the time.

To the original poster you are writing java code but you aren't really "coding java".

Make your JTable a member variable of your class. Put your database query in its own class (data access object). Make another class that extends DefaultTableModel (or AbstractTableModel...DefaultTableModel extends AbstractTableModel and it just gives you some convenience methods to work with, like addRow).

In general, most DB access should be taken off of the event dispatcher thread and put in its own thread (so you don't block the GUI). Let the thread update your model (or obtain results back from the thread and then update your model).

In your table model just have an ArrayList (why are you using Vector?) that stores your data. When your thread is done querying the DB replace the old data in the ArrayList with the new data, have the getRowCount method return the size of the array list and then call fireTableDataChanged.

JTable's can be intimidating the first time you use them but they really are quite easy, it does most of the work for you.

mjparmea at 2007-7-13 2:15:50 > top of Java-index,Desktop,Core GUI APIs...
# 13

Hi,

Thank you so much for your detailed reply.

I understand a lot.

can you please give me a demo to understand?.Because last two weeks I am with JTable but yet I could not do it well.

But I never loss hope because of your detailed replies.

I am also trying

Thank you so much.

Meena.

myque-ans@soona at 2007-7-13 2:15:50 > top of Java-index,Desktop,Core GUI APIs...
# 14
How many demos do you need? The Swing tutorial on 'How to Use Tables" has plenty of demos.I gave you a demo in my last reply.We don't fully understand you application and your requirements. So you have to write some code yourself. We can only do so much.
camickra at 2007-7-13 2:15:50 > top of Java-index,Desktop,Core GUI APIs...
# 15

Hi,

Good Evening,

I review some demos and the last thread given by you again carefully.

I try the following coding which contains two classes one for collect database information and another for extend DefaultTableModel and override the methods in that.

I think i have to override the follwing methods to satisfy my needs

1.getRowCount();

2.getColumnCount();

3.getColumnNames();

4.getValueat();

5.isCellEditable();

I am using vector to hold the database.

I got errors in overriding methods of getValueat() and getColumnName();

I attached my coding .Please tell me how to override this two methods when i am using Vectors to hold the datas.

import java.awt.*;

import java.awt.event.*;

import java.io.*;

import java.sql.*;

import java.util.*;

import javax.swing.*;

import javax.swing.table.*;

public class datas extends JFrame

{

ResultSet rs;

ResultSetMetaData md;

Vector data = new Vector();

Vector columnNames = new Vector();

jTable table;

public datas()

{

try

{

Connection con;

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

String url = "jdbc:odbc:SERTS";

String user = "root";

String pw = "";

con = DriverManager.getConnection(url,user,pw);

Statement st = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);

String sql = "SELECT * FROM [Student-File]";

rs = st.executeQuery(sql);

md = rs.getMetaData();

int columns = md.getColumnCount();

for (int i = 1; i <= columns; i++)

{

columnNames.addElement( md.getColumnName(i) );

}

while (rs.next())

{

row = new Vector(columns);

for (int x = 1; x <= columns; x++ )

{

row.addElement(rs.getObject(x));

}

data.addElement(row);

}

table = new JTable();

JScrollPane scrollPane = new JScrollPane( table );

getContentPane().add( scrollPane );

DefaultTableModel model = new myclass();

table.setModel( model );

}

catch(Exception e)

{

System.out.println( e );

}

}

class myclass extends DefaultTableModel

{

public int getRowCount() {

return data==null ? 0 : data.size();

}

public int getColumnCount() {

return columnNames==null ? 0 : columnNames.size();

}

public String getColumnName(int column)

{

return columnNames[column];

}

public boolean isCellEditable(int nRow, int nCol)

{

return false;

}

public Object getValueAt(int nRow, int nCol)

{

return data[nRow][nCol];

}

}

public static void main(String[] args)

{

datas frame = new datas();

frame.setDefaultCloseOperation( EXIT_ON_CLOSE );

frame.pack();

frame.setVisible(true);

}

}

Thank you so much

Meena.

myque-ans@soona at 2007-7-20 20:46:43 > top of Java-index,Desktop,Core GUI APIs...
# 16

Hi,

Good Evening .

Thank you so much for your reply.

Now i am using two seperate class one for database information another for extends DefaultTableModel.In a thread I just now send my coding pointing two errors.But still i am using vectors.Because for last two week i work with vector.So trying ArrayList takes is hard because i have no basic idea about that.

Because of your replies I have confident about JTable.

Thank you so much.

Meena.

myque-ans@soona at 2007-7-20 20:46:43 > top of Java-index,Desktop,Core GUI APIs...