fireTableDataChanged has no effect on JTable - java

I have a problem with updating my JTable in Java Swing.
The datas I want to show changes a few times per second and I look for a efficient way to update the data in the JTable.
I used the method setModel() to update the data, and it works, BUT it has 2 drawbacks:
If the user resize the table columns in the header, then he wil get about 10 exceptions (I think because the model is no longer available because it changes a few times per second)
The information of the length of the resized column (in Pixel) get lost, every time the data (and so also the TableModel) changed.
For the TableModel i use my own model ResultSetTableModel which extends AbstractTableModel.
This ResultSetTableModel has a method setResultSet(ResultSet rs) and overwrites the method getValueAt(x,y)...
As I told if I set a new ResultSet to my ResultSetTableModel and then add it to the JTable by the method setModel(resultSetTableModel) it works, but it has the 2 drawbacks i told.
So I think I can solve this problem with the method fireTableDataChanged() but I tried many possibilities but get no change.
Do you know, where I have to place the fireevent?
At the moment I try this, but it doesn't work and I don't know why:
private ResultSetTableModel resultSetTableModel;
private DataFetcher dataFetcher;
private JTable table;
...
//works fine
public void initaialUpdateTable() {
resultSetTableModel = new CachingResultSetTableModel(dataFetcher.getRS());
table.setModel(resultSetTableModel);
}
//does not work
public void updateTable(){
resultSetTableModel.setResultSet(dataFetcher.getRS());
resultSetTableModel.fireTableDataChanged();
}
If I every times call initaialUpdateTable(), it works fine, but i want that just the data changes and not the whole model
Thanks for your answers
Michael

but i want that just the data changes and not the whole model
Hmm how can I..., there is no only one ...
1) Something that you can see in the GUI is TableView, only presentation layer, and all data are always stored in the TableModel
2) If you don't declare any TableModel, this doesn't mean that there isn't exist, still are there DefaultTableModel
3) Your private ResultSetTableModel resultSetTableModel; must extend AbstractTableModel,
4) If you'll to block any of fireXxxXxxChanged();, then no changes goes back to the TableView,
5) Basic stuff here, start with fireTableCellUpdated(row, col);
EDIT
More informations about TableModels here, here or search for ResultSetTableModel, TableFromDatabase

Sorry I don't have a concrete answer to your question, but I couldn't quite fit all that I want to say in a comment.
I used the method setModel() to update the data
You should probably stick to a single model that provides methods to modify its data. These methods should appropriately notify listeners when something has changed.
Here's a really awesome article that shows how to implement a high-performance, multi-threaded table with frequently changing data. You could probably use a lot of the example source code.
How to Create Frequently-Updated JTables that Perform Well

Related

JTable.clearSelection() vs Jtable.getSelectionModel.clearSelection() - When to use what?

I need to cancel all selections within a JTable model object. Java provides this function "clearSelection()" which does, what I need, as far as I understand.
But I am confused why this function can be called on a JTable object as well as on a selection model for a JTable object:
1) mytable.clearSelection();
2) mytable.getSelectionModel().clearSelection();
Both ways work, but I do not understand in what situation a clearSelection() of a SelectionModel (like at 2) ) would make any sense. As far as I understood SelectionModels, they are used to decide what kind of selections a JTable allows. I use the SelectionModel to only allow a Selection of exactly one row
//allow only one row to be selected
mytable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
Which way is to be preferred in what kind of situation? Is there a good reason not to use way 1?
I would be glad if anyone has some beginner friendly explanation for that. Thx in advance.
Here is the implementation of JTable#clearSelection()
public void clearSelection() {
selectionModel.clearSelection();
columnModel.getSelectionModel().clearSelection();
}
As you can see, there is two ListSelectionModel which are cleared, because you can select column and/or row and/or cell.
From Oracle tutorial :
JTable uses a very simple concept of selection, managed as an
intersection of rows and columns. It was not designed to handle fully
independent cell selections.
A ListSelectionModel handle all aspect of the selection such as which row is selected, how can we select some rows, etc... Not only the kind of selection !
More information in the Oracle JTable tutorial
Usually when you see two methods like that it is because the table will invoke the SelectionModel.clearSelection() method for you. So the table method is a convenience method.
In this case the actual code is:
public void clearSelection()
{
selectionModel.clearSelection();
columnModel.getSelectionModel().clearSelection();
}
So both the row and column selection models are cleared.

Swing MVC - Data in Model

