SubWindow with static footer and sizing-to-content

I’m banging my head up what appears to be a beginners problem; I suspect I just can’t see the wood for the trees.

We want to be able to display a SubWindow in our application. The contents/component to display in the window is variable - I don’t know the size of it. We want the SubWindow to size itself to accomodate the content passed in - and if it can’t all be displayed, to display scrollbars. The window is not resizable by the user.

OK - that all seems fine - just Window#setSizeUndefined(). But in addition, we want to display a footer to the main contents that does not scroll - typically, this will be a horizontal container containing confirm/cancel buttons.

This is where it all gets confusing; I’ve tried creating a VerticalLayout, sticking a panel and the buttons inside the layout, using setExpandRatio on the panel - but for that to work, we’d need to do VerticalLayout#setSizeFull - which would contradicts the Window#setUndefined()

I think what I’m really looking for is a Panel#setFooter(Component) - but it doesn’t exist.

In summary: SubWindow, with static footer, contents scrollable, automatically sizing to size of contents where possible.
How should we approach this - or are we trying to achieve something that isn’t currently possible?

Cheers,

Charles.

Anyone? Bueller? Bueller?

Is this a simple idiot-in-from-of-keyboard issue, or is it just “Not Easy To Do”?

Cheers,

Charles.

Have you tried a VerticalSplitPanel, add Panel for content as firstComponent , and footer as secondComponent ?
You will have to play around with the style to make the splitter disappear, also might need some tweeking with min-width,min-height,max-width,max-height properties …

:slight_smile:

Hi;

I’ve not - until just now :slight_smile:

This approach has promise - but I still think the fundamental issue of SplitPanel#setSizeUndefined and Window#setSizeUnderfined work against each other. Certainly, the initial size of the window is then just the size of the Window Caption! If I then allow the window to be resizeable, and then resize it - it’s an improvement, certainly, but the footer size/splitter bar location “scales” and is not a constant.

Cheers,

Charles.

You will have to give the VerticalSplitPanel a size, try to give it an estimated size based in the amount of data you have and the Browser/UI window size. In Vaadin 6 I usually controlled min/max size of popups windows with CSS. Still have to play with that in Vaadin 7 though…

You’re basically asking for a feature that is not supported currently – max-height. Or setFooter alternatively.

I tried to hack it together in Chrome Web Inspector with plain CSS, but it seems it is impossible, at least with the DOM structure we have in place.

I think the only viable option is to create a small Window extension that forces the window height always to be smaller the main browser window height. Then position the footer of the window using CSS absolute positioning (this part needs some trial and error). Or create an extension that places a footer below the v-window-contents element.

This would be a great place for an add-on that provides this functionality, I bet many would find it useful.

Well, I’ve started dabbling - I’ve created a component extension that adds a footer component element underneath the window.contents element. If I then set the footer component to be an already attached component (e.g. a layout containing buttons), it shows in the correct place with the correct size, and moves with the window. Hurrah!

However,
a) If the window is resizable and resized, the footer component is put in the wrong place. This is due to the resize handling of the main window only adjusting for the size of the actual window.footer element
b) More importantly, the events don’t get through to the footer component. e.g. if I click on the button in the footer component - no joy…

Hmmm. Not sure where to go with this. It could be something to do with the sinking of events by the VWindow to allow for moving components, or it could be something to do with the footer already-having-been-attached-and-then-being-moved.

@Connect(WindowFooterExtension.class)
public class WindowExtensionConnector extends AbstractExtensionConnector {

  protected Widget footerWidget = null;
  protected VWindow vWindow;
  protected final SimplePanel footerPanel = new SimplePanel();
  protected ComponentConnector windowConnector;

  @Override
  public WindowFooterState getState() {
    return (WindowFooterState) super.getState();
  }

  @Override
  public void onStateChanged(StateChangeEvent stateChangeEvent) {
    super.onStateChanged(stateChangeEvent);
    VConsole.log("*** WindowExtension State Changed");
    WindowFooterState state = getState();
    if (state.footerComponent == null) {
      setFooterWidget(new HTML("Empty Footer"));
    } else {
      setFooterWidget(((ComponentConnector) state.footerComponent).getWidget());
    }
  }

  public void setFooterWidget(Widget footerWidget) {
    VConsole.log("*** Setting Footer Widget " + footerWidget);
    this.footerWidget = footerWidget;

    footerPanel.setWidget(this.footerWidget);

  }

  @Override
  protected void extend(ServerConnector target) {
    VConsole.log("*** WindowExtension.extend");
    ComponentConnector target1 = (ComponentConnector) target;

    windowConnector = ((ComponentConnector) target);

    vWindow = (VWindow) target1.getWidget();

    DOM.appendChild(vWindow.contents, footerPanel.getElement());
  }

}

I think hacking together footer support is the wrong way to go. This is just a special case of a functionality that is relevant in other contexts as well. You can’t force the developer to guess sizes or write special purpose code. The solution needs to work universally, or the framework will break down with all the special purpose massaging that it will need, once to support footers in forms, a second time to support a vertical strip in some control, and so on.

And why extensions for something as basic as laying things out and popping the scrollbars in the right place? Coming from HTML, this sort of things is free.

Again, this should be thought off holistically. It’s not a nice to have - it’s layout 101.

So if I have:

Window (size = undefined)
…Wrapper (size = full)
…Body (expand = 1, size = full)
…Lots of stuff (size = undefined)
…Footer (expand = 0, size = undefined)

Why doesn’t the size of “Lots of stuff” and the size of “Footer” dictate the size of the window? It sounds reasonable to me that it should, even if it means throwing away the current beautiful layout algorithm in favor of a more complicated one.

See also
this thread
which asks for the same.