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
Related
I want to edit the tree viewer element based on my context menu option. Basically i need to update the element value which is displayed. If i double click on tree viewer element i was able to update the value, but through context menu also i should be able to do.
Sample code for adding the context menu:
protected def void createContextMenu(Viewer viewer) {
val MenuManager contextMenu = new MenuManager("Menu"); // $NON-NLS-1$
contextMenu.setRemoveAllWhenShown(true);
contextMenu.addMenuListener(new IMenuListener() {
public override void menuAboutToShow(IMenuManager mgr) {
fillContextMenu(mgr);
}
});
val Menu menu = contextMenu.createContextMenu(viewer.getControl());
viewer.getControl().setMenu(menu);
}
/**
* Fill dynamic context menu
*
* #param contextMenu
*/
protected def void fillContextMenu(IMenuManager contextMenu) {
contextMenu.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
contextMenu.add(new Action("Rename") {
public override void run() {
val selectedElement = (treeViewer.selection as IStructuredSelection).firstElement
}
});
}
See if this helps or let me know otherwise
package myFolder;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MenuEvent;
import org.eclipse.swt.events.MenuListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TreeItem;
public class trying {
public static void main(String[] args){
Display display = new Display();
Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
shell.setSize(300,300);
TreeViewer viewer = new TreeViewer(shell);
viewer.getTree().setHeaderVisible(true);
viewer.getTree().setLinesVisible(true);
viewer.setContentProvider(new ITreeContentProvider () {
#Override
public void dispose() {
// TODO Auto-generated method stub
}
#Override
public void inputChanged(Viewer arg0, Object arg1, Object arg2) {
// TODO Auto-generated method stub
}
#Override
public Object[] getChildren(Object arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public Object[] getElements(Object arg0) {
// TODO Auto-generated method stub
return new String[]{"Hoshe","Irani"};
}
#Override
public Object getParent(Object arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public boolean hasChildren(Object arg0) {
// TODO Auto-generated method stub
return false;
}
});
viewer.setLabelProvider(new ILabelProvider(){
#Override
public void addListener(ILabelProviderListener arg0) {
// TODO Auto-generated method stub
}
#Override
public void dispose() {
// TODO Auto-generated method stub
}
#Override
public boolean isLabelProperty(Object arg0, String arg1) {
// TODO Auto-generated method stub
return false;
}
#Override
public void removeListener(ILabelProviderListener arg0) {
// TODO Auto-generated method stub
}
#Override
public Image getImage(Object arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public String getText(Object arg0) {
// TODO Auto-generated method stub
return "hoshe";
}
});
viewer.setInput("Hoshe");
Menu popupMenu = new Menu(viewer.getControl());
MenuItem newItem = new MenuItem(popupMenu, SWT.CHECK);
newItem.setText("New");
MenuItem refreshItem = new MenuItem(popupMenu, SWT.CHECK);
refreshItem.setText("Refresh");
MenuItem deleteItem = new MenuItem(popupMenu, SWT.CHECK);
deleteItem.setText("Delete");
popupMenu.addMenuListener(new MenuListener() {
#Override
public void menuShown(MenuEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void menuHidden(MenuEvent arg0) {
// TODO Auto-generated method stub
display.asyncExec(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
TreeItem [] arr = viewer.getTree().getSelection();
for(MenuItem item2 : popupMenu.getItems()){
boolean bool1 = item2.getSelection();
if(bool1){
arr[0].setText(item2.getText());
item2.setSelection(false);
}
}
}
});
}
});
viewer.getTree().setMenu(popupMenu);
shell.open();
while(!shell.isDisposed()){
if(!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
}
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);
}
}
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.
I have a cell table in one of my GWT screen. Now requirement is that there will be some button on the screen clicking on which one editable row will be inserted into the cell table. if I am not wrong this is called inline editing.
Can somebody please help me with that? I have just started working in GWT.
Here is very simple example of adding new editable row to the celltable. I hope I understand what you meant :)
public class Test
implements EntryPoint
{
public void onModuleLoad()
{
//create and attach table
final CellTable<A> table = new CellTable<A>();
RootPanel.get().add(table);
//add editable cell
table.addColumn(new Column<A, String>(new TextInputCell())
{
#Override
public String getValue(
A object)
{
return object.getA() == null ? "" : object.getA();
}
});
//put some data
ListDataProvider<A> dataProvider = new ListDataProvider<A>(
Arrays.asList(new A("AAA"), new A("BBB"), new A("CCC")));
dataProvider.addDataDisplay(table);
//add button with click handler
RootPanel.get().add(new Button("add new", new ClickHandler()
{
#Override
public void onClick(
ClickEvent event)
{
//add new object to visible items
List<A> data = new ArrayList<A>(table.getVisibleItems());
A newOne = new A();
data.add(newOne);
table.setRowData(data);
}
}));
}
class A
{
String a;
public A(
String a)
{
super();
this.a = a;
}
public A()
{
super();
}
public String getA()
{
return a;
}
public void setA(
String a)
{
this.a = a;
}
}
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;
}
}