com.servoy.j2db.server.headlessclient.dataui.WebDataRenderer.java Source code

Java tutorial

Introduction

Here is the source code for com.servoy.j2db.server.headlessclient.dataui.WebDataRenderer.java

Source

/*
 This file belongs to the Servoy development and deployment environment, Copyright (C) 1997-2010 Servoy BV
    
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU Affero General Public License as published by the Free
 Software Foundation; either version 3 of the License, or (at your option) any
 later version.
    
 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
    
 You should have received a copy of the GNU Affero General Public License along
 with this program; if not, see http://www.gnu.org/licenses or write to the Free
 Software Foundation,Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
 */
package com.servoy.j2db.server.headlessclient.dataui;

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Point;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;

import javax.swing.border.Border;
import javax.swing.border.TitledBorder;

import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.IAjaxCallDecorator;
import org.apache.wicket.ajax.calldecorator.AjaxCallDecorator;
import org.apache.wicket.markup.MarkupStream;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.mozilla.javascript.Undefined;

import com.servoy.base.scripting.api.IJSEvent.EventType;
import com.servoy.j2db.ControllerUndoManager;
import com.servoy.j2db.FormController;
import com.servoy.j2db.IApplication;
import com.servoy.j2db.IScriptExecuter;
import com.servoy.j2db.IView;
import com.servoy.j2db.dataprocessing.DataAdapterList;
import com.servoy.j2db.dataprocessing.IDisplay;
import com.servoy.j2db.dataprocessing.IDisplayData;
import com.servoy.j2db.dataprocessing.IFoundSetInternal;
import com.servoy.j2db.dataprocessing.IRecordInternal;
import com.servoy.j2db.dataprocessing.Record;
import com.servoy.j2db.dnd.DRAGNDROP;
import com.servoy.j2db.dnd.JSDNDEvent;
import com.servoy.j2db.persistence.Form;
import com.servoy.j2db.persistence.IDataProviderLookup;
import com.servoy.j2db.persistence.IPersist;
import com.servoy.j2db.server.headlessclient.WebForm;
import com.servoy.j2db.server.headlessclient.dnd.DraggableBehavior;
import com.servoy.j2db.ui.DataRendererOnRenderWrapper;
import com.servoy.j2db.ui.IComponent;
import com.servoy.j2db.ui.IDataRenderer;
import com.servoy.j2db.ui.IProviderStylePropertyChanges;
import com.servoy.j2db.ui.IStylePropertyChanges;
import com.servoy.j2db.ui.ISupportOnRenderCallback;
import com.servoy.j2db.ui.ISupportRowStyling;
import com.servoy.j2db.ui.runtime.IRuntimeComponent;
import com.servoy.j2db.util.ComponentFactoryHelper;
import com.servoy.j2db.util.Debug;
import com.servoy.j2db.util.IDelegate;
import com.servoy.j2db.util.IStyleRule;
import com.servoy.j2db.util.IStyleSheet;
import com.servoy.j2db.util.PersistHelper;
import com.servoy.j2db.util.Utils;

/**
 * The web implementation of the {@link IDataRenderer}
 * 
 * @author jcompagner
 */
public class WebDataRenderer extends WebMarkupContainer implements IDataRenderer, IProviderStylePropertyChanges {
    private static final long serialVersionUID = 1L;

    private Dimension size = new Dimension(0, 0);
    private Point location = new Point(0, 0);
    //   private boolean visible;
    private String tooltiptext;
    //   private Cursor cursor;
    private boolean opaque;
    private Border border;
    private Font font;
    private Color foreground;
    private Color background;
    //   private final IApplication application;
    private DataAdapterList dataAdapterList;
    //   private final Set globalFields = new HashSet();
    private HashMap<IPersist, IDisplay> fieldComponents = new HashMap<IPersist, IDisplay>();
    private final ChangesRecorder jsChangeRecorder = new ChangesRecorder(
            TemplateGenerator.DEFAULT_FIELD_BORDER_SIZE, TemplateGenerator.DEFAULT_FIELD_PADDING);

    private IView parentView;
    private final String formPartName;

    private FormController dragNdropController;
    private final ISupportOnRenderCallback dataRendererOnRenderWrapper;

