This tutorial shows how to deal with NatTable states and persisting them.
This tutorial is based on Nebula NatTable 1.5.0.
1. State Persistence
NatTable supports persisting and restoring its state.
This is done via implementations of the IPersistable
interface.
Every class that implements this interface needs to provide methods for saving and loading the states it provides.
These methods are:
void saveState(String, Properties)
void loadState(String, Properties)
Looking at the method parameters you will notice that the persistence mechanism in NatTable is implemented by using java.util.Properties
.
Therefore every state needs to be persisted as a key-value-pair, where values need to be Strings.
This first parameter is the state key prefix, which can be used to handle multiple state sets in one Properties
object.
The second parameter is the Properties
object to which the states should be added.
All layers that support saving their states implement the IPersistable
interface by default.
It is also possible to register custom IPersistable
implementations with any layer using ILayer#registerPersistable()
.
These implementations will also be handled automatically on saving and loading NatTable states.
The following picture shows the process on saving a state with default layer and custom IPersistable
implementations.
Settings that can be persisted using the persistence mechanism in NatTable include, but are not limited to the following:
-
Visible state of columns (
ColumnHideShowLayer
) -
Column order (
ColumnReorderLayer
) -
Column/Row size (
DataLayer
) -
Sorting state (
SortHeaderLayer
) -
Freeze state (
CompositeFreezeLayer
) -
Column group state (
ColumnGroupModel
) -
Filter row state (
FilterRowDataProvider
) -
Styles that are applied using the
DisplayColumnStyleEditor
The persistence mechanism will only gather the states in memory, within the provider Properties
object.
If these settings should be persisted in the file system or a database, this needs to be implemented additionally.
The NatTable
class also implements the IPersistable
interface to trigger the state processing.
A typical code block for saving a NatTable state to a file could look similar to the following code snippet:
Properties myState = new Properties();
natTable.saveState("", myState);
try (FileOutputStream tableStateStream =
new FileOutputStream("myState.properties")) {
myState.store(tableStateStream, null);
} catch (IOException e) {
e.printStackTrace();
}
To support multiple state sets that can be even changed at runtime, there are two options.
. either create a new Properties
object for every state that should be persisted
. make use of the prefix mechanism
The first approach supports a clean separation of state sets even on the file level.
The disadvantage is that this leaves you to deal with the state management yourself.
The second approach will manage all state sets within one Properties
object.
The separation of state sets is done via state prefixes as explained initially.
The state prefix will be prepended to every key that is stored by calling IPersistable#saveState(String, Properties)
or loaded via IPersistable#loadState(String, Properties)
.
When adding additional states by implementing the |
2. View Configuration Management
Since Nebula NatTable 1.0.0 there is a convenience persistence dialog for managing multiple state sets. In this context state sets are called view configurations, which is a more user friendly notation than the more technical state set. The persistence dialog mainly supports creating and loading view configurations and can be added to a NatTable by adding the appropriate menu item and command handler to a menu. The following code will add the menu item to the column header menu and the command handler for opening the dialog to the grid layer of the NatTable instance:
// add the necessary action to the column header
// menu of the default HeaderMenuConfiguration
natTable.addConfiguration(
new HeaderMenuConfiguration(natTable) {
@Override
protected PopupMenuBuilder createColumnHeaderMenu(NatTable natTable) {
return super.createColumnHeaderMenu(natTable)
.withStateManagerMenuItemProvider();
}
});
// register the necessary command handler
// to the grid layer of the NatTable instance
DisplayPersistenceDialogCommandHandler handler =
new DisplayPersistenceDialogCommandHandler();
gridLayer.registerCommandHandler(handler);
After selecting the menu item out of the column header menu a dialog will show up, giving the user the opportunity to save the current active state set as a new view configuration with a custom name. This view configuration can be reloaded afterwards or even deleted, to give a user the flexibility to change the view of a table on simple clicks. The list of view configuration will also indicate the current active view configuration with a leading asterisk �*�.
PersistenceDialog
for managing view configurationsThe dialog does not support choosing an empty name for a view configuration.
This is related to the prefixing and a supported convenience functionality.
If you create the DisplayPersistenceDialogCommandHandler
instance with the NatTable instance it should be attached to as parameter, the initial view configuration without any user modifications will be stored as the default configuration.
This default configuration is not editable by the user and provides the functionality to always be able to return to the initial default view configuration.
To make use of storing the default configuration in the view configuration management, you need to register the |
To open the dialog in another way than by a header menu, it is also possible to execute the DisplayPersistenceDialogCommand
via NatTable#doCommand()
programmatically.
This enables you for example to add a command to the toolbar of your application that opens the dialog, rather than a popup menu on the table itself.
PersistenceDialog
programmaticallyButton viewConfigButton = new Button(buttonPanel, SWT.PUSH);
viewConfigButton.setText("View Configuration");
viewConfigButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
natTable.doCommand(new DisplayPersistenceDialogCommand(natTable));
}
});
It is also possible to listen for changes on view configurations within the PersistenceDialog
, like adding, removing or changing a view configuration.
To do this you need to register listeners of type IStateChangeListener
to the DisplayPersistenceDialogCommandHandler
.
On opening a new dialog, the listeners will be registered to the dialog, so you can be informed about view configuration changes outside the dialog.
DisplayPersistenceDialogCommandHandler handler =
new DisplayPersistenceDialogCommandHandler(natTable);
handler.addStateChangeListener(new IStateChangedListener() {
@Override
public void handleStateChange(StateChangeEvent event) {
//do something on state change
}
});
There is also API provided to manage view configurations programmatically.
The PersistenceHelper
class helps on retrieving the view configuration names and deleting a view configuration out of a Properties
instance.
This can be used for example to implement a custom dialog for view configuration management, or to for example implement a combobox to easily switch between created view configurations.
The following snippet shows how an implementation of a combobox for switching between view configurations could look like.
Composite toolbar = new Composite(panel, SWT.NONE);
// create the command handler with a Properties object
Properties natTableState = new Properties();
DisplayPersistenceDialogCommandHandler handler =
new DisplayPersistenceDialogCommandHandler(natTableState, natTable);
gridLayer.registerCommandHandler(handler);
// create a combobox for showing the available view states
Combo viewStates = new Combo(toolbar, SWT.DROP_DOWN);
viewStates.setItems(PersistenceHelper
.getAvailableStates(natTableState)
.toArray(new String[] {}));
viewStates.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
int index = viewStates.getSelectionIndex();
if (index >= 0) {
String selected = viewStates.getItem(index);
// load the state
natTable.loadState(selected, natTableState);
}
}
});
// add listener to update the combo on view state management changes
handler.addStateChangeListener(new IStateChangedListener() {
@Override
public void handleStateChange(StateChangeEvent event) {
viewStates.setItems(PersistenceHelper
.getAvailableStates(natTableState)
.toArray(new String[] {}));
}
});
// add button to show dialog
Button manage = new Button(toolbar, SWT.PUSH);
manage.setText("View Management");
manage.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
natTable.doCommand(new DisplayPersistenceDialogCommand(natTable));
}
});
3. Links and Literature
Nothing listed.
3.1. vogella Java example code
If you need more assistance we offer Online Training and Onsite training as well as consulting