Как заставить виджет заполнить пространство в вертикальном описании в GWT

#gwt

#gwt

Вопрос:

Отредактировано, чтобы включить предложения ниже: этот блок кода теперь работает для создания макета на снимке экрана;

У меня есть UiBinder, и я пытаюсь создать макет так, чтобы на панели содержимого был основной раздел, который заполняет доступную ширину и высоту, опуская нижний колонтитул до самого низа. Я попробовал это;

 <!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">
<ui:style>
.eastPanel {
        background-color: #F60;
    }

    .westPanel {
        background-color: #EEE;
    }

    .northPanel {
        background-color: #39F;
    }

    .southPanel {
        background-color: #99C;
    }

    .centrePanel {
        background-color: #FFC;
    }

    .headerPanel {
        font-weight: bold;
        background-color: #37B6CE;
    }

    .mainPanel {
        font-weight: bold;
        background-color: #123;
    }

    .footerPanel {
        font-weight: bold;
        background-color: #206876;
    }
</ui:style>
<g:DockLayoutPanel unit='EM'>
    <g:north size='8'>
        <g:FlowPanel styleName="{style.northPanel}">
            <g:SimplePanel ui:field="northPanel" />
            <g:Label>This is the NORTH panel</g:Label>
        </g:FlowPanel>
    </g:north>
    <g:west size='13'>
        <g:FlowPanel styleName="{style.westPanel}">
            <g:SimplePanel ui:field="westPanel" />
            <g:Label>This is the WEST panel</g:Label>
        </g:FlowPanel>
    </g:west>
    <g:center>
        <g:LayoutPanel styleName="{style.centrePanel}"  ui:field="centrePanel">
            <g:layer top="0em" height="2em">
                <g:HTMLPanel  styleName="{style.headerPanel}"  ui:field="headerPanel">                  
                fixed header - usually a search box
                </g:HTMLPanel>
            </g:layer>
            <g:layer top="2em" bottom="2em">
                <g:HTMLPanel styleName="{style.mainPanel}"  ui:field="meainPanel">
Expanding main area
                </g:HTMLPanel>
            </g:layer>
            <g:layer bottom="0px" height="2em">
                <g:HTMLPanel  styleName="{style.footerPanel}" ui:field="footerPanel">

                fixed footer - maybe some copyright information
                </g:HTMLPanel>
            </g:layer>
        </g:LayoutPanel>
    </g:center>

    <g:east size='0'>
        <g:FlowPanel styleName="{style.eastPanel}">
            <g:Label>This is the EAST panel</g:Label>
        </g:FlowPanel>
    </g:east>
    <g:south size="0">
        <g:FlowPanel styleName="{style.southPanel}">
            <g:Label>This is the SOUTH panel</g:Label>
        </g:FlowPanel>
    </g:south>
</g:DockLayoutPanel>
  

`

введите описание изображения здесь

Это старый код, который не работал, потому что он использовал таблицу для компоновки основной области содержимого;

 <!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:wids="urn:import:org.limepepper.JavaCart.gwt.ui.client.widgets">
<ui:style>
    .mainPanel {
        background-color: #AFC;
        width: 100%;
        height: 100%;
    }
</ui:style>
<g:DockLayoutPanel unit='EM'>
    <g:north size='8'>
        <g:FlowPanel styleName="{style.northPanel}">
            <g:SimplePanel ui:field="northPanel" />
            <g:Label>This is the NORTH panel</g:Label>
        </g:FlowPanel>
    </g:north>
    <g:west size='13'>
        <g:FlowPanel styleName="{style.westPanel}">
            <g:SimplePanel ui:field="westPanel" />
            <g:Label>This is the WEST panel</g:Label>
        </g:FlowPanel>
    </g:west>
    <g:center>
        <g:HTMLPanel>
            <g:VerticalPanel>
                <g:HTMLPanel>
                    A heade panel
                </g:HTMLPanel>
                <g:HTMLPanel styleName="{style.mainPanel}">
                I want this panel to fill the space
                th
                rh
                tr
                h
                <br>
                </br>
                <br></br>
                <p></p>

                </g:HTMLPanel>
                <g:HTMLPanel>
                    Footer here
                </g:HTMLPanel>
            </g:VerticalPanel>

        </g:HTMLPanel>
    </g:center>
    <g:east size='0'>
        <g:FlowPanel styleName="{style.eastPanel}">
            <g:Label>This is the EAST panel</g:Label>
        </g:FlowPanel>
    </g:east>
    <g:south size="0">
        <g:FlowPanel styleName="{style.southPanel}">
            <g:Label>This is the SOUTH panel</g:Label>
        </g:FlowPanel>
    </g:south>
</g:DockLayoutPanel>
  

`

