Выравнивание по среднему центру в GWT LayoutPanels (эквивалент Alignment.MIDDLE_CENTER)

Как разместить LayoutPanel в среднем центре родительского LayoutPanel (RootLayoutPanel, экран, страница браузера)? Предполагая, что внутренняя панель имеет фиксированный размер, внешняя панель является гибкой и имеет размеры (с окном браузера).

В Vaadin это однострочная команда:
(VerticalLayout)outerPane).setComponentAlignment(innerPane, Alignment.MIDDLE_CENTER);

Что такое эквивалент GWT?
Перечисление GWT Layout.Alignment предоставляет только BEGIN END STRETCH.
Неадекватное. Расположение по центру экрана необходимо для отображения небольших форм, диалоговых окон, предупреждающих сообщений, экранов входа и т. Д.

Подробности в моем посте на форуме GWT
Спасибо

--- ОБНОВЛЕНИЕ (27.2.2012) ---------------

Чтобы использовать предложенную технику - используя setWidgetLeftRight() и setWidgetTopBottom() - мне нужно фактически вычислить NW-позицию (x,y) внутреннего компонента относительно внешнего компонента и делать это после каждого изменения размера внешнего контейнера или внутреннего контейнера (высота содержимого),

Так что, если GWT не поддерживает центрирование, и кажется, что даже в последней версии это не так, требуется больше кодирования:

outerComponent.setWidgetLeftRight(innerComponent, x, PX, x, PX);
outerComponent.setWidgetTopBottom(innerComponent, y, PX, y, PX);    

х, у рассчитывается как:
х = (w1 - w2) / 2
y = (h1 - h2) / 2
где:
w1 - ширина внешнего компонента (переменная, легко получить?)
h1 - высота внешнего компонента (переменная, легко получить?)
w2 - ширина внутренней центрированной детали (фиксированная)
h2 - высота по центру внутреннего компонента (переменная, в зависимости от содержимого, потенциально сложно получить)

Все предпочтительно в пикселях (PX?) Или EM. Когда смешано с%, должно произойти больше конверсии.

С каждым случаем изменения размера координаты должны быть пересчитаны (w1, h1 change).

При каждом изменении внутреннего содержимого координаты должны пересчитываться (изменения h2).

Это в значительной степени замаскированный абсолютный макет (AbsolutePanel).

CSS решение? Я нашел несколько примеров на этом сервере, но ни один не помечен как решенный. Ни один с вертикальным и горизонтальным центрированием и гибкой высотой внутреннего компонента.

Почему я не предпочитаю решение на основе CSS:

  • Склонен к перекрестным проблемам браузера. GWT не поможет вам здесь.
  • Я считаю смешивание макетов в коде и в CSS плохим дизайнерским решением. CSS лучше всего оставить для "декоративных" объявлений (размеры и цвета шрифта, поля, отступы).
  • Мой собственный плохой опыт работы с макетами CSS; легко сломать, сложно отладить, много головных болей, прежде чем все сложить. Лучше всего избегать. У меня были большие надежды на GWT.

Я думаю об этом решении на основе кода:

  • новый подкласс виджета? Панель? Компоновка? Составная часть? (внутренний компонент)
  • реализовать функцию requireResize Ожидается, реализовать метод обратного вызова onResize()
  • получить фактические значения для переменных размеров (w1, h1, h2). Как?
  • установить новые координаты для внутреннего компонента. Как?

Указывает на любого, кто предоставляет решение на основе этих предпосылок:)

2 ответа

Ну, вы могли бы использовать VerticalPanel и установите поле HorizontalAlignment или, если вы хотите использовать LayoutPanels вы можете адаптировать решение в документах GWT, которые вы разместили в ветке групп Google.

LayoutPanel p = new LayoutPanel(); 
Widget centercontent;
p.add(centercontent);
p.setWidgetLeftRight(centercontent, 5, EM, 5, EM);     // Center panel 
p.setWidgetTopBottom(centercontent, 5, EM, 5, EM); 

Это создаст центральную панель с полями в 5 em слева, справа, сверху и снизу, как показано ниже (будет видна только белая панель посередине). EM - фиксированный размер, подобный пикселю, но зависит от основного размера шрифта. Если ваш базовый размер шрифта (определенный для вашего тела) установлен на 16 пикселей, то 1 EM = 16 px (см. здесь для преобразования информации).

Вы также можете использовать относительные значения для полей:

p.setWidgetLeftRight(centercontent, 5, PCT, 5, PCT);     //5 % left and right margin
p.setWidgetTopBottom(centercontent, 5, PCT, 5, PCT);     // 5 % top and bottom margin.

Однако, таким образом, вы не сможете решить вашу проблему полностью (разные размеры форм -> смотрите скриншоты в теме Google), потому что центральная панель всегда будет иметь фиксированные поля (5 ЕМ или 5 %) независимо от вертикального размера центральной панели.,
Кроме того, содержимое центральной панели будет обрезано, если оно будет выше доступного размера экрана, и будет изменено при изменении размера браузера.

Поэтому я думаю, что лучший подход - это поставить FlowPanel/HTMLPanel внутри LayoutPanel и применять стили CSS, чтобы позволить естественное изменение размера.

Что делать, если вы добавили ResizeListener на центральную панель (я не уверен, что это работает, попробую сейчас). По сути, всякий раз, когда окно изменяет размеры, панель центрируется (вычисляя ее высоту относительно высоты ее родителя).

РЕДАКТИРОВАТЬ

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

@Override public void onResize(ResizeEvent event) {

    // for my case, this is the first parent element with the full height.
    Widget parent = getParent().getParent();
    int height = parent.getOffsetHeight();

    // could make this more exact by including height of this panel.
    getElement().getStyle().setPaddingTop((int)((height - 80)/2), Unit.PX);
}

// my panel is not initially visible
@Override public void onAttach() { 
    super.onAttach();
    Scheduler.get().scheduleDeferred(new ScheduledCommand() {
        @Override public void execute() {
            onResize(null);
        }
    });
}
Другие вопросы по тегам