6

[数]のuiBinderベースのウィジェットを別のウィジェットの特定の場所に挿入する必要があります。挿入されたウィジェットのレイアウトはやや複雑なので、HTMLで定義しようとしています。

referencePanel.add(...)はjava.lang.IllegalStateExceptionで失敗します:このウィジェットの親はHasWidgetsを実装していません。不満なウィジェットの親がわからない-innerPanelまたはreferencePanel。

ReferenceUIオブジェクトがRootPanelに追加された場合、それはページの下部に追加されます。ただし、最初にRootPanelに追加された場合、referencePanelに追加されたときにJavaScriptExceptionコード3(HIERARCHY_REQUEST_ERR)があります。

助言がありますか?

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>
4

2 に答える 2

13

修正から始めて、後で説明します。

問題の修正

この問題を解決する最も簡単な方法は次のとおりです。コードは次のとおりです。

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

これを次のコードに置き換えます。最後の行だけが変更されていることに注意してください。

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

このようにして、Compositeオブジェクトを追加します。HTMLPanel(your innerPanel)はドキュメントに直接添付されるため、ユーザーに違いはありません。


いくつかの背景

複雑なパネルへのウィジェットの追加

ウィジェットを複雑なパネル(複数の子ウィジェットを保持するパネル)に追加すると、次の4つのことが次々に発生します。

  1. ウィジェットは、現在の親から自分自身を削除するように指示されます
  2. パネルは、子のリストにウィジェットを追加します
  3. パネルはウィジェットをドキュメントに追加します
  4. ウィジェットは、パネルを新しい親として設定するように指示されます

親から自分自身を削除するようにウィジェットに指示する

子供が親から自分自身を削除するように指示されると、次のいずれかが発生します。

  • ウィジェットに親がない場合、ウィジェットは何もしません
  • ウィジェットがを実装するパネルの子である場合、ウィジェットはHasWidgetsパネルにそのウィジェットを削除するように指示します
  • それ以外の場合、ウィジェットはIllegalStateException「このウィジェットの親はHasWidgetsを実装していません。

複合ウィジェット

を呼び出すinitWidget(Widget)と、ウィジェットの親がCompositeオブジェクトに設定されます。

問題

を追加しようとするとinnerPanel、現在の親から自分自身を削除するように指示されます。innerPanel実際には、UiBinderテンプレートのルートです。その親はCompositeオブジェクトです(具体的にはReferenceUI)。これにより、ウィジェットの削除がComposite実装されておらず、サポートされていないため、例外がスローされます。HasWidgets

于 2010-05-13T22:37:09.250 に答える
3

残念ながら、IIRCではUiBinderのコードでウィジェットのIDを設定することはできません(通常のHTMLでのみ設定できると思います)。someWidget.getElement().setId()したがって、 (上記のコードで行ったように)を介して正しいIDを設定する必要があります。

今欠けているのは、次のHTMLPanel referencePanelように、に正しいIDを持つプレースホルダー(div、spanなど)です。

<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:IMHO、クラスReferenceUI.refPanelからの一意のIDを生成して設定するReferenceUI(そしてIDを公開する)必要があります。そうすれば、一部の外部ウィジェットからのウィジェットの「内部」を台無しにしないでください。


OK、わかったと思います。IllegalStateException例外がスローされているのは、 ReferenceUI.refPanel(またはReferenceUI.referencePanel、現在の名前がどれであるかわからない)にAppUIDemoReferenceUI明らかに実装されていないHasWidgets)-コンポジット全体を追加する必要がある場合ReferenceUI reference:)なぜ追加したのかわかりませんそもそもこのようになっていますが(おそらくIDが混乱しているため)、コードは次のようになります。

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

        referencePanel.add(reference);
    }
于 2010-05-13T17:15:56.147 に答える