JavaFX TableView items do not change after changes to the table in the UI - callback

I have a TableView which I populate with MappingItem objects. The goal is to create a mapping between an Excel source fields to database fields.
In the TableView I have two columns. One is of <MappingItem, String> and represents an Excel header. The other is of <MappingItem, GoldplusField> and represents a database field. The second column's cells are ComboBoxTableCell which has a list of fields from my DB.
The problem is that after I change the selection in the second column combobox, the MappingItem does not get updated by my selection. I tried to get the selected Cell and extract the item but I always get Null references.
This is the UI:
This is a sample code:
package tableviewexample;
import javafx.application.Application;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.beans.value.ObservableValue;
import javafx.collections.*;
import javafx.event.*;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.ComboBoxTableCell;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.util.StringConverter;
public class TableViewExample extends Application {
#Override
public void start(Stage primaryStage) {
TableView<MappingItem> table = new TableView<>();
// FIRST COLUMN
TableColumn<MappingItem, String> colA = new TableColumn<>("Excel Column");
colA.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<MappingItem, String>, ObservableValue<String>> () {
#Override
public ObservableValue<String> call(TableColumn.CellDataFeatures<MappingItem, String> param) {
return new ReadOnlyObjectWrapper(param.getValue().getExcelColumnName());
}
});
//SECOND COLUMN
TableColumn<MappingItem, GoldplusField> colB = new TableColumn<>("Database Field Column");
colB.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<MappingItem, GoldplusField>, ObservableValue<GoldplusField>> () {
#Override
public ObservableValue<GoldplusField> call(TableColumn.CellDataFeatures<MappingItem, GoldplusField> param) {
return new ReadOnlyObjectWrapper(param.getValue().getGpField());
}
});
GoldplusField gp1 = new GoldplusField("T1", "fName", "First Name");
GoldplusField gp2 = new GoldplusField("T1", "phn", "Phone");
ObservableList<GoldplusField> fieldsList = FXCollections.observableArrayList(gp1, gp2);
colB.setCellFactory(ComboBoxTableCell.forTableColumn(new FieldToStringConvertor(), fieldsList));
colB.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<MappingItem, GoldplusField>>() {
public void handle(TableColumn.CellEditEvent<MappingItem, GoldplusField> e) {
GoldplusField gpf = colB.getCellData(table.getFocusModel().getFocusedItem());
System.out.println(gpf.getGpName());
MappingItem item = table.getSelectionModel().getSelectedItem();
System.out.println(item.getGpField().getGpName());
}
});
table.setEditable(true);
table.getColumns().addAll(colA, colB);
MappingItem mi1 = new MappingItem("name");
MappingItem mi2 = new MappingItem("phone");
ObservableList<MappingItem> miList = FXCollections.observableArrayList(mi1, mi2);
table.setItems(miList);
StackPane root = new StackPane();
root.getChildren().add(table);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
class FieldToStringConvertor extends StringConverter<GoldplusField> {
#Override
public String toString(GoldplusField object) {
if (object != null)
return object.getGpName();
else
return "";
}
#Override
public GoldplusField fromString(String string) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
class MappingItem {
private String excelColumnName;
private GoldplusField gpField;
public String getExcelColumnName() { return excelColumnName; }
public void setExcelColumnName(String excelColumnName) { this.excelColumnName = excelColumnName; }
public GoldplusField getGpField() { return gpField; }
public void setGpField(GoldplusField gpField) { this.gpField = gpField; }
public MappingItem(String columnName) {
this.excelColumnName= columnName;
}
public MappingItem(GoldplusField gpField) {
this.gpField = gpField;
}
public MappingItem(String columnName, GoldplusField gpField) {
this.excelColumnName = columnName;
this.gpField = gpField;
}
}
class GoldplusField {
private String table;
private String dbName;
private String gpName;
public String getDbName() { return dbName; }
public String getGpName() { return gpName; }
public String getTable() { return table; }
public void setDbName(String dbName) { this.dbName = dbName; }
public void setGpName(String gpName) { this.gpName = gpName; }
public void setTable(String table) { this.table = table; }
public GoldplusField(String table, String dbName, String gpName) {
this.dbName = dbName;
this.gpName = gpName;
this.table = table;
}
}
}

