In my application I have a JTable and a List.
The List : The list is populated using a JPA query. The user can re-execute the query by changing attributes in the GUI. Let's assume the query has a named parameter "year" and the user can change this. Then the following happens (simplified by leaving out exception handling):
myList.clear() mylist.addAll( myQuery.setParameter("year", 2010) )
As the list changes, the binding fires the required handlers and the table now reflects the new dataset.
The JTable :
The contents of the JTable come from a BeansBinding (more precisely a JTableBinding
). The binding source is the aforementioned list.
The query is only executed for intensive tasks. Like applying a rough filter on a huge dataset. The earlier example with the year is a good example. This will always return a manageable chunk of data to the client. Now, to have a more responsive user experience, more fine-grained filters happen in the JTable itself. This avoids unnecessary round-trips to the database.
Next, assume the following scenario: A user selects a row in the table and hit's the delete button. If the table has not been filtered the required code is straightforward (again, no error-checking, concurrency locking, and exception handlers for code simplicity):
MyObject = myList.get( myTable.getSelectedRow() );
myEntityManager.getTransaction().begin()
myEntityManager.remove( myObject )
myEntityManager.getTransaction().commit()
However : If the table is filtered on the client side, the table won't reflect the data inside the List. So getSelectedRow()
will not return an index which will map to the same entry in the List ( I have not tested this, but I beleive I am correct with this assumption? )
How best to solve this?
I've solved the problem at hand with the following:
selectedTableElement
which contains a member holding the element which is currently selected in the table. Next, I created a new binding (source: my table, target: my "selectedElement" bean) using
binding = Bindings.createAutoBinding(UpdateStrategy.READ_WRITE, myTable, ELProperty.create("${selectedElement}"), selectedTableElement, BeanProperty.create("selectedElement"), "selectedElementBinding");
This solution effectively solves the problem by keeping track of the selected element of the table using Beans Binding.
But is this really necessary? It feels clunky to me. A whole new class only the encapsulate the selected element? Is there no other, more direct way of retrieving the "${selectedElement}"
property of the JTable
?
I'll try to answer to both your questions.
Regarding the first question (the filtered selected index vs the real list index):
createJTableBinding
. So, the client-side filtering might be applied through the use of swing TableRowSorter and RowFilter. Am I right ? if so, you could use the method int row = myTable.convertRowIndexToModel(myTable.getSelectedRow());
For the second question (bean to keep the selected item of table)
this
as the source/target object, and create a property selectedElement
in the class containing the table. Thus, you won't need another class. The code will be : createAutoBinding(UpdateStrategy.READ_WRITE, myTable,
ELProperty.create("${selectedElement}"), this, BeanProperty.create("selectedElement"), "selectedElementBinding");
createAutoBinding(UpdateStrategy.READ_WRITE, myTable,
ELProperty.create("${selectedElement}"), this, BeanProperty.create("selectedElement"), "selectedElementBinding");
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.