Error: Fields cannot be added to a DataSource after the underlying component created

I’m new to using SmartGWTEE and I’m getting this… “Error: Fields cannot be added to a DataSource after the underlying component has been created.”

I understand that I can’t use setFields twice but is there another solution to solve this? I’m using MySQL for this project.

public class Student extends DynamicForm {

	public Student() {

		final DynamicForm form1 = this;
		final DynamicForm form2 = new DynamicForm();
		
		form1.setItemLayout(FormLayoutType.ABSOLUTE);

		form1.setSize("100%", "100%");
		form2.setHeight("123px");
        		
		DataSource dataSource = DataSource.get("user");
		
		// Student List Grid
		final ListGrid listGrid = new ListGrid();
		listGrid.setDataSource(dataSource);
		listGrid.setShowFilterEditor(true);
		listGrid.setAutoFetchData(true);
		listGrid.setCanEdit(true);
		listGrid.setCanRemoveRecords(true);
		listGrid.setFields(
				new ListGridField("lastname", "Last Name"),
				new ListGridField("firstname", "First Name")  
		);
		listGrid.addRecordClickHandler(new RecordClickHandler() {
			public void onRecordClick(RecordClickEvent event) {
				form2.reset();
				form2.editSelectedData(listGrid);
			}
		});
		listGrid.setRect(6, 6, 200, 500);
		form1.addChild(listGrid);
  
		// Account Tab
		TabSet tabSet = new TabSet();
		tabSet.setRect(212, 6, 850, 500);
		
		Tab tab = new Tab("Account");
		
		form2.setIsGroup(true);
		dataSource.setFields(
				new DataSourceTextField("username", "User Name"),
				new DataSourceTextField("firstname", "First Name"),
				new DataSourceTextField("lastname", "Last Name")
		);
		
		form2.setDataSource(dataSource);

		tab.setPane(form2);
		tabSet.addTab(tab);

		form1.addChild(tabSet);
	}
}

Just call setFields() before providing the DataSource to any components.

I tried to move the setFields before calling setDataSource. It still showed all fields in the dynamicform from the user.ds.xml. How can I override it so it only shows the data I already set in the setFields?

See the QuickStart Guide, Data Binding chapter.

Thanks Isomorphic but the guide only provided basic setup and it doesn’t solve the problem I’m having.

Here are the snippets of my code where the problem is originating from.

listGrid.setFields(
        new ListGridField("lastname", "Last Name"),
	new ListGridField("firstname", "First Name")  
);
listGrid.setDataSource(dataSource);

....
....

dataSource.setFields(
	new DataSourceTextField("username", "User Name"),
	new DataSourceTextField("firstname", "First Name"),
	new DataSourceTextField("lastname", "Last Name")
);
form2.setDataSource(dataSource);

As you can see I have ListGrid for two fields and DynamicForm for three fields. If I comment out both setFields and it will show all fields including PK which I do not want. If I don’t comment out both setFields and it’ll generate the error as I mentioned above. I want the ability to have direct control of the textfields by hiding it depending on user’s security level. Is there a easier workaround for this?

No really, read the Data Binding chapter. It covers exactly this. If you think it doesn’t you probably read something else and thought it was called the quick start - get the QuickStart Guide here.

Thanks Isomorphic. You were correct that I overlooked something in Data Binding. I made changes to my code and now it works! Cheers!

form2.setFields(new TextItem[] {
	new TextItem("username", "User Name"),
	new TextItem("firstname", "First Name"),
	new TextItem("lastname", "Last Name")
});
form2.setDataSource(dataSource);