OK. As have been mentioned, the problem was, probably, that the properties were not "writable".
I ended up changing my objects properties to JavaFX Properties. Then I set up a PropertyValueFactory for each of them and passed it to the column's CellValueFactory.
Thank you.
private void populateSourceColumnsColumn() {
ArrayList<MappingItem> items = new ArrayList<> ();
ArrayList<String> headers = SheetHelper.getTableHeadersAsString(sheet, true);
for (String header : headers) {
items.add(new MappingItem(header) );
}
ObservableList<MappingItem> itemsList = FXCollections.observableArrayList(items);
mappingTable.setItems(itemsList);
// First Column
PropertyValueFactory<MappingItem, String> fNameCellValueFactory = new PropertyValueFactory<>("excelColumnName");
inputColumnsColumn.setCellValueFactory(fNameCellValueFactory);
// Second Column
PropertyValueFactory<MappingItem, GoldplusField> gpFieldCellValueFactory = new PropertyValueFactory<>("gpField");
goldplusFieldsColumn.setCellValueFactory(gpFieldCellValueFactory);
GoldplusDatabase gpDb = new GoldplusDatabase(DatasourceContext.INSTANCE.getDataSource());
ObservableList<GoldplusField> fieldsList = FXCollections.observableArrayList(gpDb.getContactFields());
goldplusFieldsColumn.setCellFactory(ComboBoxTableCell.forTableColumn(new FieldToStringConvertor(), fieldsList));
}
public class MappingItem {
private StringProperty excelColumnName = new SimpleStringProperty(this, "excelColumnName");
private ObjectProperty<GoldplusField> gpField = new SimpleObjectProperty<GoldplusField>(this, "gpField");
public String getExcelColumnName() {
return excelColumnName.get();
}
public void setExcelColumnName(String excelColumnName) {
this.excelColumnName.set(excelColumnName);
}
public StringProperty excelColumnNameProperty() {
return excelColumnName;
}
public GoldplusField getGpField() {
return gpField.get();
}
public void setGpField(GoldplusField gpField) {
this.gpField.set(gpField);
}
public ObjectProperty gpFieldProperty() {
return this.gpField;
}
public MappingItem() {
super();
}
public MappingItem(String columnName) {
this.excelColumnName.set(columnName);
}
public MappingItem(GoldplusField gpField) {
this.gpField.set(gpField);
}
public MappingItem(String columnName, GoldplusField gpField) {
this.excelColumnName.set(columnName);
this.gpField.set(gpField);
}
}
public class GoldplusField {
private StringProperty table = new SimpleStringProperty(this, "table");
private StringProperty dbName = new SimpleStringProperty(this, "dbName");
private StringProperty gpName = new SimpleStringProperty(this, "gpName");
public String getDbName() {
return dbName.get();
}
public String getGpName() {
return gpName.get();
}
public String getTable() {
return table.get();
}
public void setDbName(String dbName) {
this.dbName.set(dbName);
}
public void setGpName(String gpName) {
this.gpName.set(gpName);
}
public void setTable(String table) {
this.table.set(table);
}
public StringProperty tableProperty() {
return this.table;
}
public StringProperty gpNameProperty() {
return this.gpName;
}
public StringProperty dbNameProperty() {
return this.dbName;
}
public GoldplusField(String table, String dbName, String gpName) {
this.dbName.set(dbName);
this.gpName.set(gpName);
this.table.set(table);
}
}

Related

Trying to read values returned on jsp form submission in springboot project by setters and use the combination to call another java class

