Reputation: 13
I want to be able to render some Choice Chips inside a NatTable cell. For that I would need a custom cell painter to be able to paint the widgets. Unfortunately, I am not very experienced with NatTable painters. Of course, the first step would be to extend the abstract class which is AbstractCellPainter, but not sure what to do in the paintCell method. TIA.
I only tried creating a custom cell editor. There, it works, but I want it to show on DisplayMode.NORMAL, not in edit mode.
Upvotes: 0
Views: 48
Reputation: 4231
Implementing a NatTable Painter is actually quite straight forward. You simply need to paint using the SWT GC
. Some information on this can be found in Introduction to SWT Graphics
I am not sure if I understand correctly, as I don't really know what "Choice Chips" are. But I suppose you mean radio buttons. The following snippet for example renders three radiobuttons in a cell, where the "active" one moves each row.
public class RadioButtonPainter extends AbstractCellPainter {
private int outerCircleDiameter = GUIHelper.convertHorizontalPixelToDpi(16);
private int innerCircleDiameter = GUIHelper.convertHorizontalPixelToDpi(10);
private int innerCirclePadding = GUIHelper.convertHorizontalPixelToDpi(3);
@Override
public void paintCell(ILayerCell cell, GC gc, Rectangle bounds, IConfigRegistry configRegistry) {
// set foreground color to black
Color previousForeground = gc.getForeground();
Color previousBackground = gc.getBackground();
gc.setForeground(GUIHelper.COLOR_BLACK);
gc.setBackground(GUIHelper.COLOR_BLACK);
int active = cell.getRowIndex() % 3;
int x = bounds.x + 5;
int y = bounds.y + 2;
gc.drawOval(x, y, this.outerCircleDiameter, this.outerCircleDiameter);
if (active == 0) {
int innerX = x + this.innerCirclePadding;
int innerY = y + this.innerCirclePadding;
gc.fillOval(innerX, innerY, this.innerCircleDiameter, this.innerCircleDiameter);
}
x += this.outerCircleDiameter + 5;
gc.drawOval(x, y, this.outerCircleDiameter, this.outerCircleDiameter);
if (active == 1) {
int innerX = x + this.innerCirclePadding;
int innerY = y + this.innerCirclePadding;
gc.fillOval(innerX, innerY, this.innerCircleDiameter, this.innerCircleDiameter);
}
x += this.outerCircleDiameter + 5;
gc.drawOval(x, y, this.outerCircleDiameter, this.outerCircleDiameter);
if (active == 2) {
int innerX = x + this.innerCirclePadding;
int innerY = y + this.innerCirclePadding;
gc.fillOval(innerX, innerY, this.innerCircleDiameter, this.innerCircleDiameter);
}
// reset GC
gc.setForeground(previousForeground);
gc.setBackground(previousBackground);
}
@Override
public int getPreferredWidth(ILayerCell cell, GC gc, IConfigRegistry configRegistry) {
return (this.outerCircleDiameter * 3) + 10 + 10;
}
@Override
public int getPreferredHeight(ILayerCell cell, GC gc, IConfigRegistry configRegistry) {
return this.outerCircleDiameter;
}
}
As said this is a very simple implementation that paints the radio buttons by hand. You could also use images for example, like it is done in the CheckBoxPainter
, to simulate a more native look and feel. But then you of course need to create the corresponding images.
I actually wonder how the editing should work, as a click would probably not activate you custom editor the right way. And I am not sure how you implement the data connection, how the painter knows which radio button is active. But there it gets more complicated. And the question was only related to implementing a painter.
Upvotes: 0