введите описание изображения здесь

но это не заполняет пространство, я мог бы сделать это программно, но я предполагаю, что есть какой-то метод GWT для использования.

Ответ №1:

Во-первых, вы должны понимать, как VerticalPanel это реализовано и как оно размещает свои дочерние виджеты. Если вы проверите HTML, сгенерированный вашей страницей, вы сразу увидите, что он реализован как <table> .

Как только вы это поймете, вы сразу увидите, что никакие манипуляции с VerticalPanel тегом или <table> тегом, если на то пошло, не позволят вам добиться желаемого эффекта.

Правильный способ реализации <g:center/> вашего DockLayoutPanel — использовать LayoutPanel и использовать его <g:layer>...</g:layer> дочерние элементы для размещения верхнего, нижнего колонтитула и содержимого. LayoutPanel (очень похоже на DockLayoutPanel ) использует абсолютное позиционирование для позиционирования своих слоев, достигая идеального размещения пикселей.

Итак, вот как это должно выглядеть:

 ...
<g:center>
  <g:layer top="0px" height="YOUR HEADER HEIGHT">
    <g:HTMLPanel>
      A heade panel
    </g:HTMLPanel>
  </g:layer>
  <g:layer top="YOUR HEADER HEIGHT" bottom="YOUR FOOTER HEIGHT">
    <g:HTMLPanel styleName="{style.mainPanel}">
        I want this panel to fill the space
    </g:HTMLPanel>
  </g:layer>
  <g:layer bottom="0px" height="YOUR FOOTER HEIGHT">
    <g:HTMLPanel>
        Footer here
    </g:HTMLPanel>
  </g:layer>
</g:center>
...
  

Достаточно указать 2 координаты на оси X или Y для слоя, и LayoutPanel заставит виджет внутри слоя занять все доступное пространство на другой оси. Поэтому, если вы укажете top , height например, значения и, виджет займет все доступное пространство на горизонтальной оси, будет расположен по top координате и будет иметь height указанное.

Ответ №2:

Вы могли бы встроить другой DockLayoutPanel в качестве center внешнего виджета DockLayoutPanel .

т.е.:

 <g:DockLayoutPanel unit='EM'>
 ...
    <g:center>
            <g:DockLayoutPanel unit="EM" width="100%" height="100%">
                <g:center>
                    <g:HTMLPanel>
                        I want this panel to fill the space
                    </g:HTMLPanel>
                </g:center>
                <g:north size="3">
                    <g:HTMLPanel>
                        A header panel
                    </g:HTMLPanel>
                </g:north>
                <g:south size="3">
                    <g:HTMLPanel>
                        Footer here
                    </g:HTMLPanel>
                </g:south>
            </g:DockLayoutPanel>

    </g:center>
...
  

DockLayoutPanel является специализированным LayoutPanel . LayoutPanel позволяет размещать объекты относительно краев самого себя, что очень полезно (например), когда вы хотите, чтобы что-то упало на дно его контейнера. Если вам нужно что-то более продвинутое, чем то, что DockLayoutPanel вам дает, я предлагаю вам проверить LayoutPanel .

Комментарии:

1. Я думаю, что DocLayoutPanels можно прикрепить только к RootLayout, поэтому было бы нормально расширяться, если бы не было боковых панелей

2. Если вы помещаете вложенную панель DockLayoutPanel в HTMLPanel, вам, вероятно, придется указать явные размеры для HTMLPanel, потому что она не реализует интерфейсы RequireResize и ProvideResize. Таким образом, вы помещаете его непосредственно в центральный элемент parnet DockLayoutPanel. @Tom H: DocklayoutPanels, как и все другие LayoutPanels, могут быть прикреплены к любой панели, которая реализует интерфейс ProvideResize. Таким образом, вы вкладываете произвольное количество LayoutPanels

3. @timeu Упс, я случайно завернул панель DockLayoutPanel в панель HTMLPanel. Я отредактировал свой ответ, чтобы убрать это.

4. @TomH я не уверен, что ты имеешь в виду. Можно встраивать LayoutPanels в LayoutPanels. Ограничение заключается в том, что если вы собираетесь использовать панели компоновки в любом месте своего приложения, контейнером верхнего уровня всего вашего приложения должна быть RootLayoutPanel (вместо RootPanel).