So, I have values in getter setter variables when I click on form submit but now want to have those values in variables and check combination of them to run code from another java class
I have tried using parametrized constructor or may be having a common setter but that did not help.
package com.grt.dto;
import java.util.Set;
public class WDPayrollRecon {
public Set<String> dataType;
public String planCountry;
public String payPeriod;
public String currentPeriod;
public String lastPayPeriod;
Set<String> test;
public Set<String> getdataType() {
return dataType;
}
public void setdataType(Set<String> dataType) {
this.dataType = dataType;
System.out.println("this is dataType" +dataType);
test = dataType;
}
public String getPlanCountry() {
return planCountry;
}
public void setPlanCountry(String planCountry) {
this.planCountry = planCountry;
}
public String getPayPeriod() {
return payPeriod;
}
public void setPayPeriod(String payPeriod) {
this.payPeriod = payPeriod;
}
public String getCurrentPeriod() {
return currentPeriod;
}
public void setCurrentPeriod(String currentPeriod) {
this.currentPeriod = currentPeriod;
}
public String getlastPayPeriod() {
return lastPayPeriod;
}
public void setlastPayPeriod(String lastPayPeriod) {
this.lastPayPeriod = lastPayPeriod;
}
public WDPayrollRecon()
{
}
public WDPayrollRecon(Set<String> dataType,String planCountry,String payPeriod,String currentPeriod,String lastPayPeriod)
{
this.dataType = dataType;
this.planCountry = planCountry;
this.payPeriod = payPeriod;
this.currentPeriod = currentPeriod;
this.lastPayPeriod = lastPayPeriod;
if(dataType.contains("GTLI")& planCountry.equals("USA")){
System.out.println("This is test");
}
else{
System.out.println("This is not test");
}
}
}

Composite cell event Handling

