Updating JTable from the TCP/IP socket or other NON-interactive sources
I need to collect a lot of data from the TCP/IP socket. I have this portion working. Next, I fed data into Table and attempted to view data change, and this is where I have problems.
So I promptly read
http://java.sun.com/docs/books/tutorial/uiswing/components/table.html
and tested few examples. Most (if not all) of them have a frame with few buttons and this works like a charm. Push a button and a row is created, push another and table is sorted, and so on.
I tried an oversimplified version
...
((DefaultTableModel)table.getModel()).addRow(
new Object[] {"T", "h", "e", "E", "n", "d"}
);
int row = table.getRowCount() - 1;
table.changeSelection(row, 0, false, false);
table.requestFocusInWindow();
table.repaint();
...
and this does not working because JTable uses events to repaint on change.
Next, I come across
http://www.java2s.com/Code/Java/Swing-Components/UnionDataTableExample.htm
and this is a code I am using for testing.
This example uses Vectors but I fail to see how am I passing data to JTable object which is dynamic ( I am adding rows and populating them). I could not get it working (but continue trying...) for cotinuous update ...
There is perhaps a solution for my problem: http://www.quicktables.org and
this may be trivial but I am just trying to understand how to properly use JTable to programatically update from data source (there are undoubtly other who tried or needed it ;-)
For testing it would be sufficient to have a thread (NOT a button) which simply adds few rows with arbitrary content. SOmething like:
...
((DefaultTableModel)table.update( table.getModel()).addRow(
new Object[] {"T", "H", "E", " ", "E", "N", "D"}
);
...
Thanks for suggestions,
Pete_j
PS. This is one of the most impressive sites with Swing examples
http://www.crionics.com/products/opensource/faq/swing_ex/SwingExamples.html
Message was edited by:
Pete_j
Message was edited by:
Pete_j
Message was edited by:
Pete_j
[2156 byte] By [
Pete_ja] at [2007-11-27 1:30:30]

# 1
Is your issue potentially related to threading? The simplistic examples in the tutorial and your program are somewhat similar:
- a user presses button which is an event so an event handler is called which adds a row to the database
- data comes in on the socket; also an event which can be handled by an event handler; can you then just add a row to the table?
Well, the data on the socket is not a UI event so it is not running on the Event Dispatch thread, so the call to add a row to the table should use SwingUtilities.invokeLater.
If you can, post the code sections that create the table and then also the code that attempts to add a row to the table.
# 2
On the other hand, this simulates a non-interactive process creating rows in a table and seems to work fine:
class Testing extends JFrame {
String colNames[] = { " string1 ", "String2", "String2" };
Object[][] data = { { "asdf", "qwer", "xcvb" }, { "rweq", "qwer", "rewq" },
{ "zxcv", "zxdcv", "zxcv" } };
DefaultTableModel dtm;
JTable table = null;
public Testing() {
setLocation(50, 50);
setDefaultCloseOperation(EXIT_ON_CLOSE);
DefaultTableModel dtm = new DefaultTableModel(data, colNames);
table = new JTable(dtm);
JScrollPane sp = new JScrollPane(table);
JPanel pnl = new JPanel();
getContentPane().add(sp);
getContentPane().add(pnl, BorderLayout.SOUTH);
pack();
start();
}
public static void main(String[] args) {
new Testing().setVisible(true);
}
public void start() {
Runnable runner = new Runnable() {
public void run() {
while (true) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
((DefaultTableModel) table.getModel()).addRow(new Object[] {
"gfsd", "asdf", "gsd" });
int row = table.getRowCount() - 1;
table.changeSelection(row, 0, false, false);
}
}
};
new Thread(runner).start();
}
}
It does violate some of the things we look for in a gui as the UI is being created and updated from a thread other than the event dispatch thread, but it might give us a starting point to talk about what your are trying to do.
# 3
Thanks for the reply. It works and I will use it to simplify what I have already written. Nice.
Since I rarely venture into GUI writing and hence the problem, I am taking this as an opportunity to ask you about few points in your reply that I would like to follow on:
You have suggested to use. SwingUtilities.invokeLater . In my app I have a number of threads, one of them is scanning the socket until is syncs with a header keys (it is a radio app so it waits for a datagram) . Once detected (there are losses and short packets are not unusual) it parses a datagram, resolves problems and places the content of fields into an Object[] data for JTable to display. Not too much work.
In case I would like follow your suggestion and use Swing, where would be a good place to place SwingUtilities.invokeLater? Any mechanism to co-register events from socket and do some "load balancing"? And finally, this would probably require defining some events to keep refreshing the window. Something like:
...
public void setValueAt(Object[] value, int row) {
Vector rowVector = (Vector) dataVector.elementAt(row);
rowVector.setElementAt(value, row);
TableModelEvent event = new TableModelEvent(this, row);
fireTableChanged(event);
this.fireTableChanged(event);
}
...
Thanks for your help
Paul_j