In Netbeans, I created a JTable and bound it's values to a JPA result set. This works great. The query contains a parameter which I set in the pre-create
box of the "query result" component. So just before Netbeans creates the query result I write this:
myQuery.setParameter("year", "1997");
This works fine. Now, I have an event handler which is supposed to change the parameter and display the new values in the table. So I do this:
myQuery.se开发者_如何学运维tParameter("year", "2005");
myResultList.clear();
myResultList.addAll(myQuery.getResultList());
jTable1.updateUI();
This works, but it feels wrong to me. Note: The result set is bound to the table. So I was hoping there was something like this:
myQuery.setParameter("year", "2005");
myResultList.refresh();
Is there something like this?
I finally figured it out...
The root of the problem lies in the JTableBinding class. Here's the important excerpt of the API doc:
If the List is an instance of ObservableList, then changes to the List contents (such as adding, removing or replacing an object) are also reflected in the JTable. Important: Changing the contents of a non-observable List while it is participating in a JTableBinding is unsupported, resulting in undefined behavior and possible exceptions.
And indeed, changing the list contents while it's not an observable list has weird behaviour in the resulting UI. If, for example, your initial query returns 1000 rows, and after the update the list only contains 100 rows, then the bound JTable still lets you try to scroll past the results. And the UI "hangs" for a short while.
In fact, when using JPA in Netbeans, and you use the appropriate components from the pallette, then you can easily fix this. The QueryResult
"widget" has a checkbox labelles "observable". Check this one and you're done. Now all changes to the result will be reflected automatically in the JTable. So you can simply do:
myQuery.setParameter("year", "2005");
myResultList.clear();
myResultList.addAll(myQuery.getResultList());
without doing anything else.
Yes it is wrong, you should never use updateUI(). That method is used when you do a LAF change, which you haven't.
I don't know how Netbeans binding works, but yes if the model is update then it need to notify the table so the table can repaint itself.
If the binding recreates a new TableModel, then you should do
table.setModel( theNewModel );
If the model just updates itself, then it should invoke:
fireTableDataChanged(...);
精彩评论