I'm using a composite cell in a grid which has two buttons.I want to handle the click events on both the buttons seperately.Is it possible?
please explain in detail how to handle these events seperately.
I'm attaching my composite cell code with the buttons for the reference.
private CompositeCell<FilterInfo> createCompositeCell(){
HasCell<FilterInfo, String> button1= new HasCell<FilterInfo, String>() {
public Cell<String> getCell() {
return new TextCell();
}
public FieldUpdater<FilterInfo, String> getFieldUpdater() {
// TODO Auto-generated method stub
return null;
}
public String getValue(FilterInfo object) {
return "button 1";
}};
HasCell<FilterInfo, String> button2= new HasCell<FilterInfo,String>(){
public Cell<String> getCell() {
return new ButtonCell();
}
public FieldUpdater<FilterInfo, String> getFieldUpdater() {
// TODO Auto-generated method stub
return null;
}
public String getValue(FilterInfo object) {
// TODO Auto-generated method stub
return "button 2";
}
};
List<HasCell<FilterInfo, ?>> cells = new ArrayList<HasCell<FilterInfo, ?>>();
cells.add(button1);
cells.add(button2);
CompositeCell<FilterInfo> compositeCell = new CompositeCell<FilterInfo>(cells);
return compositeCell;
You handle click event in FieldUpdater of each button.
Here is minimal working example:
package com.adam.test.client;
import java.util.ArrayList;
import java.util.List;
import com.google.gwt.cell.client.ButtonCell;
import com.google.gwt.cell.client.CompositeCell;
import com.google.gwt.cell.client.FieldUpdater;
import com.google.gwt.cell.client.HasCell;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.cellview.client.CellList;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.RootPanel;
public class Test implements EntryPoint {
#Override
public void onModuleLoad() {
CompositeCell<FilterInfo> compositeCell = createCompositeCell();
CellList<FilterInfo> list = new CellList<FilterInfo>(compositeCell);
List<FilterInfo> values = new ArrayList<FilterInfo>();
values.add(new FilterInfo());
values.add(new FilterInfo());
values.add(new FilterInfo());
list.setRowData(values);
RootPanel.get().add(list);
}
private CompositeCell<FilterInfo> createCompositeCell() {
Column<FilterInfo, String> button1Column = new Column<FilterInfo, String>(new ButtonCell()) {
#Override
public String getValue(FilterInfo object) {
return "Button 1";
}
};
button1Column.setFieldUpdater(new FieldUpdater<FilterInfo, String>() {
#Override
public void update(int index, FilterInfo object, String value) {
Window.alert("Button 1 clicked!");
}
});
Column<FilterInfo, String> button2Column = new Column<FilterInfo, String>(new ButtonCell()) {
#Override
public String getValue(FilterInfo object) {
return "Button 2";
}
};
button2Column.setFieldUpdater(new FieldUpdater<FilterInfo, String>() {
#Override
public void update(int index, FilterInfo object, String value) {
Window.alert("Button 2 clicked!");
}
});
ArrayList<HasCell<FilterInfo, ?>> compositeColumns = new ArrayList<HasCell<FilterInfo, ?>>();
compositeColumns.add(button1Column);
compositeColumns.add(button2Column);
return new CompositeCell<FilterInfo>(compositeColumns);
}
private class FilterInfo {}
}
I would suggest you to create the custom cell and override the onBrowserEvent and render methods. Handle the click event in the onBrowserEvent method.
Refer http://www.gwtproject.org/doc/latest/DevGuideUiCustomCells.html

Apply table filter

I have this example of Java table which generates values every second.
Short example:
MainApp.java
public class MainApp extends Application
{
private TableView<Employee> table;
private TextField txtField;
private ObservableList<Employee> data;
MyService myService;
#Override
public void start(Stage stage) throws Exception
{
Label lbl = new Label("Enter text below to filter: ");
initFilter();
initTable();
myService = new MyService();
myService.setDelay(new Duration(300));
myService.setPeriod(new Duration(1000));
myService.start();
VBox container = new VBox();
container.getChildren().addAll(lbl, txtField, table);
StackPane root = new StackPane();
root.getChildren().add(container);
Scene scene = new Scene(root, 500, 400);
stage.setScene(scene);
stage.show();
}
class MyService extends ScheduledService<Void>
{
#Override
protected Task<Void> createTask()
{
return new Task<Void>()
{
#Override
protected Void call() throws Exception
{
data = getTableData();
table.setItems(FXCollections.observableArrayList(data));
return null;
}
};
}
}
public static void main(String[] args)
{
launch(args);
}
private void initTable()
{
table = new TableView<>();
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
TableColumn<Employee, String> empIdCol = new TableColumn<>("Employee ID");
empIdCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Employee, String>, ObservableValue<String>>()
{
#Override
public ObservableValue<String> call(TableColumn.CellDataFeatures<Employee, String> p)
{
return p.getValue().empIdProperty();
}
});
TableColumn<Employee, String> nameCol = new TableColumn<>("Name");
nameCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Employee, String>, ObservableValue<String>>()
{
#Override
public ObservableValue<String> call(TableColumn.CellDataFeatures<Employee, String> p)
{
return p.getValue().nameProperty();
}
});
TableColumn<Employee, Number> ageCol = new TableColumn<>("Age");
ageCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Employee, Number>, ObservableValue<Number>>()
{
#Override
public ObservableValue<Number> call(TableColumn.CellDataFeatures<Employee, Number> p)
{
return p.getValue().ageProperty();
}
});
TableColumn<Employee, String> cityCol = new TableColumn<>("City");
cityCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Employee, String>, ObservableValue<String>>()
{
#Override
public ObservableValue<String> call(TableColumn.CellDataFeatures<Employee, String> p)
{
return p.getValue().cityProperty();
}
});
table.getColumns().setAll(empIdCol, nameCol, ageCol, cityCol);
}
private void initFilter()
{
txtField = new TextField();
txtField.setPromptText("Filter");
txtField.textProperty().addListener(new InvalidationListener()
{
#Override
public void invalidated(Observable o)
{
if (txtField.textProperty().get().isEmpty())
{
table.setItems(data);
return;
}
ObservableList<Employee> tableItems = FXCollections.observableArrayList();
ObservableList<TableColumn<Employee, ?>> cols = table.getColumns();
for (int i = 0; i < data.size(); i++)
{
for (int j = 0; j < cols.size(); j++)
{
TableColumn col = cols.get(j);
String cellValue = col.getCellData(data.get(i)).toString();
cellValue = cellValue.toLowerCase();
if (cellValue.contains(txtField.textProperty().get().toLowerCase()))
{
tableItems.add(data.get(i));
break;
}
}
}
table.setItems(tableItems);
}
});
}
private ObservableList<Employee> getTableData()
{
ObservableList<Employee> list = FXCollections.observableArrayList();
String[] name =
{
"Sriram", "Pete", "Eric", "Dawson", "John"
};
String[] city =
{
"New York", "Chicago", "Little Rock", "Los Angeles", "Oakland"
};
for (int i = 0; i < 5; i++)
{
Employee emp = new Employee();
emp.setName(name[i]);
emp.setAge((int) (Math.random() * 100));
emp.setCity(city[i]);
emp.setEmpId(String.valueOf(i + 1000));
list.add(emp);
}
return list;
}
}
Employee.java
public class Employee {
private SimpleStringProperty name = new SimpleStringProperty();
private SimpleIntegerProperty age = new SimpleIntegerProperty();
private SimpleStringProperty city = new SimpleStringProperty();
private SimpleStringProperty empId = new SimpleStringProperty();
public SimpleStringProperty nameProperty() {
return name;
}
public void setName(String name) {
this.name.set(name);
}
public String getName() {
return name.get();
}
public SimpleIntegerProperty ageProperty() {
return age;
}
public void setAge(Integer age) {
this.age.set(age);
}
p
ublic Integer getAge() {
return age.get();
}
public SimpleStringProperty cityProperty() {
return city;
}
public String getCity() {
return city.get();
}
public void setCity(String city) {
this.city.set(city);
}
public SimpleStringProperty empIdProperty() {
return empId;
}
public void setEmpId(String empId) {
this.empId.set(empId);
}
public String getEmpId() {
return empId.get();
}
}
I noticed that the filter that I use to filter the content is applied only for the current Service run.
For next run the filter is not applied.
Use a FilteredList to manage the filtering. Instead of updating the list directly, replace the contents of its source list from the service. When the text in the text field changes, just update the predicate for the filtered list.
As an aside, your code updates the TableView from a background thread, which violates the threading rules of JavaFX. This is fixed in the example below.
SSCCE:
import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
import javafx.concurrent.ScheduledService;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;
public class FilteredTableViewExample extends Application {
private TableView<Employee> table;
private TextField txtField;
private FilteredList<Employee> tableData;
private ObservableList<Employee> data;
MyService myService;
#Override
public void start(Stage stage) throws Exception {
Label lbl = new Label("Enter text below to filter: ");
initFilter();
initTable();
myService = new MyService();
myService.setDelay(new Duration(300));
myService.setPeriod(new Duration(1000));
myService.start();
VBox container = new VBox();
container.getChildren().addAll(lbl, txtField, table);
StackPane root = new StackPane();
root.getChildren().add(container);
Scene scene = new Scene(root, 500, 400);
stage.setScene(scene);
stage.show();
}
class MyService extends ScheduledService<List<Employee>> {
#Override
protected Task<List<Employee>> createTask() {
Task<List<Employee>> task = new Task<List<Employee>>() {
#Override
protected List<Employee> call() throws Exception {
return getTableData();
}
};
task.setOnSucceeded(e -> data.setAll(task.getValue()));
return task ;
}
}
public static void main(String[] args) {
launch(args);
}
private void initTable() {
table = new TableView<>();
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
TableColumn<Employee, String> empIdCol = new TableColumn<>("Employee ID");
empIdCol.setCellValueFactory(p -> p.getValue().empIdProperty());
TableColumn<Employee, String> nameCol = new TableColumn<>("Name");
nameCol.setCellValueFactory(p -> p.getValue().nameProperty());
TableColumn<Employee, Number> ageCol = new TableColumn<>("Age");
ageCol.setCellValueFactory(p -> p.getValue().ageProperty());
TableColumn<Employee, String> cityCol = new TableColumn<>("City");
cityCol.setCellValueFactory(p -> p.getValue().cityProperty());
table.getColumns().setAll(empIdCol, nameCol, ageCol, cityCol);
data = FXCollections.observableArrayList();
tableData = new FilteredList<>(data);
table.setItems(tableData);
}
private void initFilter() {
txtField = new TextField();
txtField.setPromptText("Filter");
txtField.textProperty().addListener((obs, oldText, newText) -> {
if (txtField.textProperty().get().isEmpty()) {
tableData.setPredicate(employee -> true);
return;
}
tableData.setPredicate(employee -> {
String text = newText.toLowerCase();
for (TableColumn<Employee, ?> col : table.getColumns()) {
String cellValue = col.getCellData(employee).toString();
cellValue = cellValue.toLowerCase();
if (cellValue.contains(text)) {
return true;
}
}
return false;
});
});
}
private List<Employee> getTableData() {
List<Employee> list = new ArrayList<>();
String[] name = { "Sriram", "Pete", "Eric", "Dawson", "John" };
String[] city = { "New York", "Chicago", "Little Rock", "Los Angeles", "Oakland" };
for (int i = 0; i < 5; i++) {
Employee emp = new Employee();
emp.setName(name[i]);
emp.setAge((int) (Math.random() * 100));
emp.setCity(city[i]);
emp.setEmpId(String.valueOf(i + 1000));
list.add(emp);
}
return list;
}
public static class Employee {
private SimpleStringProperty name = new SimpleStringProperty();
private SimpleIntegerProperty age = new SimpleIntegerProperty();
private SimpleStringProperty city = new SimpleStringProperty();
private SimpleStringProperty empId = new SimpleStringProperty();
public SimpleStringProperty nameProperty() {
return name;
}
public void setName(String name) {
this.name.set(name);
}
public String getName() {
return name.get();
}
public SimpleIntegerProperty ageProperty() {
return age;
}
public void setAge(Integer age) {
this.age.set(age);
}
public Integer getAge() {
return age.get();
}
public SimpleStringProperty cityProperty() {
return city;
}
public String getCity() {
return city.get();
}
public void setCity(String city) {
this.city.set(city);
}
public SimpleStringProperty empIdProperty() {
return empId;
}
public void setEmpId(String empId) {
this.empId.set(empId);
}
public String getEmpId() {
return empId.get();
}
}
}

