Cell colors in a GWT CellTable - gwt

I'm using a CellTable and would like to programatically change the background color of certain cells in some situations. I tried it with an Custom Cell as described in the documentation and changed the background color with
sb.appendHtmlConstant ("<div style=\"background-color:blue;\">");
sb.append (safeValue);
sb.appendHtmlConstant ("</div>");
This basically works, but seems to be quite slow. Is there a better way to do this?

Actually you can Override getCellStyleNames() and return the wanted style for the cell
TextColumn<Composant> nameColumn= new TextColumn<Composant>() {
#Override
public String getCellStyleNames(Context context, Composant object) {
return "styleName";
}
#Override
public String getValue(Composant object) {
return object.getName();
}
};

Related

updating GWT(GXT) Buttoncell in a grid at runtime

I am creating a button cell in GXT Grid,
and adding the cell in my grid column like this
myCol.setCell(getButtonCell());
Now all cells are drawn , after that depends on the server call i want to update my cell with a new Value of MyDTO.
So on my RPC success , I want to call this render for all of my cells and update there values.
How can i achieve this.
public ButtonCell<MyDTO> getButtonCell()
{
ButtonCell<MyDTO> cellTest = new ButtonCell<MyDTO>()
{
#Override
public void render(Context context, MyDTO value, SafeHtmlBuilder
sb)
{
sb.appendHtmlConstant(value.getName());
}
A Sencha GXT grid uses a ListStore. To show new data inside the grid, the store needs to be updated. This can be done by calling store.addAll(theNewDataList). Keep in mind to clear the store before adding new values.
Updating the store will force the grid to redraw. During the redraw, the render-method of the ButtonCell will be called. To change the layout of the button, implement inside the render-method what you want to do.
This is an example from the Sencha GXT Explorer (https://examples.sencha.com/gxt/examples/#ExamplePlace:grid_aggregationgrid):
final NumberFormat numberFormat = NumberFormat.getFormat("0.00");
changeColumn.setCell(new PropertyDisplayCell<Double>(new DoublePropertyEditor(numberFormat)) {
#Override
public void render(com.google.gwt.cell.client.Cell.Context context, Double value, SafeHtmlBuilder sb) {
String style = value < 0 ? "red" : "green";
sb.appendHtmlConstant("<span style='color:" + style + "'>");
super.render(context, value, sb);
sb.appendHtmlConstant("</span>");
}
});
In case the value is less than 0 it will render a red string otherwise a green one.
Hope that helps.

JavaFX8 TreeTableView notifications for scrolled items

I am writing an application that is using a JavaFX8 TreeTableView. The tree table has three columns, two of which are String properties (name and value) and one which has a Canvas widget in it that draws a picture from from data from a database (waveforms). There is also a control on the application that allows the display (of all of the drawings) to be zoomed out or in (or for that matter scrolled left and right).
The name and value columns use StringProperty values from my data model so there are CellValueFactory set for those columns. The drawing column uses both a CellFactory and CellValueFactory like this:
// Waveform column
TreeTableColumn<DrawRow, WaveformTraceBox> waveColumn = new TreeTableColumn<>();
waveColumn.setCellFactory(new Callback<TreeTableColumn<DrawRow, WaveformTraceBox>, TreeTableCell<DrawRow, WaveformTraceBox>>() {
#Override
public TreeTableCell<DrawRow, WaveformTraceBox> call(TreeTableColumn<DrawRow, WaveformTraceBox> param) {
return new WaveformTraceBoxTreeTableViewCell<>();
}
});
waveColumn.setCellValueFactory(new Callback<TreeTableColumn.CellDataFeatures<DrawRow, WaveformTraceBox>, ObservableValue<WaveformTraceBox>>() {
#Override
public ObservableValue<WaveformTraceBox> call(TreeTableColumn.CellDataFeatures<DrawRow, WaveformTraceBox> param) {
return new ReadOnlyObjectWrapper<>(new WaveformTraceBox());
}
});
Where WaveformTraceBoxTreeTableViewCell is:
protected static class WaveformTraceBoxTreeTableViewCell<T> extends TreeTableCell<DrawRow, T> {
public WaveformTraceBoxTreeTableViewCell() {
super();
}
#Override
protected void updateItem(T value, boolean empty) {
super.updateItem(value, empty);
setText(null);
setGraphic(null);
if (!empty && getTreeTableRow().getItem() != null) {
getTreeTableRow().getItem().setTraceBox((WaveformTraceBox)value);
setGraphic((WaveformTraceBox) value);
}
}
DrawRow is my data model. When the user zooms out or in via the controls on the window the draw row model will notify it's associated Canvas drawing item to re-draw its display. The drawing of the display can take some time to do because of the large amount of data that needs to be processed to generate the display.
Now my problem: As the TreeTableView widget is scrolled it will ask for new Canvas widgets -- which get associated with DrawRow items from the data model. However widgets from the list that get scrolled off the screen will get thrown away by the tree widget.
I have found no way to tell if the item I am working with has been thrown away or is not being used any more. So the code is doing much more work than it needs to because it is trying to draw cells that are no longer being used or shown. Eventually this will cause other problems because of garbage collection I think.
So my real question is how can I tell if a cell has been abandoned by the tree table so I can stop trying to update it? Any help with this would greatly be appreciated. I am not able to find this anywhere on the various web searches I have done.
Do you need to worry here? What is still "drawing cells that are no longer being used"? Are you running some kind of update in a background thread on the WaveformTraceBox?
In any event, you've structured this pretty strangely.
First, (less important) why is your WaveformTraceBoxTreeTableViewCell generic? Surely you want
protected static class WaveformTraceBoxTreeTableViewCell extends TreeTableCell<DrawRow, WaveformTraceBox>
and then you can replace T with WaveformTraceBox throughout and get rid of the casts, etc.
Second: if I understand this correctly, WaveformTraceBox is a custom Node subclass of some kind; i.e. it's a UI component. The cell value factory shouldn't really return a UI component - it should return the data to display. The cell factory should then use some UI component to display the data.
That way, you can create a single WaveFormTraceBox in the cell implementation, and update the data it displays in the updateItem(...) method.
So something like:
// Waveform column
TreeTableColumn<DrawRow, WaveformData> waveColumn = new TreeTableColumn<>();
waveColumn.setCellFactory(new Callback<TreeTableColumn<DrawRow, WaveformData>, TreeTableCell<DrawRow, WaveformData>>() {
#Override
public TreeTableCell<DrawRow, WaveformData> call(TreeTableColumn<DrawRow, WaveformData> param) {
return new WaveformTraceBoxTreeTableViewCell();
}
});
waveColumn.setCellValueFactory(new Callback<TreeTableColumn.CellDataFeatures<DrawRow, WaveformData>, ObservableValue<WaveformData>>() {
#Override
public ObservableValue<WaveformTraceBox> call(TreeTableColumn.CellDataFeatures<DrawRow, WaveformTraceBox> param) {
return new ReadOnlyObjectWrapper<>(getDataToDisplayForItem(param.getValue()));
}
});
protected static class WaveformTraceBoxTreeTableViewCell extends TreeTableCell<DrawRow, WaveFormData> {
private WaveformTraceBox traceBox = new WaveformTraceBox();
public WaveformTraceBoxTreeTableViewCell() {
super();
}
#Override
protected void updateItem(WaveFormData value, boolean empty) {
super.updateItem(value, empty);
setText(null);
setGraphic(null);
if (!empty && getTreeTableRow().getItem() != null) {
traceBox.setData(value);
setGraphic(traceBox);
} else {
setGraphic(null);
}
}
}
Obviously you need to define the WaveFormData class to encapsulate the data your WaveFormTraceBox will display, and give the WaveFormTraceBox a setData(WaveFormData) method. If you are using any resources that need to be cleaned up, the invocation of setData(...) will indicate that the previous data is no longer being accessed by that WaveformTraceBox.

How to add click handler to GWT ImageResource cell?

Please help me out with this problem.
I have this code below,I actually want to insert an image into a GWT datagrid and add a click handler to the image. But it is not responding to clicks, pls what do you think might be the problem?
This is the Resource interface
public interface Resources extends ClientBundle {
#Source("delete.png")
ImageResource getDeleteImage();
#Source("edit.png")
ImageResource getEditImage();
}
Below is the ImageResource Cell that I coded, but it is not responding to clicks.
DataGrid<AccountDTO> dataGrid = new DataGrid<AccountDTO>();
Column<AccountDTO, ImageResource>delete = new Column<AccountDTO, ImageResource>(new ImageResourceCell()) {
#Override
public ImageResource getValue(AccountDTO object) {
return resources.getDeleteImage();
}
};
delete.setFieldUpdater(new FieldUpdater<AccountDTO, ImageResource>() {
#Override
public void update(int arg0, AccountDTO object, ImageResource resource) {
Window.alert(object.getId() + "" + object.getChargeAccount());
dataProvider.getList().remove(object);
dataProvider.refresh();
dataGrid.redraw();
}
dataGrid.addColumn(delete, "");
dataGrid.setColumnWidth(delete, 3.0, Unit.EM)
In the same way you have use a custom cell by extending AbstractCell for cell table you would extend ClickableTextCell (have a look a this answer). But as you are using image in your cell it gets tricky. This tutorial worked for us.
This is an old question, but there is a much simpler solution than suggested in the other answer.
datagrid.addCellPreviewHandler(new Handler<AccountDTO>() {
#Override
public void onCellPreview(CellPreviewEvent<AccountDTO> event) {
if ("click".equals(event.getNativeEvent().getType())) {
if (event.getColumn() == datagrid.getColumnIndex(myImageColumn)) {
AccountDTO account = event.getValue();
// Do what you need with a click
}
}
}
});

Adding style to a ButtonCell

I know my question is considered initially to refer to the "very novice" level, but I have spent quite o lot of time on searching for the answer. I have used in a gwt application a DataGrid and I have attached a diversity of specific Cell widgets (i.e. TextCell, ButtonCell). My concern is how I can add and handle styling to the button of a ButtonCell through custom css. The code which implements the column of ButtonCells looks like as follows:
Column<FilterInfo, String> delButtonColumn = new Column<FilterInfo, String>(new ButtonCell()) {
#Override
public String getValue(FilterInfo object) {
return "X";
}
};
So, how can I add styling to the button (not to the entire Cell)? I suspect that I should also override the render function, however I cannot figure out how the styling is applied
#Override
public void render(Context context, FilterInfo object, SafeHtmlBuilder sb) {
super.render(context, object, sb);
???
}
You can use the setCellStyleNames() method in Column to apply a style that will be applied to every cell of the column. You have to use GWT 2.4 for this to work. It will probably be something like that. Please note that the code was written outside of any IDE, so it may contain errors.
Column<FilterInfo, String> delButtonColumn = new Column<FilterInfo, String>(new ButtonCell()) {
#Override
public String getValue(FilterInfo object) {
return "X";
}
};
delButtonColumn.setCelLStyleNames("yourStyleName");
And the css :
.yourStyleName.gwt-Button{
//your styling here
}

gwt celltable: Possible to only make some cells in a column editable?

I'm using GWT 2.4. When using a CellTable, I've seen its possible to add a column in which all of the cells are editable ...
final TextInputCell nameCell = new TextInputCell();
Column<Contact, String> nameColumn = new Column<Contact, String>(nameCell) {
#Override
public String getValue(Contact object) {
return object.name;
}
};
table.addColumn(nameColumn, "Name");
but what if I don't want every cell in the column to be editable, only specific ones, based on properties in my "Contact" object? How would I set this up? Thanks, - Dave
The way I would do it is extend the TextInputCell and override the render method to render something else, if you don't want the value in that particular row editable.
Something like this:
public class MyTextInputCell extends TextInputCell {
#Override
public void render(Context context, String value, SafeHtmlBuilder sb) {
YourObject object = getYourObject();
if ( object.isThisCellEditable() ) {
super.render(context,value,sb);
} else {
sb.appendEscaped(value); // our some other HTML. Whatever you want.
}
}
}
In the render method you have access to the cell's context. Context.getIndex() returns the absolute index of the object. I can't remember of the top of my wad right now, but if you do not provide a ProvidesKey implementation when creating your CellTable you will get one that will use the object itself as the key. So you can get the object using Context.getKey().