Dear Isomorphic Team, I'm having trouble with the TileGrid-Component. My UI heavily relies on thsis component, so this is quite urgent and I hope, you can shed some light on a few things, see below.
I've provide a test case for you. I'm working with the latest production build (5.0p) on GWT 2.6, testing on Chrome in Super Dev Mode.
1. RecordContextClick on tiles throws an error
- Related to http://forums.smartclient.com/showthread.php?t=31328&highlight=TileGrid
- An error will be logged to the DevConsole on every RecordContextClick
- On record context click, the respective tile will be selected and the selectionChangedHandler will fire. I have a use case where I want to show a context menu for a tile without the selectionChangedHandler to fire. Unfortunately it is not possible to cancel the recordContextClick-Event without suppressing the context menu at all. How can I accomplish this?
2. Tile Hover Components
- Related to http://forums.smartclient.com/showthread.php?t=30898
- Hover Components work for the TileGrid itself.
- Tile Hover Components will not work when configured setTileProperties-API
- Hover Components do work, when implemented by a child component of SimpleTile, e.g. a DynamicForm
3. Tile Recycling
- UseCase: I'd like to be able to define a tileContructor using the setTileContructor-API and use the updateTile-API to keep my CustomTiles up to date.
- The new createTile-API and updateTile-API are not usable i.e. these two functions exist in the Java-API but NOT in the JavaScript-Modules (see TileGrid.js). Hence, overriding these methods is useless because they will never be called, right? So, what is meant by "If defined, this method will be called when a new tile is required." (from JavaDoc)? Should I use JSNI to define these methods on each TileGrid instance? I guess not. Could you please explain!
- Tile recycling will only work reliably for the internally rendered DetailViewer that is showing tile record data. Have a look at TileGrid #2 in the TestCase.
Here is the TestCase.
It took me some hours to research these questions and elaborate on feasible workarounds, however I'm quite stuck at the moment. I really appreciate your suggestions.
I've provide a test case for you. I'm working with the latest production build (5.0p) on GWT 2.6, testing on Chrome in Super Dev Mode.
1. RecordContextClick on tiles throws an error
- Related to http://forums.smartclient.com/showthread.php?t=31328&highlight=TileGrid
- An error will be logged to the DevConsole on every RecordContextClick
- On record context click, the respective tile will be selected and the selectionChangedHandler will fire. I have a use case where I want to show a context menu for a tile without the selectionChangedHandler to fire. Unfortunately it is not possible to cancel the recordContextClick-Event without suppressing the context menu at all. How can I accomplish this?
Code:
18:31:01.584:MDN3:WARN:Log:Call to Super for method: handleRightMouseDown failed on: [SimpleTile ID:isc_HelloWorld_1_0_tile_3]: couldn't find a superclass implementation of : SimpleTile.handleRightMouseDown [a][c]SimpleTile.invokeSuper(clazz=>null, methodName=>"handleRightMouseDown", a=>undef, b=>undef, c=>undef, d=>undef, e=>undef, f=>undef, g=>undef, h=>undef, i=>undef, j=>undef, lastArg=>undef) @ Class.js:1556:47 [a][c]SimpleTile.Super(methodName=>"handleRightMouseDown", args=>[object Arguments], nativeArguments=>undef) @ Class.js:1404:21 [a]SimpleTile.handleRightMouseDown() @ TileGrid.js:1054:25 [c]EventHandler.bubbleEvent(target=>[SimpleTile ID:isc_HelloWorld_1_0_tile_3], eventType=>"rightMouseDown", eventInfo=>null, targetIsMasked=>false) @ EventHandler.js:5123:44 EventHandler.doHandleMouseDown(DOMevent=>[object MouseEvent], syntheticEvent=>undef) @ EventHandler.js:1810:28 EventHandler.observation() @ Class.js:2476:68 [c]EventHandler.handleMouseDown(DOMevent=>[object MouseEvent], syntheticEvent=>undef) @ EventHandler.js:1643:26 [c]EventHandler.dispatch(handler=>[c]EventHandler.handleMouseDown(), event=>[object MouseEvent]) @ EventHandler.js:6544:34 HTMLDocument.eval(event=>[object MouseEvent]) @ [no file]:3:127
- Related to http://forums.smartclient.com/showthread.php?t=30898
- Hover Components work for the TileGrid itself.
- Tile Hover Components will not work when configured setTileProperties-API
- Hover Components do work, when implemented by a child component of SimpleTile, e.g. a DynamicForm
3. Tile Recycling
- UseCase: I'd like to be able to define a tileContructor using the setTileContructor-API and use the updateTile-API to keep my CustomTiles up to date.
- The new createTile-API and updateTile-API are not usable i.e. these two functions exist in the Java-API but NOT in the JavaScript-Modules (see TileGrid.js). Hence, overriding these methods is useless because they will never be called, right? So, what is meant by "If defined, this method will be called when a new tile is required." (from JavaDoc)? Should I use JSNI to define these methods on each TileGrid instance? I guess not. Could you please explain!
- Tile recycling will only work reliably for the internally rendered DetailViewer that is showing tile record data. Have a look at TileGrid #2 in the TestCase.
Here is the TestCase.
Code:
public class HelloWorld implements EntryPoint { public static class CustomTileForm extends DynamicForm { public CustomTileForm() { super(); setBorder("1px solid black"); setHeight(HEIGHT); setWidth(WIDTH); setNumCols(1); setColWidths("*"); setCanHover(true); setHoverMoveWithMouse(true); setShowHoverComponents(true); FormItem idField = new StaticTextItem(TestRecord.ID); idField.setShowTitle(false); FormItem nameField = new StaticTextItem(TestRecord.NAME); nameField.setShowTitle(false); setFields(idField, nameField); } @Override public Canvas getHoverComponent() { return createDefaultHoverComponent("TileForm"); } } static class CustomTileGrid extends TileGrid { public CustomTileGrid() { super(); setDataSource(new DS()); setBackgroundColor("lightGray"); setBorder("1px solid black"); setWidth(300); setHeight(300); setTileHeight(HelloWorld.HEIGHT); setTileWidth(HelloWorld.WIDTH); setAutoFetchData(true); addRecordContextClickHandler(new RecordContextClickHandler() { private Menu createContextMenu() { return new Menu(); } @Override public void onRecordContextClick(RecordContextClickEvent event) { setContextMenu(createContextMenu()); } }); } } public static class CustomTileWrapper extends SimpleTile { private CustomTileForm editor; public CustomTileWrapper() { super(); setCanHover(true); setShowHoverComponents(true); addDrawHandler(new DrawHandler() { @Override public void onDraw(DrawEvent event) { addChild(getOrCreateEditor()); updateContents(getTileRecord()); } }); } @Override public Canvas getHoverComponent() { return createDefaultHoverComponent("TileWrapper"); } public CustomTileForm getOrCreateEditor() { if (editor == null) { editor = new CustomTileForm(); } return editor; } public Record getTileRecord() { return getAttributeAsRecord("record"); } public void updateContents(Record record) { getOrCreateEditor().editRecord(record); } } static class DS extends DataSource { public DS() { setClientOnly(true); DataSourceTextField id = new DataSourceTextField(TestRecord.ID); id.setPrimaryKey(true); DataSourceTextField name = new DataSourceTextField(TestRecord.NAME); setFields(id, name); int recCount = 1000; Record[] data = new Record[recCount]; for (int i = 0; i < recCount; i++) { data[i] = new TestRecord(String.valueOf(i), "Name_" + String.valueOf(i)); } setCacheData(data); } } public static class TestRecord extends Record { public static final String ID = "id"; public static final String NAME = "name"; public TestRecord(String id, String name) { setAttribute(ID, id); setAttribute(NAME, name); } } public interface TileMetaFactory extends BeanFactory.MetaFactory { BeanFactory<CustomTileWrapper> getCustomTileWrapper(); } static int HEIGHT = 120; static int WIDTH = 120; public static Canvas createDefaultHoverComponent(String contents) { Canvas canvas = new Canvas(); canvas.setContents("Hover Generated by " + contents); return canvas; } @Override public void onModuleLoad() { HLayout testLayout = new HLayout(10); //use default approach with TileProperties-Config final TileGrid tg1 = new CustomTileGrid() { @Override public Canvas getHoverComponent() { return createDefaultHoverComponent("TileGrid#1"); } }; tg1.setCanHover(true); tg1.setShowHoverComponents(true); Canvas c = new Canvas() { @Override public Canvas getHoverComponent() { //WILL NOT WORK return createDefaultHoverComponent("Plain Old SimpleTile"); } }; c.setCanHover(true); c.setShowHoverComponents(true); tg1.setTileProperties(c); //use factory-based approach GWT.create(TileMetaFactory.class); final TileGrid tg2 = new CustomTileGrid() { @Override public Canvas getHoverComponent() { return createDefaultHoverComponent("TileGrid#2"); } //WILL NEVER BE CALLED, BECAUSE NEITHER updateTile(..) NOR createTile(..) are defined on the TileGrid Instance. //However, HOW SHOULD THESE METHODS BE DEFINED? @Override public void updateTile(Record record, Integer tileIndex, Canvas reclaimedTile) { CustomTileWrapper wrapper = (CustomTileWrapper) reclaimedTile; wrapper.updateContents(record); } }; tg2.setCanHover(true); tg2.setShowHoverComponents(true); tg2.setTileConstructor(CustomTileWrapper.class.getName()); testLayout.addMember(tg1); testLayout.addMember(tg2); testLayout.draw(); } }
It took me some hours to research these questions and elaborate on feasible workarounds, however I'm quite stuck at the moment. I really appreciate your suggestions.
Comment