We have created a custom control that extends TextItem to find a file on the Server. This control works perfectly when it is embedded in a DynamicForm (both in smartGWTPro 2.5 and smartGWTPower 3.0)
This control also worked perfectly with smartGWTPro 2.5 when used with a ValuesManager linking two dynamic forms on separate tabs. We started having problems when we upgraded to smartGWTPower 3.0 when the control is used with a ValuesManager linking two dynamic forms.
Code Below for the Tabbed GUI:
Code below for the custom control:
We receive the following stack trace on module load:
18:07:10.688:INFO:Log:initialized
18:07:10.691:WARN:Page:NOTE: isc.Page.getWidth() called before <BODY> tag was written out -- value cannot be determined. Returning 500
18:07:10.691:WARN:Page:NOTE: isc.Page.getHeight() called before <BODY> tag was written out -- value cannot be determined. Returning 500
18:07:10.968:WARN:Log:New Class ID: 'EditPane' collides with ID of existing Class object '[DataSource ID:EditPane]'. Existing object will be replaced.
This conflict would be avoided by disabling ISC Simple Names mode. See documentation for further information.
18:07:11.020:INFO:Log:isc.Page is loaded
18:07:37.339:WARN:DynamicForm:isc_DynamicForm_0:destroyed FormItem passed to setItems()/addItem(): FormItems cannot be re-used with different DynamicForms
18:07:37.386:WARN:Log:Error:
''this.form' is null or not an object'
in http://127.0.0.1:8888/dsdmi/sc/modules/ISC_Forms.js
at line 1572
FormItem.isDisabled()
FormItem.iconIsDisabled(_1=>Obj{name:_0}, _2=>undef)
FormItem.$36c(_1=>Obj{name:_0})
FormItem.$14v()
FormItem.init([TextItem ID:isc_TextItem_0 name:excelFileName], undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef)
Class.invokeSuper(_1=>null, _2=>"init", _3=>undef, _4=>undef, _5=>undef, _6=>undef, _7=>undef, _8=>undef, _9=>undef, _10=>undef)
Class.Super(_1=>"init", _2=>Obj{length:13}, _3=>undef)
TextItem.init([TextItem ID:isc_TextItem_0 name:excelFileName], undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef)
Class.completeCreation(_1=>[TextItem ID:isc_TextItem_0 name:excelFileName], _2=>undef, _3=>undef, _4=>undef, _5=>undef, _6=>undef, _7=>undef, _8=>undef, _9=>undef, _10=>undef, _11=>undef, _12=>undef, _13=>undef)
DynamicForm.createItem(_1=>[TextItem ID:isc_TextItem_0 name:excelFileName], _2=>"TextItem")
DynamicForm.$10l(_1=>Array[1], _2=>null, _3=>true, _4=>undef)
DynamicForm.setItems(_1=>Array[1], _2=>undef)
DynamicForm.setFields(_1=>Array[0])
Canvas.setDataSource(_1=>[DataSource ID:DataImportElementDS], _2=>Array[0])
** recursed on Class.invokeSuper
Would very much appreciate support on this problem.
I have a very basic Eclipse project (4 client-side and 4 server-side classes) that re-produces the problem based on DataSourceDMI in the samples that I can forward if that is helpful.
This control also worked perfectly with smartGWTPro 2.5 when used with a ValuesManager linking two dynamic forms on separate tabs. We started having problems when we upgraded to smartGWTPower 3.0 when the control is used with a ValuesManager linking two dynamic forms.
Code Below for the Tabbed GUI:
Code:
public class DataSourceDMI implements EntryPoint {
private DataSource dataImportElementDataSource;
/** smartGWT ValuesManager used to coordinate between multiple forms linked to the same DataImportElementDS datasource. */
private ValuesManager dataImportElementValueManager;
/**
* This is the entry point method.
*/
public void onModuleLoad() {
Log.info("In module load");
if (!GWT.isScript()) {
KeyIdentifier debugKey = new KeyIdentifier();
debugKey.setCtrlKey(true);
debugKey.setKeyName("m");
Page.registerKey(debugKey, new KeyCallback() {
public void execute(String keyName) {
SC.showConsole();
}
});
}
VStack vStack = new VStack();
vStack.setLeft(175);
vStack.setTop(75);
vStack.setWidth("70%");
vStack.setMembersMargin(20);
Label topLabel = new Label("Test");
vStack.addMember(topLabel);
dataImportElementDataSource = DataSource.get("DataImportElementDS");
Log.info("Got DataImportElements datasource " + dataImportElementDataSource);
dataImportElementValueManager = new ValuesManager(); // used to combine form data management across tabs
dataImportElementValueManager.setDataSource(dataImportElementDataSource);
TabSet tabSet = new TabSet();
tabSet.setSize("100%", "*");
// first tab
Tab tab1 = new Tab("Tab1");
DynamicForm form1 = setupForm1();
tab1.setPane(form1);
tabSet.addTab(tab1);
//second tab
Tab tab2 = new Tab("tab2");
DynamicForm form2 = setupForm2();
tab2.setPane(form2);
tabSet.addTab(tab2);
vStack.addMember(tabSet);
vStack.draw();
}
/** Create the form for tab1 */
private DynamicForm setupForm1(){
Log.info("Creating form");
DynamicForm form = new DynamicForm();
form.setValuesManager(dataImportElementValueManager);
form.setNumCols(2);
form.setColWidths(110, "*");
form.setPadding(5);
form.setSize("550", "70");
Log.info("Adding picker");
/** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
final TextItem picker = new ServerSideExcelFilePicker("excelFileName", "Excel File Name");
// if replace line above with the following, no problem encountered
//final TextItem picker = new TextItem("excelFileName", "Excel File Name");
/*** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
picker.setWidth("*");
form.setFields(picker);
return form;
}
/** Create the form for tab1 */
private DynamicForm setupForm2(){
Log.info("Creating form");
DynamicForm form = new DynamicForm();
form.setValuesManager(dataImportElementValueManager);
form.setNumCols(2);
form.setColWidths(110, "*");
form.setPadding(5);
form.setSize("550", "70");
Log.info("Adding picker");
final TextItem item = new TextItem("worksheet", "Excel Worksheet");
item.setWidth("*");
form.setFields(item);
return form;
}
}
Code:
public class ServerSideExcelFilePicker extends ServerSideFilePicker {
public ServerSideExcelFilePicker(String name, String title) {
super(name, title);
Log.info("Constructing Excel file picker.");
this.setFileFilter(".*?xls");
}
}
public class ServerSideFilePicker extends TextItem {
private static Dialog dialog;
private static ServerSideFilePicker currentEditor;
/**
* An optional filter used to limit the files displayed by this file picker. For example, can set to ".xls" to limit returned files to excel files. If is
* null, no filtering done.
*/
private String fileFilter = null;
/**
* Constructor
*
* @param name name of this file picker form item
* @param title String title to associate with this file picker
* @param callingForm the calling form. Required for work-around to trigger change events on calling form when picker value is set programatically.
*/
public ServerSideFilePicker(String name, String title) {
super(name, title);
Log.info("Constructing file picker");
this.setWidth(400);
PickerIcon searchPicker = new PickerIcon(PickerIcon.SEARCH);
setIcons(searchPicker);
addIconClickHandler(new IconClickHandler() {
public void onIconClick(IconClickEvent event) {
Log.info("Responding to click on file picker icon");
// get global coordinates of the clicked picker icon
Rectangle iconRect = getIconPageRect(event.getIcon());
// remember what editor is active, so we can set its value from the picker dialog
ServerSideFilePicker.currentEditor = ServerSideFilePicker.this;
// get the current value of the text item. Send to the dialog as the current file to display
String directory = ServerSideFilePicker.currentEditor.getValueAsString();
// lazily create the the server side directory display dialog when the picker is first used
if (ServerSideFilePicker.dialog == null) {
Log.info("Dialog is null, creating new dialog.");
dialog = new ServerSideFileDisplayDialog(directory, fileFilter);
} else {
// TODO send new criteria to dialog to change files displayed
}
// show the picker dialog
Log.info("About to show dialog");
ServerSideFilePicker.showDialog(iconRect.getLeft(), iconRect.getTop());
}
});
}
public String getFileFilter() {
return fileFilter;
}
/**
* A regular expression used to filter the files returned by this user interface.
*
* @param fileFilter
*/
public void setFileFilter(String fileFilter) {
this.fileFilter = fileFilter;
}
// set the specified value and dismiss the picker dialog
protected static void setCurrentValue(String value) {
String oldVal = currentEditor.getValueAsString();
currentEditor.setValue(value);
dialog.hide();
}
/** Work around to force setValue to fire a change event.
*
*/
private native void fireChangedEvent() /*-{
var obj = null;
obj = this.@com.smartgwt.client.core.DataClass::getJsObj()();
var selfJ = this;
if (obj.getValue === undefined) {
return;
}
var param = {
"form" : obj.form,
"item" : obj,
"value" : obj.getValue()
};
var event = @com.smartgwt.client.widgets.form.fields.events.ChangedEvent::new(Lcom/google/gwt/core/client/JavaScriptObject;)(param);
selfJ.@com.smartgwt.client.core.DataClass::fireEvent(Lcom/google/gwt/event/shared/GwtEvent;)(event);
}-*/;
@Override
public void setValue(String value) {
super.setValue(value);
Log.info("In overidden setValue method. Firing changge event");
fireChangedEvent();
}
// show the picker dialog at the specified position
protected static void showDialog(int left, int top) {
dialog.show();
dialog.moveTo(left, top);
}
protected static void hideDialog() {
dialog.hide();
}
18:07:10.688:INFO:Log:initialized
18:07:10.691:WARN:Page:NOTE: isc.Page.getWidth() called before <BODY> tag was written out -- value cannot be determined. Returning 500
18:07:10.691:WARN:Page:NOTE: isc.Page.getHeight() called before <BODY> tag was written out -- value cannot be determined. Returning 500
18:07:10.968:WARN:Log:New Class ID: 'EditPane' collides with ID of existing Class object '[DataSource ID:EditPane]'. Existing object will be replaced.
This conflict would be avoided by disabling ISC Simple Names mode. See documentation for further information.
18:07:11.020:INFO:Log:isc.Page is loaded
18:07:37.339:WARN:DynamicForm:isc_DynamicForm_0:destroyed FormItem passed to setItems()/addItem(): FormItems cannot be re-used with different DynamicForms
18:07:37.386:WARN:Log:Error:
''this.form' is null or not an object'
in http://127.0.0.1:8888/dsdmi/sc/modules/ISC_Forms.js
at line 1572
FormItem.isDisabled()
FormItem.iconIsDisabled(_1=>Obj{name:_0}, _2=>undef)
FormItem.$36c(_1=>Obj{name:_0})
FormItem.$14v()
FormItem.init([TextItem ID:isc_TextItem_0 name:excelFileName], undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef)
Class.invokeSuper(_1=>null, _2=>"init", _3=>undef, _4=>undef, _5=>undef, _6=>undef, _7=>undef, _8=>undef, _9=>undef, _10=>undef)
Class.Super(_1=>"init", _2=>Obj{length:13}, _3=>undef)
TextItem.init([TextItem ID:isc_TextItem_0 name:excelFileName], undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef)
Class.completeCreation(_1=>[TextItem ID:isc_TextItem_0 name:excelFileName], _2=>undef, _3=>undef, _4=>undef, _5=>undef, _6=>undef, _7=>undef, _8=>undef, _9=>undef, _10=>undef, _11=>undef, _12=>undef, _13=>undef)
DynamicForm.createItem(_1=>[TextItem ID:isc_TextItem_0 name:excelFileName], _2=>"TextItem")
DynamicForm.$10l(_1=>Array[1], _2=>null, _3=>true, _4=>undef)
DynamicForm.setItems(_1=>Array[1], _2=>undef)
DynamicForm.setFields(_1=>Array[0])
Canvas.setDataSource(_1=>[DataSource ID:DataImportElementDS], _2=>Array[0])
** recursed on Class.invokeSuper
Would very much appreciate support on this problem.
I have a very basic Eclipse project (4 client-side and 4 server-side classes) that re-produces the problem based on DataSourceDMI in the samples that I can forward if that is helpful.
Comment