The EntityTableModel provides a table representation of entities: the items fetched by its EntityQueryModel, a selection and an editModel for editing them.
Every EntityTableModel contains an EntityEditModel instance — a default one is created automatically unless one is supplied via a constructor argument.
public class CustomerTableModel extends SwingEntityTableModel {
public CustomerTableModel(EntityConnectionProvider connectionProvider) {
super(new CustomerEditModel(connectionProvider));
}
}
public class CustomerAddressTableModel extends SwingEntityTableModel {
public CustomerAddressTableModel(EntityConnectionProvider connectionProvider) {
super(CustomerAddress.TYPE, connectionProvider);
}
}
1. Items, selection and query
items().refresh() populates the table by running the query model's query — the condition, attributes, order by and limit it is configured with. selection() provides the selected items and indexes as observable values, which is what selection-scoped controls bind their enabled state to, and what master models propagate to their detail models.
When entities of the table’s type are inserted, updated or deleted anywhere in the application, the table model reacts: updated rows are replaced in place, deleted rows removed, and inserted entities added according to the onInsert() strategy — prepended by default, appended, or ignored.
2. Application logic
Operations on the selected rows belong in the table model, keeping the UI layer free of business logic. Here a database function raises the price of the selected tracks, and the updated entities are reconciled back into the table with replace():
public final class RaisePriceTask implements ResultTaskHandler<Collection<Entity>> {
private final BigDecimal increase;
private RaisePriceTask(BigDecimal increase) {
this.increase = increase;
}
@Override
public Collection<Entity> execute() throws Exception {
Collection<Long> trackIds = Entity.values(Track.ID, selection().items().get());
return connection().execute(Track.RAISE_PRICE, new RaisePriceParameters(trackIds, increase));
}
@Override
public void onResult(Collection<Entity> result) {
replace(result);
}
}
The task above is a ResultTaskHandler, prepared by the model and executed by the UI on a background thread, with the result applied on the UI thread.
Functions returning new entities follow the same pattern — here wrapped in a transaction:
public Entity createRandomPlaylist(RandomPlaylistParameters parameters) {
EntityConnection connection = connection();
return transaction(connection, () -> connection.execute(Playlist.RANDOM_PLAYLIST, parameters));
}