-
Notifications
You must be signed in to change notification settings - Fork 8
05_Styling
Every layer that has effect on visualization has it's own style configuration. For example, the SelectionLayer
has it's own style configuration telling how to render selected cells, the ColumnHeaderLayer
has it's own style configuration telling how to render the column header cells, while the NatTable itself knows the style configuration on how to render all other cells (mainly the cells in the body region of a grid). To customize the visualization of the NatTable you have to override and register your own style configuration on the specific layer itself.
The styling is configured by creating and registering Style
objects. There are several ConfigAttributes
that can be set to define a Style
:
BACKGROUND_COLOR
FOREGROUND_COLOR
HORIZONTAL_ALIGNMENT
VERTICAL_ALIGNMENT
FONT
BORDER_STYLE
-
IMAGE
(only used by theImagePainter
) -
GRADIENT_BACKGROUND_COLOR
(only used by theGradientBackgroundPainter
) -
GRADIENT_FOREGROUND_COLOR
(only used by theGradientBackgroundPainter
) -
PASSWORD_ECHO_CHAR
(only used by thePasswordTextPainter
andPasswordCellEditor
)
Theses ConfigAttributes
are defined in the CellStyleAttributes
interface and can be used like this (snippet from DefaultNatTableStyleConfiguration
):
Style cellStyle = new Style();
cellStyle.setAttributeValue(CellStyleAttributes.BACKGROUND_COLOR, bgColor);
cellStyle.setAttributeValue(CellStyleAttributes.FOREGROUND_COLOR, fgColor);
cellStyle.setAttributeValue(CellStyleAttributes.GRADIENT_BACKGROUND_COLOR, gradientBgColor);
cellStyle.setAttributeValue(CellStyleAttributes.GRADIENT_FOREGROUND_COLOR, gradientFgColor);
cellStyle.setAttributeValue(CellStyleAttributes.FONT, font);
cellStyle.setAttributeValue(CellStyleAttributes.HORIZONTAL_ALIGNMENT, hAlign);
cellStyle.setAttributeValue(CellStyleAttributes.VERTICAL_ALIGNMENT, vAlign);
cellStyle.setAttributeValue(CellStyleAttributes.BORDER_STYLE, borderStyle);
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_STYLE, cellStyle);
NatTable user cell painters to paint each cell. These painters implement the ICellPainter
interface. The default painter is the TextPainter
. NatTable comes with a bunch of painters that can be used and mixed so the NatTable gets painted the way you want.
Paints the interior of the cell using a given painter. It then goes on put some decorations around/behind the cell.
Implementing classes are:
-
TextPainter
- paints its content as text -
VerticalTextPainter
- paints its content as text vertically -
PasswordTextPainter
- specializedTextPainter
that paints echo chars for every character -
LineBorderDecorator
- paints a border around the cell -
PaddingDecorator
- puts a padding around the cell contents -
BeveledBorderDecorator
- Gives the cell a button like look by drawing a beveled border -
ImagePainter
- Paints an image into the cell. -
BackgroundImagePainter
- Paints the background of the cell it wraps using the given image -
GradientBackgroundPainter
- Paints the background of a cell in a gradient way.
You can mix and match the above painters to create your own variations without needing to write much code.
For example the following snippet from StyledColumnHeaderConfiguration
of StyledGridExample
Image bgImage =
new Image(Display.getDefault(), getClass().getResourceAsStream("column_header_bg.png"));
TextPainter txtPainter =
new TextPainter(false, false);
ICellPainter bgImagePainter =
new BackgroundImagePainter(txtPainter, bgImage, GUIHelper.getColor(192, 192, 192));
will paint something like this
As the name suggests, it paints its content as text and reads the relevant style attributes out of the IConfigRegistry
. It takes into account font, colors and alignment when it paints. There are several constructors that allow modifications to the default behaviour. So it is possible to tell the TextPainter
to wrap the text, paint the background, add spacing and/or calculate the cell size (row height, column width) dependent on the text that should be rendered and if the text should be rendered underlined and/or strikethrough.
All of the listed configurations to the TextPainter
also apply to the VerticalTextPainter
. To get familiar with the various possibilities of TextPainter
configuration, you should have a look at the TextPainter_Examples.
The ImagePainter
can be used to render an image to a cell. There are two ways to configure it:
- constructor - the
ImagePainter
is created with an image and will only render this image. - style configuration - the
ImagePainter
is created with no image, so on rendering it checks the style configuration for theIMAGE
attribute to know which image to render
Paints using a base painter and then decorates it using a second painter. For example, in the following snippet from the ButtonCellExample
new CellPainterDecorator(new TextPainter(), CellEdgeEnum.RIGHT, new ImagePainter(myImage))
will paint something like this
In order to use a custom cell painter you need to:
- Create a custom implementation of the
ICellPainter
. Normally you would be able to reuse one of the existing ones. - Apply a custom label to the cells which should use your painter.
- Register your painter in the config registry against the cell labels you applied in step 2. Custom painters are registered as
CellConfigAttributes.CELL_PAINTER
attributes.
The PercentageBarExample
shows how to use the PercentageBarCellPainter
instead of the TextPainter
in the body region of the grid. This is done by registering the new painter as shown the following snippet
configRegistry.registerConfigAttribute(
CellConfigAttributes.CELL_PAINTER,
new PercentageBarCellPainter(),
DisplayMode.NORMAL,
GridRegion.BODY);
The painter itself looks like this
public PercentageBarCellPainter() {
super(new PaddingDecorator(
new LineBorderDecorator(
new PercentageBarDecorator(new TextPainter()),
new BorderStyle())));
}
The diagram below illustrates the various parts of the cell these painters paint
NatTable supports conditional configurations by using cell labels. This way it is also possible to add conditional styling. To use conditional styling the first step is to register a label to a cell.
The following snippet from the CellConfigurationExample
shows how to register labels to certain conditions like a special value, column or row index.
//add custom cell label to cells that contain value AAA in column 2
CellOverrideLabelAccumulator cellLabelAccumulator =
new CellOverrideLabelAccumulator(gridLayer.getBodyDataProvider());
cellLabelAccumulator.registerOverride("AAA", 2, CELL_LABEL);
// Register label accumulator with the data layer
bodyDataLayer.setConfigLabelAccumulator(cellLabelAccumulator);
The snippet below shows how to implement a custom IConfigLabelAccumulator that can be used on a NatTable that shows persons and highlight rows that show females:
@Override
public void accumulateConfigLabels(
LabelStack configLabels, int columnPosition, int rowPosition) {
Person rowObject = dataProvider.getRowObject(rowPosition);
if (rowObject.getGender().equals(Person.Gender.FEMALE)) {
configLabels.addLabel(FEMALE_LABEL);
}
}
Note:
To make this work the IConfigLabelAccumulator
needs to know the IDataProvider
.
To enable conditional styling, the custom style needs to be registered in the IConfigRegistry
against the label defined before.
Style style = new Style();
// You can set other attributes here
style.setAttributeValue(
CellStyleAttributes.BACKGROUND_COLOR,
GUIHelper.COLOR_RED);
configRegistry.registerConfigAttribute(
CellConfigAttributes.CELL_STYLE, // attribute to apply
style, // value of the attribute
DisplayMode.NORMAL, // apply during normal rendering
CELL_LABEL); // apply for all cells with this label