I'm starting to learn how implement MVC pattern in swing. I have a confusion when in comes to the data in model.
In the application that I'm doing, I have several JTextFields. The data set in the fields come from JTable. I have a ListSelectionListener in my controller added to that jtable (in the view) so that when selection has changed, the data from the selected row will be reflected to the respective textfields
public void transferTableDataToFields(){
if(tblProduct.getSelectedRows().length != 0){
int selRow = tblProduct.getSelectedRow();
txtID.setText(tblProduct.getValueAt(selRow, 0).toString());
txtName.setText(tblProduct.getValueAt(selRow, 1).toString());
txtDescIn.setText(tblProduct.getValueAt(selRow, 2).toString());
txtSupplier.setText(tblProduct.getValueAt(selRow, 4).toString());
txtPrice.setText(tblProduct.getValueAt(selRow, 5).toString());
}
}
My question is, am I doing it the right way? Should I define fields in the model that corresponds to the textfields in my view, then change my code to controller setting the model's fields to values from view's jtable then let the model fire a property change notification to its listener, then let the listener call the update method in the view based on the property change event?
My problem with this approach is that, the view should have a method that will return the row selected from the jtable which I find a bit ugly.
EDIT
#trashgod this is what I'm saying.
Inside my TableModel implementation, is it better to populate the data here?
public MyTableModel extends AbstractTableModel{
List<Row> data;
Row header;
public MyTableModel(){
initializeData();
}
public void initializeData{
//query database here then put it in the list
}
//other methods to implement e.g. getvalueAt(int x, inty){data.get(x).get(y);}
}
Is it better if I make it like this? because currently I stored and populate the data of my table in my main model (also containing fields with corresponding textfields in the SelectedRow view) then I pass the data in my JTable's model.
In this case, the current selection is a property of the view, an instance of JTable, not the model, an implementation of TableModel.
If you choose to supersede editing in the JTable itself, a ListSelectionListener is the correct way to update your (anonymous) dependent view, e.g. SelectedRow. Your controller should have little to do except add SelectedRow as a listener to your JTable. As SelectedRow contains (presumably) editable fields, you are responsible for several things:
Propagate any changes back to the original table's TableModel, typically via setValueAt().
Convert between view and model coordinates, mentioned here.
Preclude (or synchronize via the ListSelectionListener) editing in the source JTable.
Addendum: Inside my TableModel implementation, is it better to populate the data here?
The answer depends on the application. Your TableModel implementation should expose a public API that provides as much (or as little) as required to support the application's requirements for concurrency and latency. For reference, DefaultTableModel is a general purpose example, although you'll want to use something more recent than Vector internally.

JTable with AbstractTableModel does not edit on click

I am constructing a JTable for an Applet that should be able to handle user edits. As such, I have extended the AbstractTableModel and have successfully populated the table with data. My problem is that once the data has been populated, clicking on the table does not allow for edits.
I have overridden the isCellEditable() method to always return true, as well as print a message to the console every time the method is invoked. However, when I interact with the table (through any number of consecutive mouse clicks on any given single cell), the cell does not become editable, and isCellEditable() never gets called either.
My question is, what needs to be called in order to edit a particular cell? I apologize for the lack of code in the post, but the code is highly proprietary, and my superiors are very strict on releasing any code.
To protect your superiors' interests, edit your question to include an sscce that exhibits the problem you describe. Several example suitable for a starting point may be found in How to Use Tables, and this example illustrates an editable AbstractTableModel. You might compare it with your implementation.
1.are you added AbstractTableModel to the JTable already visible on the screen
2.if yes then codes lines isn't isCellEditable(), but should be
#Override
public boolean isCellEditable(int row, int column) {
return true;
}
3.I'd suggest to use DefaultTableModel rather than to override required methods for AbstractTableModel

Problem in giving input to JTable from keyboard

I want to know how to give input to the cell in a jtable from keyboard.
And when I try to do this when I move on to next cell the previous enter data is removed or erased automatically.
I am using abstracttable model for creating jtable.
iam using abstracttable model for creating jtable....
and when i try to do dis when i move on to next cell the previous enter data is removed or erased automatically....
The AbstractTableModel doesn't implement the setValueAt(...) method. So unless your custom model implements this correctly you will lose the data entered in the editor.
I suggest you keep it simple and use the DefaultTableModel until you better understand how a JTable works. The code would be:
DefaultTableModel model = new DefaultTableModel(...);
JTable table = new JTable( model );
As discussed in How to Use Tables, you can specify a renderer and editor for each column in a JTable, or you can override getColumnClass() to obtain the default for any of the listed data types. In addition, you might compare what you're doing with one of the examples listed there or edit your question to include an sscce.
Sounds like you are not saving the data entered into your model. Secondly, I would suggest extending DefaultTableModel instead of AbstractTableModel unless you have a good reason.

Working with data and a JTable?

I have a JTable that I want to use to display some data (a String and a Boolean in each row). The data is maintained by my own class. Is there some way to bind the data model to the JTable, so that when I add to the model, the JTable is dynamically updated and when I remove something from the model, the row is removed from the JTable?
I have previously worked with Flex and Actionscript, and this is very easy to do there with data binding, so I'm just wondering how it's done in Java.
Thanks.
You will need to have your dataset implement the TableModel interface. if you do that then you can apply it to the JTable. If you extend AbstractTableModel you will inherit some event firing methods that your table will handle and will update the view. see this tutorial. Note that the default implementation of JTable will renderer your data for you, and if a Boolean is found, it will show up as a check box.
You'll probably find both the Java JTable tutorial and the JTable API documentation helpful in understanding how JTable works, but otherwise here's a quick rundown.
The premise of a JTable is that it is paired with an object that implements the TableModel interface, which by default is an instance of DefaultTableModel. The table model object is made up of a list of columns, each of which has its own data type (String and Boolean in your case), and a list of rows containing the actual data for the table.
Whenever the JTable is drawn by the swing drawing code, it repeatedly calls the method:
public Object getValueAt(int row, int col)
Thus, when you add data to the table model, it is always rendered as you expect in the next screen refresh (dynamically).
The only thing you really need to worry about, then, is getting the data from your object into the table model and back out again. Other than that, JTable takes care off all the heavy lifting.
While implementing TableModel is easy enough for simple cases, you might want to consider a true binding approach (my favorite is Glazed Lists - watch the 30 second video on how easy this is and you'll be won over). Beans Binding (now Better Beans Binding) also has an implementation of observable lists that might be useful (although I much prefer the Glazed Lists approach)

Categories

Resources