NatTable - dynamic scaling enhancements
The last weeks I worked on harmonizing the scaling capabilities of NatTable. The first goal was to provide scaled versions of all internal NatTable images. This caused an update of several NatTable images like the checkbox, that you will notice in the next major release. To test the changes I implemented a basic dynamic scaling, which by accident and some additional modification became the new zoom feature in NatTable. I will give a short introduction to the new feature here, so early adaptors have a chance to test it in different scenarios before the next major release is published.
To enable the UI bindings for dynamic scaling / zooming the newly introduced ScalingUiBindingConfiguration
needs to be added to the NatTable.
natTable.addConfiguration( new ScalingUiBindingConfiguration(natTable));
This will add a MouseWheelListener
and some key bindings to zoom in/out:
- CTRL + mousewheel up = zoom in
- CTRL + mousewheel down = zoom out
- CTRL + ‘+’ = zoom in
- CTRL + ‘-‘ = zoom out
- CTRL + ‘0’ = reset zoom
The dynamic scaling can be triggered programmatically by executing the ConfigureScalingCommand
on the NatTable instance. This command already exists for quite a while, but it was mainly used internally to align the NatTable scaling with the display scaling. I have introduced new default IDpiConverter
to make it easier to trigger dynamic scaling:
DefaultHorizontalDpiConverter
Provides the horizontal dots per inch of the default display.DefaultVerticalDpiConverter
Provides the vertical dots per inch of the default display.FixedScalingDpiConverter
Can be created with a DPI value to set a custom scaling.
At initialization time, NatTable internally fires a ConfigureScalingCommand
with the default IDpiConverter
to align the scaling with the display settings.
As long as only text is included in the table, registering the ScalingUiBindingConfiguration
is all you have to do. Once ICellPainter
are used that render images, some additional work has to be done. The reason for this is that for performance and memory reasons the images are referenced in the painter and not requested for every rendering operation. As painters are not part of the event handling, they can not be simply updated. Also for several reasons there are mechanisms that avoid applying the registered configurations multiple times.
There are three ways to style a NatTable, and as of now this requires three different ways to handle dynamic scaling updates for image painters.
AbstractRegistryConfiguration
This is the default way that exists for a long time. Most of the default configurations provide the styling configuration this way. As there is no way to identify which configuration registersICellPainter
and how the instances are created, theScalingUiBindingConfiguration
needs to be initialized with an updater that knows which steps to perform.natTable.addConfiguration( new ScalingUiBindingConfiguration(natTable, configRegistry -> { // we need to re-create the CheckBoxPainter // to reflect the scaling factor on the checkboxes configRegistry.registerConfigAttribute( CellConfigAttributes.CELL_PAINTER, new CheckBoxPainter(), DisplayMode.NORMAL, "MARRIED"); }));
- Theme styling In a
ThemeConfiguration
the styling options for a NatTable are collected in one place. In the previous state theICellPainter
instance creation was done on the member initialization which was quite static. Therefore theICellPainter
instance creation was moved to a new method namedcreatePainterInstances()
, so the painter update on scaling can be performed without any additional effort. For custom painter configurations this means that they should be added to a theme viaIThemeExtension
.natTable.addConfiguration( new ScalingUiBindingConfiguration(natTable)); // additional configurations natTable.configure(); ... IThemeExtension customThemeExtension = new IThemeExtension() { @Override public void registerStyles(IConfigRegistry configRegistry) { configRegistry.registerConfigAttribute( CellConfigAttributes.CELL_PAINTER, new CheckBoxPainter(), DisplayMode.NORMAL, "MARRIED"); } @Override public void unregisterStyles(IConfigRegistry configRegistry) { configRegistry.unregisterConfigAttribute( CellConfigAttributes.CELL_PAINTER, DisplayMode.NORMAL, "MARRIED"); } }; ThemeConfiguration modernTheme = new ModernNatTableThemeConfiguration(); modernTheme.addThemeExtension(customThemeExtension); natTable.setTheme(modernTheme);
- CSS styling The CSS styling support in NatTable already manages the painter instance creation. The only thing to do here is to register a command handler that triggers the CSS apply operation actively. Otherwise the images will scale only on interactions with the UI.
natTable.registerCommandHandler( new CSSConfigureScalingCommandHandler(natTable));
I have tested several scenarios, and the current state of development looks quite good. But of course I am not sure if I tested everything and found every possible edge case. Therefore it would be nice to get some feedback from early adopters if the new zoom feature is stable or not. The p2 update site with the current development snapshot can be found on the NatTable SNAPSHOTS page. From build number 900 on the feature is included. Any issues found can be reported on the corresponding Bugzilla ticket 560802.
Please also note that with the newly introduced zooming capability I have dropped the ZoomLayer
. It did only increase the cell dimensions but not the font or the images. Therefore it was not functional (maybe never finished) IMHO and to avoid confusions in the future I have deleted it now.