Как объединить несколько находящихся в uiBinder виджетов?

Я должен вставить [количество] находящиеся в uiBinder виджеты в другой в конкретном месте. Вставленный виджет имеет несколько сложное расположение, таким образом, я пытаюсь определить его в HTML.

referencePanel.add (...) перестал работать с java.lang. IllegalStateException: родитель Этого виджета не реализует HasWidgets. Не знайте, какой родитель виджета это недовольно - innerPanel или referencePanel.

Если объект ReferenceUI добавляется к RootPanel, и затем он добавляется к концу страницы. Но если это добавляется к RootPanel сначала, затем существует Код JavaScriptException 3 (HIERARCHY_REQUEST_ERR) при добавлении к referencePanel.

Какие-либо предложения?

public class AppUIDemo extends Composite {
    @UiTemplate("AppUIDemo.ui.xml")
    interface AppUIDemoUiBinder extends UiBinder<Widget, AppUIDemo> {
    }

    @UiTemplate("ReferenceUI.ui.xml")
    interface ReferenceUIUiBinder extends
            UiBinder<Widget, ReferenceUI> {
    }

    private static AppUIDemoUiBinder uiBinder = GWT
            .create(AppUIDemoUiBinder.class);
    private static ReferenceUIUiBinder refUIBinder = GWT
            .create(ReferenceUIUiBinder.class);

    @UiField
    FlowPanel referencePanel;

    public AppUIDemo() {
            initWidget(uiBinder.createAndBindUi(this));
            ReferenceUI reference = new ReferenceUI(refUIBinder);

            HTMLPanel innerPanel = reference.getRefPanel();
            innerPanel.getElement().setId(HTMLPanel.createUniqueId());
            referencePanel.add(innerPanel);
        }
}

 

public class ReferenceUI extends Composite {

    interface ReferenceUIUiBinder extends
            UiBinder<Widget,ReferenceUI> {
    }

    private static ReferenceUIUiBinder uiBinder = GWT
            .create(ReferenceUIUiBinder.class);


    @UiField
HTMLPanel refPanel;

    public ReferenceUI() {
        initWidget(uiBinder.createAndBindUi(this));
    }

    public CreditReferenceUI(final UiBinder<Widget, CreditReferenceUI> binder) {
        initWidget(binder.createAndBindUi(this));
    }

    public HTMLPanel getRefPanel() {
        return refPanel;
    }
}

ReferenceUI.ui.xml

<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
    xmlns:g="urn:import:com.google.gwt.user.client.ui"
    xmlns:gwittir="urn:import:com.totsp.gwittir.client.ui">
            <g:HTMLPanel ui:field="referencePanel">
            <table>
            <tr>
                <td>
                    <b>First Name</b></td>
                <td>
                    <b>Last Name</b></td>
                <td>
                    <b>Phone</b></td>
                <td>
                    <b>Fax</b></td>
            </tr>
            <tr>
                <td>
                    <gwittir:TextBox ui:field="referenceFirstName" styleName="input"/></td>
                <td>
                    <gwittir:TextBox ui:field="referenceLastName" styleName="input"/></td>
                <td>
                    <table><tr>
            <td> ( </td> <td>
                <gwittir:TextBox ui:field="referencePhoneAreaCode" styleName="input" maxLength="3"/></td>
                <td> ) </td> <td>
                <gwittir:TextBox ui:field="referencePhoneNumber" styleName="input" maxLength="7"/></td>
            <td> # </td> <td>
                <gwittir:TextBox ui:field="referencePhoneExtension" styleName="input" maxLength="25"/></td>
        </tr></table></td>
                <td>
                     <table><tr>
            <td> ( </td> <td>
                <gwittir:TextBox ui:field="referenceFaxAreaCode" styleName="input" maxLength="3"/></td>
                <td> ) </td> <td>
                <gwittir:TextBox ui:field="referenceFaxNumber" styleName="input" maxLength="7"/></td>
        </tr></table></td>
                </tr>
            <tr>
                <td style="text-align:right">
                    <b>Address: </b> Street</td>
                <td>
                    <gwittir:TextBox ui:field="referenceStreet" styleName="input"/></td>
                <td colspan="2" style="width:50%">
                    <table><tr><td>   City</td>
                    <td><gwittir:TextBox ui:field="referenceCity" styleName="input" maxLength="25"/></td>
                    <td> State </td>
                    <td class="state"><gwittir:TextBox ui:field="referenceState" styleName="input" maxLength="2"/></td>
                    <td> ZIP</td>
                    <td><gwittir:TextBox ui:field="referenceZIP" styleName="input" maxLength="9"/></td></tr></table>
                </td>
            </tr>
        </table>
    </g:HTMLPanel>
