For testing purposes (using JemmyFX), I want to check that the content of a TableView is appropriately formatted. For example: one column is of type Double and a cell factory has been applied to show the number as a percent: 20%.
How can I verify that when the value is 0.2d, the cell is showing as 20%?
Ideally I am looking for something along those lines:
TableColumn<VatInvoice, Double> percentVat = ...
assertEquals(percentVat.getTextualRepresentation(), "20%");
Note: I have tried to use the TableCell directly like below but getText() returns null:
TableCell<VatInvoice, Double> tc = percentVat.getCellFactory().call(percentVat);
tc.itemProperty().set(0.2);
assertEquals(tc.getText(), "20%"); //tc.getText() is null
The best I have found so far, using JemmyFX, is the following:
public String getCellDataAsText(TableViewDock table, int row, int column) {
final TableCellItemDock dock = new TableCellItemDock(table.asTable(), row, column);
return dock.wrap().waitState(new State<String>() {
#Override public String reached() {
return dock.wrap().cellWrap().getControl().getText();
}
});
}
You can try editing the cell factory.
tc.setCellFactory(new Callback<TableColumn, TableCell>(){
#Override
public TableCell call(TableColumn param){
return new TableCell(){
#Override
public void updateItem(Object item, boolean isEmpty){
//...logic to format the text
assertEquals(getText(), "20%");
}
};
}
});
Related
I have an objectlistview with 4 columns and a dynamic number of rows, I'm struggling with programmable editing a cell text value, and optionally change the forecolor
I've read everything and anything that I could put my hands on, but couldn't find any valid and right to the point example on how to do it.
the ObjectListView is created this why
List<VideoItem> list = new List<VideoItem>();
foreach (dynamic item in VideoItems)
{
list.Add(new VideoItem { Index = (int)item.index, OldName = (string)item.oldname, NewName = (string)item.newname });
}
olv1.AddObjects(list);
VideoItem class look like this
private class VideoItem
{
public int Index;
public string OldName;
public string NewName;
}
but i need to programmably edit a cell text on event. I'm doing some logical operations on other cell at the end im storing the result to to cell next to it.
You should be storing the result (making the change) to the underlying model object and then call RefreshObject(myModelObject);
About the forcolor, i need to change only the cell I've changed
"To change the formatting of an individual cell, you need to set UseCellFormatEvents to true and then listen for FormatCell events."
Take a look at this.
Just to add to Rev1.0 Answer, i needed to update the object that contains the items (in my case a List) then, use olv1.RefreshObject(list); flow by olv1.BuildList(true);
the olv1.BuildList(true); refresh the GUI immediately.
here a small code snippet to make thing bit more clear
it's changing the data in column 3 when a checkbox is checked.
using System.Collections.Generic;
using System.Windows.Forms;
namespace Test
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Initializeolv();
}
private class VideoItem
{
public int Index;
public string OldName;
public string NewName;
}
private List<VideoItem> list = new List<VideoItem>();
private void Initializeolv()
{
for (var i = 1; i <= 10; i++)
{
list.Add(new VideoItem { Index = i, OldName = $"old{i}", NewName = $"new{i}" });
}
olv1.AddObjects(list);
}
private void olv1_ItemChecked(object sender, ItemCheckedEventArgs e)
{
list[e.Item.Index].NewName = "new200";
olv1.RefreshObject(list);
olv1.BuildList(true);
}
}
}
In itext 5, it can be used cell events to compute a subtotal of a table column. How can this be done in itext 7?
The itext 5 example can be found in this URL: http://developers.itextpdf.com/examples/tables/using-cell-events-add-special-content#2887-subtotal.java
There is currently no direct alternative of cell event functionality in iText7.
Howerver, the desired output can be achieved using rich rendering mechanism which allows a lot more than just events.
I will provide just one of the possible ways to implement a subtotal of table on the page. Total is easy and thus I'm leaving it out of the scope of the answer.
For the starters, we will need a class responsible for calculations:
private static class SubtotalHandler {
private int subtotalSum;
public void reset() {
subtotalSum = 0;
}
public void add(int val) {
subtotalSum += val;
}
public int get() {
return subtotalSum;
}
}
The code for generating the table itself will look like this:
Table table = new Table(UnitValue.createPercentArray(new float[] {1, 1})).setWidth(400);
table.setHorizontalAlignment(HorizontalAlignment.CENTER);
// Create our calculating class instance
SubtotalHandler handler = new SubtotalHandler();
for (int i = 0; i < 200; i++) {
table.addCell(new Cell().add(String.valueOf(i + 1)));
int price = 10;
Cell priceCell = new Cell().add(String.valueOf(price));
// Note that we set a custom renderer that will interact with our handler
priceCell.setNextRenderer(new SubtotalHandlerAwareCellRenderer(priceCell, handler, price));
table.addCell(priceCell);
}
table.addFooterCell(new Cell().add("Subtotal"));
Cell subtotalCell = new Cell();
// We create a custom renderer for the subtotal value itself as well because the text of the cell will depend on the state of the subtotal handler
subtotalCell.setNextRenderer(new SubtotalCellRenderer(subtotalCell, handler));
table.addFooterCell(subtotalCell);
Renderers of cells with price just tell the subtotal handler that some amount has been added:
private static class SubtotalHandlerAwareCellRenderer extends CellRenderer {
private SubtotalHandler subtotalHandler;
private int price;
public SubtotalHandlerAwareCellRenderer(Cell modelElement, SubtotalHandler subtotalHandler, int price) {
super(modelElement);
this.subtotalHandler = subtotalHandler;
this.price = price;
}
#Override
public void draw(DrawContext drawContext) {
super.draw(drawContext);
subtotalHandler.add(price);
}
#Override
public IRenderer getNextRenderer() {
return new SubtotalHandlerAwareCellRenderer((Cell) modelElement, subtotalHandler, price);
}
}
When it comes to the rendering of the footer cell, the corresponding cell asks the subtotal handler about the amount and prints it, and resets the subtotal handler afterwards:
private static class SubtotalCellRenderer extends CellRenderer {
private SubtotalHandler subtotalHandler;
public SubtotalCellRenderer(Cell modelElement, SubtotalHandler subtotalHandler) {
super(modelElement);
this.subtotalHandler = subtotalHandler;
}
#Override
public void draw(DrawContext drawContext) {
super.draw(drawContext);
new Canvas(drawContext.getCanvas(), drawContext.getDocument(), occupiedArea.getBBox()).
showTextAligned(String.valueOf(subtotalHandler.get()), occupiedArea.getBBox().getX() + 3,
occupiedArea.getBBox().getY() + 3, TextAlignment.LEFT);
subtotalHandler.reset();
}
#Override
public IRenderer getNextRenderer() {
return new SubtotalCellRenderer((Cell) modelElement, subtotalHandler);
}
}
The output looks like this:
I have a table with editable cells (Strings) in JavaFX. I want to edit the value of the cells IN the table itself. Now the edit behaviour in FX is a little bit unusual. You have to press enter to commit the edited value. Changing row or cell is not enough. So my idea was to paint the cell background in yellow when I start editing it and remove the yellow color when the user presses enter to remind the user to press enter. But I have some problems to get the cell in the start-edit method. How can I change the color?
Any hint is welcome!
Here is my code
TableColumn nameCol = new TableColumn("Name");
nameCol.setCellFactory(TextFieldTableCell.forTableColumn());
nameCol.setOnEditStart(new EventHandler<CellEditEvent<Zone, String>>() {
#Override
public void handle(CellEditEvent<Zone, String> cell)
{
if(cell.getRowValue() != null)
//how to get the cell and then ->.setStyle("-fx-background-color:yellow");
}});
Rather than relying on the setOnEditStart API, work with the table's RowFactory.
/**
*
* #author ggrec
*
*/
private class FXTableRowFactory implements Callback<TableView<FXTableRow>, TableRow<FXTableRow>>
{
#Override
public TableRow<FXTableRow> call(final TableView<FXTableRow> arg0)
{
return new TableRow<FXTableRow>() {
#Override protected void updateItem(final FXTableRow line, final boolean empty)
{
super.updateItem(line, empty);
if (line == null)
return;
if (isEditing())
{
this.setStyle(line.getStyleWhenEditing());
}
}
};
}
}
I want set the the graphics of starting cell to an eror image when there is any error in the table view data(any row data).I am using the following code inside the update method.
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
String text = getString();
setText(empty ? null : text);
String text2 = text.trim();
boolean isHex = text2.matches("^[0-9A-Fa-fx]+$");
// Pattern compile = Pattern.compile("^[0-9A-Fa-fx]+.*");
// Matcher matcher = compile.matcher(text);
// boolean find = matcher.find();
// getTableView().getColumns().;
setGraphic(null);
if (!isHex) {
getStyleClass().add("oneCell");
// this.setTextFill(Color.RED);
// getTableView().getColumns().get(0;
revertbackchanges();
Image error = new Image(getClass().getResourceAsStream("twobuttons/icon_error_1.png"));
} else {
setGraphic(null);
getStyleClass().remove("oneCell");
}
here i am checking the cell data whether the data are hex value or not if other than hex is entered then i am changing the color of the cell to red .Now i want to show a error like icon on the 1st cell .How can i get the 1st cell from table view and set the graphics on it.As shown on image i can show an error with respective to cell on which user has entered the wrong value but along with that i want to show and error icon on Command cell i.e TX_default or i want to highlight the whole cell .Any help on this is really appreciated
this time its workied i tired..
Image img =new Image(getClass().getResourceAsStream("Add-Male-User-icon.png"));
ImageView imgs =new ImageView(img);
tablecol.setCellFactory(new Callback<TableColumn<CheckDo, String>, TableCell<CheckDo, String>>() {
#Override
public TableCell<CheckDo, String> call(TableColumn<CheckDo, String> p) {
return new TableCell<CheckDo, String>() {
#Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (!isEmpty())
this.setGraphic(imgs);
}
}
};
Is there anyway to define the editor type on a cell by cell basis in GXT 3.0?
I need to create a transposed table; the column become the row and the row is the column. That being the case, a column (from a normal table point of view) will have various editor type, whereby a row will have identical editor type.
I am trying to use following approach - It seems to be working fine, and allow to open up editors based on data type but when i click out; it doesn't close/hide editor.
I would really appreciate if someone can please point me in right direction.
final GridInlineEditing<MyModel> editing = new GridInlineEditing<MyModel>(mygrid){
#SuppressWarnings("unchecked")
#Override public <O> Field<O> getEditor(ColumnConfig<MyModel, ?> columnConfig) {
if(valueColumnName.equals(columnConfig.getHeader().asString())) {
MyModel myModel = tree.getSelectionModel().getSelectedItem();
if(MyModelType.STRING.equals(myModel.getMyModelType())) {
TextField textField = new TextField();
textField.setAllowBlank(Boolean.FALSE);
return (Field<O>) textField;
}
else {
TextArea textField = new TextArea();
textField.setAllowBlank(Boolean.FALSE);
return (Field<O>) textField;
}
}
return super.getEditor(columnConfig);
}
};
editing.setClicksToEdit(ClicksToEdit.TWO);
PS:
This is similar to question below; but answer is specific to post GXT 3.0. I am new to stackoverflow and it seems recommendation was to create new question instead of adding new post to old thread.
GXT EditorGrid: choose cell editor type on a cell by cell basis
After playing around all day; my colleague(Praveen) and I figured it out. So instead of trying to override GridInlineEditing's getEditor() method override startEditing() method. Also, you will need converters if you have data like Date, List etc. Below is sample code; hope this help others.
final GridInlineEditing<MyModel> editing = new GridInlineEditing<MyModel>(tree){
#Override public void startEditing(GridCell cell) {
MyModel myModel= tree.getSelectionModel().getSelectedItem();
if(MyModelType.TEXT.equals(myModel.getContextVariableType())) {
TextArea textField = new TextArea();
textField.setAllowBlank(Boolean.FALSE);
super.addEditor(valueColumn, textField);
}
else if(MyModelType.BOOLEAN.equals(myModel.getContextVariableType())) {
SimpleComboBox<String> simpleComboBox = new SimpleComboBox<String>(new StringLabelProvider<String>());
simpleComboBox.setTriggerAction(TriggerAction.ALL);
simpleComboBox.add("YES");
simpleComboBox.add("NO");
super.addEditor(valueColumn, simpleComboBox);
}
else if(MyModel.INTEGER.equals(myModel.getContextVariableType())) {
SpinnerField<Integer> spinnerField = new SpinnerField<Integer>(new IntegerPropertyEditor());
spinnerField.setIncrement(1);
Converter<String, Integer> converter = new Converter<String, Integer>(){
#Override public String convertFieldValue(Integer object) {
String value = "";
if(object != null) {
value = object.toString();
}
return value;
}
#Override public Integer convertModelValue(String object) {
Integer value = 0;
if(object != null && object.trim().length() > 0) {
value = Integer.parseInt(object);
}
return value;
}
};
super.addEditor(valueColumn, converter, (Field)spinnerField);
}
else {
TextField textField = new TextField();
textField.setAllowBlank(Boolean.FALSE);
super.addEditor(valueColumn, textField);
}
super.startEditing(cell);
}
};
editing.setClicksToEdit(ClicksToEdit.TWO);
I think the reason you are not seeing the fields not closing is because you are not actually adding them to the GridInlineEditing class.
In the parts where you have the following return statements;
return (Field<O>) textField;
Those textfields are never added to the grid.
I would try substituting the following code for your first two return statement;
super.addEditor(columnConfig, (Field<O>) textField;
This adds the editor to some maps used by AbstractGridEditing. Specifically, the AbstractGridEditing.removeEditor(GridCell, Field<?>) method, which is used in GridInlineEditing.doCompleteEditing() and GridInlineEditing.cancelEditing() needs the field to be in the map so it can be detached from its parent.