TableViewer not refreshing in RAP

I tried to run my Eclipse RCP code to run in Eclipse RAP environment. In my Eclipse RCP code, there is functionality to add the rows in to table. But
adding the code does not work in Eclipse RAP. I am using TableViewer.
Following is my code.
public class BasicEntryPoint extends AbstractEntryPoint {
private static final int COLUMNS = 2;
private TableViewer viewer;
private class ViewContentProvider implements IStructuredContentProvider {
public Object[] getElements(Object inputElement) {
List<Person> list = (List<Person>) inputElement;
return list.toArray();
}
public void dispose() {
}
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
}
private class ViewLabelProvider extends LabelProvider implements
ITableLabelProvider {
public Image getColumnImage(Object element, int columnIndex) {
return null;
}
public String getColumnText(Object element, int columnIndex) {
Person p = (Person) element;
if (columnIndex == 0) {
return p.getName();
}
return p.getPlace();
}
}
private class Person{
String name;
String place;
public void setName(String name) {
this.name = name;
}
public void setPlace(String place) {
this.place = place;
}
public String getName() {
return name;
}
public String getPlace() {
return place;
}
}
public List<Person> persons() {
List<Person> list = new ArrayList<Person>();
Person person = new Person();
person.setName("bb");
person.setPlace("jjj");
list.add(person);
person = new Person();
person.setName("sss");
person.setPlace("fff");
list.add(person);
return list;
}
#Override
protected void createContents(Composite parent) {
parent.setLayout(new GridLayout(2, false));
viewer = new TableViewer(parent, SWT.NONE);
viewer.setContentProvider(new ViewContentProvider());
viewer.setLabelProvider(new ViewLabelProvider());
final Table table = viewer.getTable();
viewer.setColumnProperties(initColumnProperties(table));
viewer.setInput(persons());
viewer.getTable().setHeaderVisible(true);
Button checkbox = new Button(parent, SWT.CHECK);
checkbox.setText("Hello");
Button button = new Button(parent, SWT.PUSH);
button.setText("World");
button.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
System.out.println("Button clicked");
Person p = new Person();
p.setName("Dee");
p.setPlace("TCR");
persons().add(p);
String prop[] ={"name","place"};
viewer.update(p, prop);
//viewer.refresh();
}
});
}
private String[] initColumnProperties(Table table) {
String[] result = new String[COLUMNS];
for (int i = 0; i < COLUMNS; i++) {
TableColumn tableColumn = new TableColumn(table, SWT.NONE);
result[i] = "Column" + i;
tableColumn.setText(result[i]);
if (i == 2) {
tableColumn.setWidth(190);
} else {
tableColumn.setWidth(70);
}
}
return result;
}
}
You should use:
viewer.add(p);
rather than update to add a new item to a table (both for SWT and RAP).
You must also update your model to contain the new item.