    /**
     * @param id
     */
    public WebDataRenderer(String id, String formPartName, final IApplication app) {
        super(id);
        //      application = app;
        add(StyleAttributeModifierModel.INSTANCE);
        add(TooltipAttributeModifier.INSTANCE);
        setOutputMarkupPlaceholderTag(true);
        this.formPartName = formPartName;
        dataRendererOnRenderWrapper = new DataRendererOnRenderWrapper(this);
        add(new StyleAppendingModifier(new Model<String>() {
            private static final long serialVersionUID = 1L;

            @Override
            public String getObject() {
                WebForm container = findParent(WebForm.class);
                if (container != null && container.getBorder() instanceof TitledBorder) {
                    int offset = ComponentFactoryHelper.getTitledBorderHeight(container.getBorder());
                    return "top: " + offset + "px;";
                }
                return ""; //$NON-NLS-1$
            }
        }) {
            @Override
            public boolean isEnabled(Component component) {
                if (WebDataRenderer.this.getParent().get(0) != WebDataRenderer.this)
                    return false;
                WebForm container = component.findParent(WebForm.class);
                if (container != null && container.getBorder() instanceof TitledBorder) {
                    return super.isEnabled(component);
                }
                return false;
            }
        });
        add(new ServoyAjaxEventBehavior("onclick", null, true) {
            @Override
            protected void onEvent(AjaxRequestTarget target) {
                if (app.getFoundSetManager().getEditRecordList().isEditing()) {
                    app.getFoundSetManager().getEditRecordList().stopEditing(false);
                    WebEventExecutor.generateResponse(target, getPage());
                }
            }

            @Override
            protected IAjaxCallDecorator getAjaxCallDecorator() {
                return new AjaxCallDecorator() {
                    private static final long serialVersionUID = 1L;

                    @Override
                    public CharSequence decorateScript(CharSequence script) {
                        return "if ((event.target || event.srcElement) == this){ " + script + " }"; //$NON-NLS-1$ 
                    }
                };
            }

        });
    }

    public void setParentView(IView parentView) {
        this.parentView = parentView;
    }

    /**
     * @see com.servoy.j2db.ui.IDataRenderer#getDataAdapterList()
     */
    public DataAdapterList getDataAdapterList() {
        return dataAdapterList;
    }

    public void addDisplayComponent(IPersist obj, IDisplay comp) {
        fieldComponents.put(obj, comp);
    }

