Designer view of custom tab panel

GWT Designer allows you to quickly create the modules, composites, panels, remote services and other elements that comprise Google Web Tookit applications.

Moderators: Konstantin.Scheglov, gnebling, Alexander.Mitin, jwren, Eric Clayberg

Designer view of custom tab panel

Postby gdunkle » Wed Jul 25, 2007 4:21 pm

GWT Designer 2.0 from 2007.06.29
GWT 1.3.3

I'm working on a a custom tab panel widget but I'm having difficulties using it in the design view. In an attempt to track down the problem I've basically cut and pasted gwt's tab panel code into my class so it's exactly the same except it has a different name. I can add the widget to the pallet and i can add the widget to the root panel but it doesn't demonstrate the same behavior in the designer as the standard tab panel. For instance i can see the tabBar and deckPanel as children of the custom tab panel whereas in the standard tab panel they don't show up. What is really a problem though is that if i try to add a child to the custom tab panel using the customerTabPanel.add(someChildWidget, "Tab1"); method nothing happens in the design view. There are no error message in the log file. I'm assuming that somewhere internally in gwt designer certain widgets are designated with certain behaviors for the design view. I was wondering if there was a way to specify such behavior for custom widgets like my custom tab panel.

Thanks
gdunkle
 
Posts: 4
Joined: Tue Jul 24, 2007 1:29 pm

Re: Designer view of custom tab panel

Postby Eric Clayberg » Thu Jul 26, 2007 4:15 am

GWT Designer has significant meta-level knowledge about all of the built-in panel types in GWT. It has to in order to provide a rich editing experience as none of that edit-time behavior is encoded into those widgets by GWT itself.

If you simply copy the code for TabPanel and paste it into a new class, Designer will treat it exactly like any other custom Composite subclass (which it is). In that case it will show the tabBar and deckPanel children as they are exposed as public children by the class (in the normal TabPanel, Designer hides those children on purpose). Furthermore, the add(Widget, String) method has no special meaning for a Composite, so it does not result in any child associations. It does have meaning for a real TabPanel, so Designer knows what to do with it.

If you want to create yoru own custom TabPanel and have Designer treat it like a normal TabPanel, you should subclass TabPanel rather than copy it. As a subclass, it will inherit all of the edit-time behavior that a normal TabPanel has.
Eric Clayberg
Software Engineering Manager
Google
http://code.google.com/webtoolkit/download.html

Author: "Eclipse Plug-ins"
http://www.qualityeclipse.com
Eric Clayberg
Moderator
 
Posts: 4503
Joined: Tue Sep 30, 2003 6:39 am
Location: Boston, MA USA

Postby gdunkle » Thu Jul 26, 2007 5:08 am

OK so I tried extending TabPanel and now i'm getting this exception in the logs.

Code: Select all
!ENTRY com.swtdesigner 4 4 2007-07-26 09:01:03.802
!MESSAGE Designer internal error [6.4.0.20070709071256]: com.swtdesigner.properties.PropertyException: java.lang.IllegalArgumentException: object is not an instance of declaring class
!STACK 0
org.apache.commons.lang.exception.NestableError: com.swtdesigner.properties.PropertyException: java.lang.IllegalArgumentException: object is not an instance of declaring class
        at com.swtdesigner.model.swing.properties.custom.DesignTimeHelper.execute(DesignTimeHelper.java:56)
        at com.swtdesigner.model.JavaInfo.notifyPropertyChanged(JavaInfo.java:5567)
        at com.swtdesigner.model.JavaInfo.notifyPropertyChanged(JavaInfo.java:5549)
        at com.swtdesigner.gef.common.property.DesignerEditorPropertyComposite.handleRootNodeSelected(DesignerEditorPropertyComposite.java:662)
        at com.swtdesigner.gef.common.property.DesignerEditorPropertyComposite.updatePropertyComposite(DesignerEditorPropertyComposite.java:865)
        at com.swtdesigner.gef.DesignerEditor.parseCompilationUnit(DesignerEditor.java:1163)
        at com.swtdesigner.gef.DesignerEditor.refreshDesignView(DesignerEditor.java:1219)
        at com.swtdesigner.gef.DesignerEditor$14.widgetSelected(DesignerEditor.java:954)
        at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:227)
        at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:66)
        at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1101)
        at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3319)
        at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:2971)
        at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2389)
        at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2353)
        at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2219)
        at org.eclipse.ui.internal.Workbench$4.run(Workbench.java:466)
        at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:289)
        at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:461)
        at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
        at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:106)
        at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:153)
        at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:106)
        at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:76)
        at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:363)
        at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:176)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:585)
        at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:504)
        at org.eclipse.equinox.launcher.Main.basicRun(Main.java:443)
        at org.eclipse.equinox.launcher.Main.run(Main.java:1169)
Caused by: com.swtdesigner.properties.PropertyException: java.lang.IllegalArgumentException: object is not an instance of declaring class
        at com.swtdesigner.gwt.model.widgets.panel.RootPanelInfo.createGUIComponent(RootPanelInfo.java:72)
        at com.swtdesigner.model.JavaInfo$19.execute(JavaInfo.java:5572)
        at com.swtdesigner.model.swing.properties.custom.DesignTimeHelper.execute(DesignTimeHelper.java:54)
        ... 32 more
Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:585)
        at com.swtdesigner.gwt.model.widgets.support.GWTState.call_TabPanel_add(GWTState.java:1014)
        at com.swtdesigner.gwt.model.widgets.panel.support.TabPanelSupport.applyWidgetProperties(TabPanelSupport.java:32)
        at com.swtdesigner.gwt.model.widgets.panel.AbstractContainerInfo.widget_applyProperties(AbstractContainerInfo.java:93)
        at com.swtdesigner.gwt.model.widgets.WidgetInfo.createWidget(WidgetInfo.java:172)
        at com.swtdesigner.gwt.model.widgets.panel.AbstractContainerInfo.createWidget(AbstractContainerInfo.java:175)
        at com.swtdesigner.gwt.model.widgets.panel.AbstractContainerInfo.createChildrenWidgets(AbstractContainerInfo.java:195)
        at com.swtdesigner.gwt.model.widgets.panel.AbstractContainerInfo.createWidget(AbstractContainerInfo.java:176)
        at com.swtdesigner.gwt.model.widgets.panel.TabPanelInfo.createWidget(TabPanelInfo.java:107)
        at com.swtdesigner.gwt.model.widgets.panel.AbstractContainerInfo.createChildrenWidgets(AbstractContainerInfo.java:195)
        at com.swtdesigner.gwt.model.widgets.panel.RootPanelInfo.createGUIComponent(RootPanelInfo.java:69)
        ... 34 more



Looks like it has something to so with calling initTab within my custom tab panel. If I comment that out error doesn't happen but the designer won't show the component correctly.

Current constructor looks like this...

Code: Select all
...
public class MyTabPanel extends TabPanel implements TabListener, SourcesTabEvents, HasWidgets, IndexedPanel
{
    private WidgetCollection children = new WidgetCollection(this);
    private DeckPanel deck = new DeckPanel();
    private TabBar tabBar = new TabBar();
    private TabListenerCollection tabListeners;

    /**
     * Creates an empty tab panel.
     */
    public MyTabPanel()
    {
        super();
        VerticalPanel panel = new VerticalPanel();
        panel.add(tabBar);
        panel.add(deck);
        panel.setCellHeight(deck, "100%");
        tabBar.setWidth("100%");
        tabBar.addTabListener(this);
        initWidget(panel);
        setStyleName("gwt-TabPanel");
        deck.setStyleName("gwt-TabPanelBottom");
     
    }
...


Also I thought is was not advisable to directly extend a component? I'm not knocking your previous answer (I just want the thing to work and if i have to directly extend that's fine with me). I'm just suggesting that giving the end user the ability to imply "meta-level knowledge" for their custom components so that the designer has a better idea how to render them might be a nice feature for future releases (if it's plausible). Maybe the ability to apply annotations (javadoc style of course since java 5 code isn't supported by gwt) or have an xml descriptor that gwt designer reads for customer components that need a certain design time behavior. Your product is great but loses much of it's power when the design view fails.

Thanks
gdunkle
 
Posts: 4
Joined: Tue Jul 24, 2007 1:29 pm

Postby Eric Clayberg » Thu Jul 26, 2007 2:17 pm

gdunkle wrote:Looks like it has something to so with calling initTab within my custom tab panel. If I comment that out error doesn't happen but the designer won't show the component correctly. Current constructor looks like this.

Hmmm. That looks basically the same as the constructor for the standard TabPanel - which basically means that you are duplicating a lot of behavior that should run only once.

It would be helpful to know why you want to create a custom TabPanel (e.g., what differentiates it from a standard TabPanel?). It would also be helpful to see the all of the code for the class rather than just the constructor.
Eric Clayberg
Software Engineering Manager
Google
http://code.google.com/webtoolkit/download.html

Author: "Eclipse Plug-ins"
http://www.qualityeclipse.com
Eric Clayberg
Moderator
 
Posts: 4503
Joined: Tue Sep 30, 2003 6:39 am
Location: Boston, MA USA

Postby gdunkle » Thu Jul 26, 2007 2:54 pm

The reason i want a custom tab panel is that i would like to wrap the deck and each tab in the tab bar with the RoundedPanel from http://gwt.bouwkamp.com/ as well as make some other layout changes...ability to specify tabs bar at top or bottom of the panel etc etc. The reason i initially started by copying the standard tab panel is because the deck, tabBar and vertical panel that lay them out are all private so there is no way to get to them via extension. I was able to get to get all this working as a composite but like i said it just doesn't play nice with the design view. I was hacking around today with the designer and tried adding my Composite tab panel to the GWTPalette.xml file

Code: Select all
<entry name="MyTabPanel"
                     description="A panel that represents a tabbed set of pages, each of which contains another widget. Its child widgets are shown as the user selects the various tabs associated with them. The tabs can contain arbitrary HTML."
                     icon="${PANEL_ICONS}tab_panel.gif">
                     <factory2 factoryClass="${FACTORY}"
                        model="${PANEL_PKG}TabPanelInfo"
                        widget="test.client.client.MyTabPanel"/>


it shows up in the palette under the standard widgets. When i try to add it to the root panel i get the same " object is not an instance of declaring class ". It looks like designer stores the actual Method object for the various tab panel methods selectTab, add(w, tabText), etc and knows to call them if the widget is actually a TabPanel. If there was just some hook into the designer to specify those methods for custom widgets or something. Extending TabPanel doesn't seem to work i think because initWidget ends up being called twice if your not going to use the layout of the parent class . I'm not trying to duplicate the tab panel exactly...I'm trying to make a slightly different tab panel that will still behave like a tab panel in the design view.
gdunkle
 
Posts: 4
Joined: Tue Jul 24, 2007 1:29 pm

Postby gdunkle » Thu Jul 26, 2007 3:09 pm

Along the same lines http://gwt.bouwkamp.com/ has a Vertical Tab panel which lines the tabs up vertically. That component also experiences the same problems as my custom tab panel in the design view.
gdunkle
 
Posts: 4
Joined: Tue Jul 24, 2007 1:29 pm

Postby Eric Clayberg » Thu Aug 02, 2007 4:39 am

gdunkle wrote:The reason i want a custom tab panel is that i would like to wrap the deck and each tab in the tab bar with the RoundedPanel from http://gwt.bouwkamp.com/ as well as make some other layout changes...ability to specify tabs bar at top or bottom of the panel etc etc. The reason i initially started by copying the standard tab panel is because the deck, tabBar and vertical panel that lay them out are all private so there is no way to get to them via extension. I was able to get to get all this working as a composite but like i said it just doesn't play nice with the design view.

In the latest build, we added some support from custom TabPanels modelled after the original TabPanel (the class name must end with "TabPanel"), so your original implementation should now work better. For example...

Image

gdunkle wrote:I was hacking around today with the designer and tried adding my Composite tab panel to the GWTPalette.xml file

There is no need to do that because Designer already includes a nice Palette Manager that can be used to add widgets to the palette.

Image
Eric Clayberg
Software Engineering Manager
Google
http://code.google.com/webtoolkit/download.html

Author: "Eclipse Plug-ins"
http://www.qualityeclipse.com
Eric Clayberg
Moderator
 
Posts: 4503
Joined: Tue Sep 30, 2003 6:39 am
Location: Boston, MA USA


Return to GWT Designer

Who is online

Users browsing this forum: No registered users and 3 guests