Does anyone have a working examples of ActionCells working within a CompositeCell?

I tried following the example, http://gwt.google.com/samples/Showcase/Showcase.html#!CwCellTree , and added two ActionCells inside of the CompositeCell with no luck. The ActionCell's onBrowserEvent() does not get triggered.
This simple example works for me. Since you didn't provide any code or further explanation on what exactly you're trying to achieve, I have no idea whether my example is of any help or not.
public void onModuleLoad() {
CellTable<Person> table = new CellTable<Starter.Person>();
List<HasCell<Person, ?>> cells = new LinkedList<HasCell<Person, ?>>();
cells.add(new HasCellImpl("first name", new Delegate<Person>() {
#Override
public void execute(Person object) {
Window.alert(object.getFirstName());
}
}));
cells.add(new HasCellImpl("last name", new Delegate<Starter.Person>() {
#Override
public void execute(Person object) {
Window.alert(object.getLastName());
}
}));
CompositeCell<Person> cell = new CompositeCell<Person>(cells);
table.addColumn(new TextColumn<Starter.Person>() {
#Override
public String getValue(Person object) {
return object.getFirstName() + " " + object.getLastName();
}
}, "name");
table.addColumn(new Column<Person, Person>(cell) {
#Override
public Person getValue(Person object) {
return object;
}
}, "composite");
LinkedList<Person> data = new LinkedList<Starter.Person>();
data.add(new Person("Amy", "Reed"));
data.add(new Person("Tim", "Gardner"));
table.setRowData(data);
RootPanel.get().add(table);
}
private class HasCellImpl implements HasCell<Person, Person> {
private ActionCell<Person> fCell;
public HasCellImpl(String text, Delegate<Person> delegate) {
fCell = new ActionCell<Person>(text, delegate);
}
#Override
public Cell<Person> getCell() {
return fCell;
}
#Override
public FieldUpdater<Person, Person> getFieldUpdater() {
return null;
}
#Override
public Person getValue(Person object) {
return object;
}
}
private class Person {
private String fFirstName;
private String fLastName;
public Person(String first, String last) {
fFirstName = first;
fLastName = last;
}
public String getFirstName() {
return fFirstName;
}
public String getLastName() {
return fLastName;
}
}