Я должен вставить [количество] находящиеся в 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>
Я начну с исправления, а потом перейду к его объяснению.
Самый простой способ решить эту проблему заключается в следующем. Вот ваш код:
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
) будет непосредственно прикреплена к документу.
Когда вы добавляете виджет на сложную панель (панель, которая содержит более одного дочернего виджета), четыре вещи происходят одна за другой:
Когда дочернему элементу предлагается удалить себя из своего родителя, происходит одно из следующего:
HasWidgets
, виджет сообщает панели об удалении этого виджета IllegalStateException
с сообщением «Родитель этого виджета. не реализует HasWidgets При вызове initWidget (Widget)
родителем виджета является установлен в объект Составной
.
Когда вы пытаетесь добавить innerPanel
, ему предлагается удалить себя из текущего родителя. innerPanel
на самом деле является корнем вашего шаблона UiBinder. Его родителем является объект Composite
(в частности, ReferenceUI
). Это приводит к возникновению исключения, поскольку Composite
не реализует HasWidgets
и не поддерживает удаление своего виджета.
К сожалению, 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);
}