    void createDataAdapter(IApplication app, IDataProviderLookup dataProviderLookup, IScriptExecuter el,
            ControllerUndoManager undoManager) throws Exception {
        dataAdapterList = new DataAdapterList(app, dataProviderLookup, fieldComponents, el.getFormController(),
                null, undoManager);

        //make it really fields only
        HashMap<IPersist, IDisplay> f = new HashMap<IPersist, IDisplay>();
        Iterator<Map.Entry<IPersist, IDisplay>> it = fieldComponents.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<IPersist, IDisplay> element = it.next();
            if (element.getValue() instanceof IDisplayData) {
                //            String id = ((IDisplayData)element.getValue()).getDataProviderID();
                //            if (dataProviderLookup.getDataProvider(id) instanceof ScriptVariable)
                //            {
                //               globalFields.add(element.getValue());
                //            }
                f.put(element.getKey(), element.getValue());
            }
        }
        fieldComponents = f;
    }

    /**
     * @see com.servoy.j2db.ui.IDataRenderer#setAllNonFieldsEnabled(boolean)
     */
    public void setAllNonFieldsEnabled(boolean b) {
        // TODO Auto-generated method stub
    }

    /**
     * @see com.servoy.j2db.ui.IDataRenderer#setAllNonRowFieldsEnabled(boolean)
     */
    public void setAllNonRowFieldsEnabled(boolean b) {
        // TODO Auto-generated method stub
    }

    /**
     * @see com.servoy.j2db.ui.IDataRenderer#stopUIEditing()
     */
    public boolean stopUIEditing(boolean looseFocus) {
        if (dataAdapterList != null)
            return dataAdapterList.stopUIEditing(looseFocus);
        return true;
    }

    /**
     * @see com.servoy.j2db.ui.IDataRenderer#setName(java.lang.String)
     */
    public void setName(String name) {
        // ignore id can't be set in web
    }

    /**
     * @see com.servoy.j2db.ui.IComponent#getName()
     */
    public String getName() {
        return getId();
    }

    public void destroy() {
        if (dataAdapterList != null) {
            dataAdapterList.destroy();
            dataAdapterList = null;
        }
        if (getRequestCycle() != null) {
            removeAll();
            if (getParent() != null) {
                remove();
            }
        }
    }

    public void setComponentVisible(boolean visible) {
        //      this.visible = visible;
    }

    public void setLocation(Point location) {
        this.location = location;
    }

    public void setSize(Dimension size) {
        this.size = size;
    }

    public void setForeground(Color foreground) {
        this.foreground = foreground;
    }

    public void setBackground(Color background) {
        this.background = background;
    }

    public void setFont(Font font) {
        this.font = font;
    }

    public void setBorder(Border border) {
        this.border = border;
    }

    public void setOpaque(boolean opaque) {
        this.opaque = opaque;
    }

    public void setCursor(Cursor cursor) {
        //      this.cursor = cursor;
    }

    public void setToolTipText(String tooltiptext) {
        if (Utils.stringIsEmpty(tooltiptext)) {
            this.tooltiptext = null;
        } else {
            this.tooltiptext = tooltiptext;
        }
    }

    /**
     * @see com.servoy.j2db.ui.IComponent#getToolTipText()
     */
    public String getToolTipText() {
        return tooltiptext;
    }

    public Point getLocation() {
        return location;
    }

    public Dimension getSize() {
        return size;
    }

    public void notifyVisible(boolean b, List<Runnable> invokeLaterRunnables) {
        if (dataAdapterList != null) {
            //we just forward the call
            dataAdapterList.notifyVisible(b, invokeLaterRunnables);
        }
    }

    public void refreshRecord(IRecordInternal record) {
        IModel<?> model = getDefaultModel();
        if (model != null) {
            model.detach();
        }
        if (dataAdapterList != null) {
            dataAdapterList.setRecord(record, true);
        }

        DataAdapterList.setDataRendererComponentsRenderState(this, record);
        if (getOnRenderComponent().getRenderEventExecutor().hasRenderCallback()) {
            jsChangeRecorder.setChanged();
        }
    }

    public Color getBackground() {
        return background;
    }

    public Border getBorder() {
        return border;
    }

    public Font getFont() {
        return font;
    }

    public Color getForeground() {
        return foreground;
    }

    public boolean isOpaque() {
        return opaque;
    }

    public void setComponentEnabled(boolean enabled) {
        setEnabled(enabled);
    }

    @SuppressWarnings("nls")
    public Iterator<? extends IComponent> getComponentIterator() {
        final Iterator<? extends Component> wicketIterator = iterator();
        Iterator<? extends IComponent> iterator = new Iterator<IComponent>() {
            private IComponent next;

            public boolean hasNext() {
                if (next != null)
                    return true;
                while (wicketIterator.hasNext()) {
                    Object comp = wicketIterator.next();
                    Object delegate = comp;
                    while (delegate instanceof IDelegate<?> && !(delegate instanceof IComponent)) {
                        delegate = ((IDelegate<?>) delegate).getDelegate();
                    }
                    if (delegate instanceof IComponent) {
                        next = (IComponent) delegate;
                        return true;
                    }
                    Debug.error(
                            "Component found which is not an IComponent " + comp + " for a datarenderer " + this,
                            new RuntimeException(comp.getClass().toString()));
                }
                return false;
            }

            public IComponent next() {
                if (next == null) {
                    hasNext();
                }
                if (next == null) {
                    throw new NoSuchElementException("Component iterator of " + this + " has no more elements");
                }
                IComponent returnValue = next;
                next = null;
                return returnValue;
            }

            public void remove() {
                wicketIterator.remove();
            }
        };
        return iterator;
    }

    public void add(IComponent c, String name) {
        //ignore
    }

    public void remove(IComponent c) {
        //ignore
    }

    @Override
    protected void onBeforeRender() {
        super.onBeforeRender();

        if (getBgcolor() == null) {
            String parentViewBGColor = getParentViewBgColor();
            if (parentViewBGColor != null) {
                setBgcolor(parentViewBGColor);
            }
        }
        dataRendererOnRenderWrapper.getRenderEventExecutor().fireOnRender(false);
    }

    @Override
    protected void onRender(final MarkupStream markupStream) {
        super.onRender(markupStream);
        jsChangeRecorder.setRendered();
    }

    public IStylePropertyChanges getStylePropertyChanges() {
        String parentViewBackground = getParentViewBgColor();

        if (parentViewBackground != null) {
            if (!parentViewBackground.equals(getBgcolor())) {
                setBgcolor(parentViewBackground);
            }
        }
        return jsChangeRecorder;
    }

    /*
     * bgcolor as string---------------------------------------------------
     */
    private String getBgcolor() {
        return PersistHelper.createColorString(background);
    }

    private void setBgcolor(String bgcolor) {
        background = PersistHelper.createColor(bgcolor);
        jsChangeRecorder.setBgcolor(bgcolor);
    }

    private String getParentViewBgColor() {
        if (parentView != null) {
            String rowBGColorCalculation = parentView.getRowBGColorScript();
            IRecordInternal rec = (IRecordInternal) getDefaultModelObject();
            if (rec != null && rec.getRawData() != null) {
                IFoundSetInternal parentFoundSet = rec.getParentFoundSet();
                int recIndex = parentFoundSet.getSelectedIndex();
                boolean isSelected = recIndex == parentFoundSet.getRecordIndex(rec);
                if (rowBGColorCalculation != null) {
                    Object bg_color = null;
                    if (rec.getRawData().containsCalculation(rowBGColorCalculation)) {
                        // data renderer is always on the selected index.
                        bg_color = parentFoundSet.getCalculationValue(rec, rowBGColorCalculation,
                                Utils.arrayMerge(
                                        new Object[] { new Integer(recIndex), new Boolean(isSelected), null, null,
                                                Boolean.FALSE },
                                        Utils.parseJSExpressions(parentView.getRowBGColorArgs())),
                                null);
                    } else {
                        try {
                            FormController currentForm = dataAdapterList.getFormController();
                            bg_color = currentForm.executeFunction(rowBGColorCalculation,
                                    Utils.arrayMerge(
                                            new Object[] { new Integer(parentFoundSet.getSelectedIndex()),
                                                    new Boolean(isSelected), null, null, currentForm.getName(), rec,
                                                    Boolean.FALSE },
                                            Utils.parseJSExpressions(parentView.getRowBGColorArgs())),
                                    true, null, true, null);
                        } catch (Exception ex) {
                            Debug.error(ex);
                        }
                    }
                    if (bg_color != null && !(bg_color.toString().trim().length() == 0)
                            && !(bg_color instanceof Undefined)) {
                        return bg_color.toString();
                    }
                }

                if (parentView instanceof ISupportRowStyling) {
                    ISupportRowStyling parentViewWithRowStyling = (ISupportRowStyling) parentView;
                    IStyleSheet ss = parentViewWithRowStyling.getRowStyleSheet();
                    IStyleRule style = isSelected ? parentViewWithRowStyling.getRowSelectedStyle() : null;
                    if (style != null && style.getAttributeCount() == 0)
                        style = null;
                    if (style == null) {
                        style = (recIndex % 2 == 0) ? parentViewWithRowStyling.getRowEvenStyle()
                                : parentViewWithRowStyling.getRowOddStyle();
                    }

                    if (ss != null && style != null) {
                        return PersistHelper.createColorString(ss.getBackground(style));
                    }
                }
            }
        }

        return null;
    }

    public String getFormPartName() {
        return this.formPartName;
    }

    public int onDrag(JSDNDEvent event) {
        Form form = dragNdropController.getForm();
        int onDragID = form.getOnDragMethodID();

        if (onDragID > 0) {
            Object dragReturn = dragNdropController.executeFunction(Integer.toString(onDragID),
                    new Object[] { event }, false, null, false, "onDragMethodID"); //$NON-NLS-1$
            if (dragReturn instanceof Number)
                return ((Number) dragReturn).intValue();
        }

        return DRAGNDROP.NONE;
    }

    public boolean onDragOver(JSDNDEvent event) {
        Form form = dragNdropController.getForm();
        int onDragOverID = form.getOnDragOverMethodID();

        if (onDragOverID > 0) {
            Object dragOverReturn = dragNdropController.executeFunction(Integer.toString(onDragOverID),
                    new Object[] { event }, false, null, false, "onDragOverMethodID"); //$NON-NLS-1$
            if (dragOverReturn instanceof Boolean)
                return ((Boolean) dragOverReturn).booleanValue();
        }

        return form.getOnDropMethodID() > 0;
    }

    public boolean onDrop(JSDNDEvent event) {
        Form form = dragNdropController.getForm();
        int onDropID = form.getOnDropMethodID();

        if (onDropID > 0) {
            Object dropHappened = dragNdropController.executeFunction(Integer.toString(onDropID),
                    new Object[] { event }, false, null, false, "onDropMethodID"); //$NON-NLS-1$
            if (dropHappened instanceof Boolean)
                return ((Boolean) dropHappened).booleanValue();
        }
        return false;
    }

    public void onDragEnd(JSDNDEvent event) {
        Form form = dragNdropController.getForm();
        int onDragEndID = form.getOnDragEndMethodID();

        if (onDragEndID > 0) {
            dragNdropController.executeFunction(Integer.toString(onDragEndID), new Object[] { event }, false, null,
                    false, "onDragEndMethodID"); //$NON-NLS-1$
        }
    }

    public IComponent getDragSource(Point xy) {
        // don't need this, ignore
        return null;
    }

    public String getDragFormName() {
        return getDataAdapterList().getFormController().getName();
    }

    public boolean isGridView() {
        return false;
    }

    public IRecordInternal getDragRecord(Point xy) {
        return getDataAdapterList().getState();
    }

    public int getYOffset() {
        return yOffset;
    }

    private int yOffset;

    public void initDragNDrop(FormController formController, int clientDesignYOffset) {
        this.yOffset = clientDesignYOffset;
        Form form = formController.getForm();
        if (form.getOnDragMethodID() > 0 || form.getOnDragEndMethodID() > 0 || form.getOnDragOverMethodID() > 0
                || form.getOnDropMethodID() > 0) {
            this.dragNdropController = formController;
            if (dragNdropController != null)
                addDragNDropBehavior();

        }
    }

    public FormController getDragNDropController() {
        return dragNdropController;
    }

    private void addDragNDropBehavior() {
        DraggableBehavior dragBehavior = new DraggableBehavior() {
            private IComponent hoverComponent;
            private boolean isHoverAcceptDrop;

            @Override
            protected void onDragEnd(String id, int x, int y, int m, AjaxRequestTarget ajaxRequestTarget) {
                if (getCurrentDragOperation() != DRAGNDROP.NONE) {
                    JSDNDEvent event = WebDataRenderer.this.createScriptEvent(EventType.onDragEnd,
                            getDragComponent(), null, m);
                    event.setData(getDragData());
                    event.setDataMimeType(getDragDataMimeType());
                    event.setDragResult(getDropResult() ? getCurrentDragOperation() : DRAGNDROP.NONE);
                    WebDataRenderer.this.onDragEnd(event);
                }

                super.onDragEnd(id, x, y, m, ajaxRequestTarget);
            }

            @Override
            protected boolean onDragStart(final String id, int x, int y, int m,
                    AjaxRequestTarget ajaxRequestTarget) {
                IComponent comp = getBindedComponentChild(id);
                JSDNDEvent event = WebDataRenderer.this.createScriptEvent(EventType.onDrag, comp, new Point(x, y),
                        m);
                setDropResult(false);
                int dragOp = WebDataRenderer.this.onDrag(event);
                if (dragOp == DRAGNDROP.NONE)
                    return false;
                setCurrentDragOperation(dragOp);
                setDragComponent(comp);
                setDragData(event.getData(), event.getDataMimeType());
                hoverComponent = null;
                isHoverAcceptDrop = false;
                return true;
            }

            @Override
            protected void onDrop(String id, final String targetid, int x, int y, int m,
                    AjaxRequestTarget ajaxRequestTarget) {
                if (getCurrentDragOperation() != DRAGNDROP.NONE) {
                    IComponent comp = getBindedComponentChild(targetid);
                    if (hoverComponent == comp && !isHoverAcceptDrop)
                        return;
                    WebDataRenderer renderer = WebDataRenderer.this;
                    JSDNDEvent event = renderer.createScriptEvent(EventType.onDrop, comp, new Point(x, y), m);
                    event.setData(getDragData());
                    event.setDataMimeType(getDragDataMimeType());
                    setDropResult(renderer.onDrop(event));
                }
            }

            //         private ISupportDragNDrop testTarget(ISupportDragNDrop ddComp, JSEvent event)
            //         {
            //            if (event.js_getSource() instanceof SpecialTabPanel)
            //            {
            //               SpecialTabPanel tabPanel = (SpecialTabPanel)event.js_getSource();
            //               Component selectedComponent = tabPanel.getEnclosingComponent().getSelectedComponent();
            //               if (selectedComponent instanceof FormLookupPanel)
            //               {
            //                  FormController formControler = ((FormLookupPanel)selectedComponent).getFormPanel();
            //                  event.setSource(null);
            //                  event.setFormName(formControler.getName());
            //                  event.setElementName(null);
            //                  return (ISupportDragNDrop)formControler.getViewComponent();
            //               }
            //            }
            //            return ddComp;
            //         }

            @Override
            protected void onDropHover(String id, final String targetid, int m,
                    AjaxRequestTarget ajaxRequestTarget) {
                if (getCurrentDragOperation() != DRAGNDROP.NONE) {
                    IComponent comp = getBindedComponentChild(targetid);
                    JSDNDEvent event = WebDataRenderer.this.createScriptEvent(EventType.onDragOver, comp, null, m);
                    event.setData(getDragData());
                    event.setDataMimeType(getDragDataMimeType());
                    isHoverAcceptDrop = WebDataRenderer.this.onDragOver(event);
                    hoverComponent = comp;
                }
            }

            @Override
            public IComponent getBindedComponentChild(final String childId) {
                IComponent comp = super.getBindedComponentChild(childId);
                if (comp == null)
                    comp = WebDataRenderer.this;
                return comp;
            }

        };
        dragBehavior.setUseProxy(true);
        add(dragBehavior);
    }

    private JSDNDEvent createScriptEvent(EventType type, IComponent dragSource, Point xy, int modifiers) {
        JSDNDEvent jsEvent = new JSDNDEvent();
        jsEvent.setType(type);
        jsEvent.setFormName(getDragFormName());
        IRecordInternal dragRecord = getDragRecord(xy);
        if (dragRecord instanceof Record)
            jsEvent.setRecord((Record) dragRecord);
        if (dragSource instanceof IDataRenderer) {
            IDataRenderer dr = (IDataRenderer) dragSource;
            FormController fct = dr.getDataAdapterList().getFormController();
            jsEvent.setSource(fct.getFormScope());
        } else {
            jsEvent.setSource(dragSource);
            if (dragSource != null) {
                String dragSourceName = dragSource.getName();
                if (dragSourceName == null)
                    dragSourceName = dragSource.getId();
                jsEvent.setElementName(dragSourceName);
            }
        }
        if (xy != null)
            jsEvent.setLocation(xy);
        jsEvent.setModifiers(modifiers);

        return jsEvent;
    }

    /*
     * @see com.servoy.j2db.ui.ISupportOnRenderWrapper#getOnRenderComponent()
     */
    public ISupportOnRenderCallback getOnRenderComponent() {
        return dataRendererOnRenderWrapper;
    }

    /*
     * @see com.servoy.j2db.ui.ISupportOnRenderWrapper#getOnRenderElementType()
     */
    public String getOnRenderElementType() {
        return IRuntimeComponent.FORM;
    }

    /*
     * @see com.servoy.j2db.ui.ISupportOnRenderWrapper#getOnRenderToString()
     */
    public String getOnRenderToString() {
        return dataAdapterList != null ? dataAdapterList.getFormController().getForm().toString()
                : super.toString();
    }
}