I'm trying to run an example of Editors with sub-editors.
When flushing the parent the value of child editor is null.
The classes are Person and Address.
The main editor is:
// editor fields
public TextField firstname;
public TextField lastname;
public NumberField<Integer> id;
public AddressEditor address = new AddressEditor();
public PersonEditor(Person p){
asWidget();
}
#Override
public Widget asWidget() {
setWidth(400);
setBodyStyle("padding: 5px;");
setHeaderVisible(false);
VerticalLayoutContainer c = new VerticalLayoutContainer();
id = new NumberField<Integer>(new IntegerPropertyEditor());
// id.setName("id");
id.setFormat(NumberFormat.getFormat("0.00"));
id.setAllowNegative(false);
c.add(new FieldLabel(id, "id"), new VerticalLayoutData(1, -1));
firstname = new TextField();
// firstname.setName("firstname");
c.add(new FieldLabel(firstname, "firstname"), new VerticalLayoutData(1, -1));
lastname = new TextField();
lastname.setName("lastname");
c.add(new FieldLabel(lastname, "lastname"), new VerticalLayoutData(1, -1));
c.add(address);
add(c);
return this;
The sub-editor:
public class AddressEditor extends Composite implements Editor<Address> {
private AddressProperties props = GWT.create(AddressProperties.class);
private ListStore<Address> store = new ListStore<Address>(props.key());
ComboBox<Address> address;
public AddressEditor() {
for(int i = 0; i < 5; i ++)
store.add(new Address("city" + i));
address = new ComboBox<Address>(store, props.nameLabel());
address.setAllowBlank(false);
address.setForceSelection(true);
address.setTriggerAction(TriggerAction.ALL);
initWidget(address);
}
And this is where the Driver is created:
private HorizontalPanel hp;
private Person googleContact;
PersonDriver driver = GWT.create(PersonDriver.class);
public void onModuleLoad() {
hp = new HorizontalPanel();
hp.setSpacing(10);
googleContact = new Person();
PersonEditor pe = new PersonEditor(googleContact);
driver.initialize(pe);
driver.edit(googleContact);
TextButton save = new TextButton("Save");
save.addSelectHandler(new SelectHandler() {
#Override
public void onSelect(SelectEvent event) {
googleContact = driver.flush();
System.out.println(googleContact.getFirstname() + ", " + googleContact.getAddress().getCity());
if (driver.hasErrors()) {
new MessageBox("Please correct the errors before saving.").show();
return;
}
}
});
The value of googleContact.getFirstname() is filled but googleContact.getAddress() is always null.
What I'm missing?
The AddressEditor needs to map to the Address model - presently, it doesn't seem to, unless Address only has one getter/setter, called getAddress() and setAddress(Address), which wouldn't really make a lot of sense.
If you want just a ComboBox<Address> (which implements Editor<Address> already), consider putting that combo in the PersonEditor directly. Otherwise, you'll need to add #Path("") to the AddressEditor.address field, to indicate that it should be directly editing the value itself, and not a sub property (i.e. person.getAddress().getAddress()).
Another way to build an address editor would be to list each of the properties of the Address type in the AddressEditor. This is what the driver is expecting by default, so it is confused when it sees a field called 'address'.
Two quick thoughts on the code itself: there is no need to pass a person into the PersonEditor - thats the job of the driver itself. Second, your editor fields do not need to be public, they just can't be private.
Related
I have a method called creatcomponents() where I am creating few text fields and buttons in a composite. Now I want to write listeners to the button which calls a method and in this method I have get the values of the text fields. The problem I am facing is I am unable to access textfields from the method called in the listeners. Can someone help me on how to acheive this?
One way is to save the controls are fields in your class:
public class MyClass
{
private Text text1;
private Text text2;
public void createComponents(Composite parent)
{
Composite composite = new Composite(parent, SWT.None);
text1 = new Text(composite, SWT.SINGLE);
text2 = new Text(composite, SWT.SINGLE);
text1.addModifyListener(new ModifyListener()
{
#Override
public void modifyText(ModifyEvent event)
{
// Access field
String text = text1.getText();
}
});
}
}
Also note that many of the event classes passed to listeners have a widget field which refers to the current control which you can also use:
text1.addModifyListener(new ModifyListener()
{
#Override
public void modifyText(ModifyEvent event)
{
Text control = (Text)event.widget;
String text = control.getText();
}
});
I am new in GWT. I am trying to use the cell table to do this. Here is my questions:
Name Gender
Ali M
Abu M
Siti F
page 1
Name Gender
Siti F
Noor F
Ahmad F
page 2
I use simple pager to do the paging function. Everything is ok except next page.
When i click next page, siti record appear 2 times.
How to prevent the name Siti not appear in page 2? Below are my code:
private static class Contact{
private final String name;
private final String gender;
public Contact(String name, String gender){
this.name = name;
this.gender = gender;
}
}
private static final List<Contact> CONTACTS = Arrays.asList(
new Contact("Ali","M"),
new Contact("Abu","M"),
new Contact("Siti","F"),
new Contact("Noor","F"),
new Contact("Ahmad","M")
);
public void onModuleLoad(){
final CellTable<Contact> table = new CellTable<Contact>();
table.setPageSize(3);
TextColumn<Contact> nameColumn = new TextColumn<Contact>(){
#Override
public String getValue(Contact object) {
return object.name;
}
};
TextColumn<Contact> genderColumn = new TextColumn<Contact>(){
#Override
public String getValue(Contact object) {
return object.gender;
}
};
table.addColumn(nameColumn, "Name");
table.addColumn(genderColumn, "Gender");
AsyncDataProvider<Contact> provider = new AsyncDataProvider<Contact>(){
#Override
protected void onRangeChanged(HasData<Contact> display) {
int start = display.getVisibleRange().getStart();
int end = start + display.getVisibleRange().getLength();
end = end >= CONTACTS.size() ? CONTACTS.size() : end;
List<Contact> sub = CONTACTS.subList(start,end);
updateRowData(start,sub);
}
};
provider.addDataDisplay(table);
provider.updateRowCount(CONTACTS.size(), true);
SimplePager.Resources pagerResources = GWT.create(SimplePager.Resources.class);
SimplePager pager = new SimplePager(TextLocation.CENTER, pagerResources, false, 0, true);
pager.setDisplay(table);
Please help me to solve this problem. Thanks.
You have faced most probably the gwt last page problem, described in the linked questions:
GWT - celltable with simple pager issue
SimplePager row count is working incorrectly
The solution here is to set:
setRangeLimited(false)
and the last page is paged correctly, ie. it contains only Noor and Ahmad.
So in conclusion: actually no duplication is present here, but a bug on pagination in case of the last page. You will observe the same behavior with also other amounts of data, but on my view point it would be always a last page issue only.
I'm trying to create a list of HITs (objects), where each has a checkbox next to it, so that I can select them and delete them all at once. I've made a form with a checkbox for each row in the table:
final HashSet<HIT> selectedValues = new HashSet<HIT>();
final CheckGroup checkgroup = new CheckGroup("checkgroup");
final Form form = new Form("form"){
#Override
public void onSubmit() {
super.onSubmit();
}
};
checkgroup.add(new CheckGroupSelector("checkboxSelectAll"));
UserHitDataProvider userHitDataProvider = new UserHitDataProvider(selectedIsReal, keyId, secretId);
final DataView<HIT> dataView = new DataView<HIT>("pageable", userHitDataProvider) {
private static final long serialVersionUID = 1L;
#Override
protected void populateItem(final Item<HIT> item) {
HIT hit = item.getModelObject();
item.add(new CheckBox("checkbox", new SelectItemUsingCheckboxModel(hit,selectedValues)));
item.add(new Label("hitName", String.valueOf(hit.getTitle())));
item.add(new Label("hitId", String.valueOf(hit.getHITId())));
}
};
//add checkgroup to form, form to page, etc.
I've also added a new class to take care of the selection/deletion:
public class SelectItemUsingCheckboxModel extends AbstractCheckBoxModel {
private HIT hit;
private Set selection;
public SelectItemUsingCheckboxModel(HIT h, Set selection) {
this.hit = h;
this.selection = selection;
}
#Override
public boolean isSelected() {
return selection.contains(hit);
}
#Override
public void select() {
selection.add(hit);
}
#Override
public void unselect() {
selection.remove(hit);
}
}
Everything renders fine, but I get an error when trying to submit:
Caused by: java.lang.IllegalStateException: Attempt to set model object on null model of component: form:checkgroup
at org.apache.wicket.Component.setDefaultModelObject(Component.java:3042)
at org.apache.wicket.markup.html.form.FormComponent.updateCollectionModel(FormComponent.java:1572)
at org.apache.wicket.markup.html.form.CheckGroup.updateModel(CheckGroup.java:160)
at org.apache.wicket.markup.html.form.Form$FormModelUpdateVisitor.component(Form.java:228)
at org.apache.wicket.markup.html.form.Form$FormModelUpdateVisitor.component(Form.java:198)
at org.apache.wicket.util.visit.Visits.visitPostOrderHelper(Visits.java:274)
at org.apache.wicket.util.visit.Visits.visitPostOrderHelper(Visits.java:262)
at org.apache.wicket.util.visit.Visits.visitPostOrder(Visits.java:245)
at org.apache.wicket.markup.html.form.FormComponent.visitComponentsPostOrder(FormComponent.java:422)
at org.apache.wicket.markup.html.form.Form.internalUpdateFormComponentModels(Form.java:1793)
at org.apache.wicket.markup.html.form.Form.updateFormComponentModels(Form.java:1757)
at org.apache.wicket.markup.html.form.Form.process(Form.java:913)
at org.apache.wicket.markup.html.form.Form.onFormSubmitted(Form.java:770)
at org.apache.wicket.markup.html.form.Form.onFormSubmitted(Form.java:703)
... 27 more
I think its some of the Ajax code breaking, since my SelectAllCheckBox button is also failing. Any ideas why? Is this even the best way to handle such a use case?
Your Checkgroup does not have a Model, thus Wicket can't copy the current state of the Model into a null object. You should use the constructor with an additional parameter representing the Model you want to store the value in.
I am trying to translate data from server to client (GXT Grid).
On the server side I have a List with data and its ok.
Then I implement RPC methods and suppose that its ok too. Here is code:
GWTService
#RemoteServiceRelativePath("gwtservice")
public interface GWTService extends RemoteService {
public List<WebasystProductData> getWebasystProductData();
}
GWTServiceAsynch
public interface GWTServiceAsync {
public void getWebasystProductData(AsyncCallback<List<WebasystProductData>> callback);
}
GWTServiceImpl
public class GWTServiceImpl extends RemoteServiceServlet implements GWTService {
//private Map<String, WebasystProductData> productData;
public List<WebasystProductData> getWebasystProductData() {
WebasystConnection waConn = new WebasystConnection();
List<WebasystProductData> waPD = waConn.getWebasystProductData();
return waPD;
}
Then I implement proxy using my beanmodel, beanmodelreader, listloader, listore and grid.
...
rpc = RpcInit.initRpc();
RpcProxy<BeanModel> proxy = new RpcProxy<BeanModel>() {
#Override
public void load(Object loadConfig, AsyncCallback callback) {
rpc.getWebasystProductData(callback);
}
};
BeanModelReader reader = new BeanModelReader();
BaseListLoader loader = new BaseListLoader(proxy, reader);
ListStore<BeanModel> store = new ListStore<BeanModel>(loader);
List<ColumnConfig> col = new ArrayList<ColumnConfig>();
ColumnConfig column = new ColumnConfig();
column.setId("productIdWA");
column.setHeader("ProductID");
column.setWidth(50);
col.add(column);
column = new ColumnConfig();
column.setId("productNameWA");
column.setHeader("productName");
column.setWidth(120);
col.add(column);
column = new ColumnConfig();
column.setId("productPriceWA");
column.setHeader("productPrice");
column.setWidth(80);
col.add(column);
column = new ColumnConfig();
column.setId("categoryIdWA");
column.setHeader("categoryID");
column.setWidth(80);
column.setAlignment(HorizontalAlignment.RIGHT);
col.add(column);
When start my app - no data inside grid. Dont know whats the problem, no errors...
Suppose the problem is in client code
The Grid doesn't do an initial laod by its self. Did you call com.extjs.gxt.ui.client.data.Loader#load ?
RpcProxy<List<WebasystProductData>> proxy= new RpcProxy<List<WebasystProductData>>() {
#Override
protected void load(Object loadConfig,AsyncCallback<List<WebasystProductData>> callback) {
getWebasystProductData(config,callback);
}
};
BeanModelReader reader = new BeanModelReader();
ListLoader<ListLoadResult<ModelData>> loader = new BaseListLoader<ListLoadResult<ModelData>>(proxy, reader);
ListStore<BeanModel> store = new LisStore<BeanModel>(loader);
then just:
Grid<BeanModel> grid = new Grid<BeanModel>(store,column);
grid.addListener(Events.Attach, new Listener<GridEvent<BeanModel>>() {
public void handleEvent(GridEvent<BeanModel> be) {
loader.load();
}
});
Remember that your Pojo need to implements the BeanModelTag interface
and the
column = new ColumnConfig();
column.setId("XXX");
XXX need to be the same as your Pojo properties
I'm trying to set the selected records of a ListGrid table object in SmartGWT, but I can't find any way of doing it. I know there's a getSelectedRecords() function, but no matching setSelectedRecords(). I tried to see if set/getSelectedState() would work, but GWT complains about needing a primary key and a DataSource object. Is there any way to set the selection of a ListGrid?
For this you can use one of the selectRecords() methods, like so:
public void onModuleLoad()
{
VLayout main = new VLayout();
final ListGrid grid = new ListGrid();
grid.setHeight(500);
grid.setWidth(400);
grid.setFields(new ListGridField("name", "Name"));
grid.setData(createRecords());
final IButton button = new IButton("Select some");
button.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event)
{
grid.selectRecords(new int[]{2, 3}); //This will select index 2 and 3
}
});
main.addMember(grid);
main.addMember(button);
RootPanel.get().add(main);
}
private ListGridRecord[] createRecords()
{
return new ListGridRecord[]{
createRecord("monkey"),
createRecord("banana"),
createRecord("orange"),
createRecord("sun")
};
}
private ListGridRecord createRecord(String name)
{
ListGridRecord record = new ListGridRecord();
record.setAttribute("name", name);
return record;
}