</ui:UiBinder>

AppUIDemo.ui.xml

<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
    xmlns:g="urn:import:com.google.gwt.user.client.ui"
    xmlns:gwittir="urn:import:com.totsp.gwittir.client.ui">
    <g:HTMLPanel ui:field="basePanel">
        <!--  <div id="MainContent">  -->
        <p><h2><b>Application Demo</b></h2></p>

        <g:FlowPanel ui:field="referencePanel">
        </g:FlowPanel>
    </g:HTMLPanel>
</ui:UiBinder>
6
задан Juniper 12 October 2014 в 08:03
поделиться

2 ответа

Я начну с исправления, а потом перейду к его объяснению.

Устранение проблемы

Самый простой способ решить эту проблему заключается в следующем. Вот ваш код:

HTMLPanel innerPanel = reference.getRefPanel();
innerPanel.getElement().setId(HTMLPanel.createUniqueId());
referencePanel.add(innerPanel);

Замените его следующим кодом. Обратите внимание, что изменилась только последняя строка.

HTMLPanel innerPanel = reference.getRefPanel();
innerPanel.getElement().setId(HTMLPanel.createUniqueId());
referencePanel.add(reference);

Таким образом, вы добавляете объект Составной . Для пользователя не будет никакой разницы, поскольку HTMLPanel (ваша innerPanel ) будет непосредственно прикреплена к документу.


Немного предыстории

Добавление виджета на сложную панель

Когда вы добавляете виджет на сложную панель (панель, которая содержит более одного дочернего виджета), четыре вещи происходят одна за другой:

  1. Виджету предлагается удалить себя из текущего родителя
  2. Панель добавляет виджет в свой список дочерних элементов
  3. Панель добавляет виджет в документ
  4. Виджету предлагается установить панель в качестве своего нового родителя.

Указание виджету удалить себя из своего родителя

Когда дочернему элементу предлагается удалить себя из своего родителя, происходит одно из следующего:

  • Если виджет не имеет родителя, он ничего не делает
  • ] Если виджет является дочерним по отношению к панели, которая реализует HasWidgets , виджет сообщает панели об удалении этого виджета
  • В противном случае виджет генерирует исключение IllegalStateException с сообщением «Родитель этого виджета. не реализует HasWidgets

Составные виджеты

При вызове initWidget (Widget) родителем виджета является установлен в объект Составной .

Проблема

Когда вы пытаетесь добавить innerPanel , ему предлагается удалить себя из текущего родителя. innerPanel на самом деле является корнем вашего шаблона UiBinder. Его родителем является объект Composite (в частности, ReferenceUI ). Это приводит к возникновению исключения, поскольку Composite не реализует HasWidgets и не поддерживает удаление своего виджета.

13
ответ дан 8 December 2019 в 14:41
поделиться

К сожалению, IIRC вы не можете установить идентификатор для виджета в коде UiBinder (я думаю, вы можете только для обычного HTML). Таким образом, вам остается установить правильный идентификатор с помощью someWidget.getElement (). SetId () (как в приведенном выше коде).

Я думаю, что сейчас не хватает заполнителя (div, span, что угодно) с правильным идентификатором в HTMLPanel referencePanel , например так:

<g:HTMLPanel ui:field="referencePanel">
    <div ui:field="referencePanelInner" />
</g:HTMLPanel>

И в AppUIDemo :

@UiField
DivElement referencePanelInner;
// ...
public AppUIDemo() {
    // ...
    referencePanelInner.setId(reference.getRefPanelId());
}

... если вы не хотите добавить ReferenceUI непосредственно в referencePanel - в этом случае вам следует просто использовать FlowPanel :)

PS: ИМХО, вы должен сгенерировать и установить уникальный идентификатор для ReferenceUI.refPanel из класса ReferenceUI (и раскрыть идентификатор) - таким образом вы не повредите «внутренности» виджета из некоторых внешние виджеты.


Хорошо, я думаю, что понял. Возникает исключение IllegalStateException , потому что вы добавляете ReferenceUI.refPanel (или ReferenceUI.referencePanel , я не знаю текущее имя) в AppUIDemo ( ReferenceUI , очевидно, не реализует HasWidgets ) - когда вы должны добавить весь составной ReferenceUI reference :) Я не знаете, почему вы сделали это именно так (возможно, из-за всей неразберихи с идентификаторами), но код должен выглядеть примерно так:

public AppUIDemo() {
        initWidget(uiBinder.createAndBindUi(this));
        ReferenceUI reference = new ReferenceUI(refUIBinder);

        referencePanel.add(reference);
    }
3
ответ дан 8 December 2019 в 14:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: