Tech Blog

GWT DisclosurePanel open/close without header

Posted by Javier Ochoa

Apr 19, 2010 6:52:00 AM

The DisclosurePanel in GWT is a special Widget that contains a header and a body, and the header contains an anchor tag for expanding or collapsing the body. It can look like this, where clicking on the arrow next to "Advanced Criteria" will disclose the rest of the panel:

gwt_disclosure

A typical use of DisclosurePanel is something like this:

DisclosurePanel pnlDisclosure = new DisclosurePanel();
pnlDisclosure.setHeader(new Label("Title"));
pnlDisclosure.setContent(new Label("Content"));

In a recent project, however, the interface designer on my team asked whether we could disable the anchor tag (for expand/collapse) on the DisclosurePanel header and have a single button do the job instead, helping the user with a hint that this panel is actually expandable. So, for example, the DisclosurePanel would look something like this (note the arrow on the right):

Collapsed:
Collapsed disclosurepanel

Expanded:
Expanded disclosurepanel

I said "OK, let's see the DisclosurePanel javadoc". Suprise! All you can do is have a header that itself is surrounded by the clickable anchor... time to extend Composite!

The solution I found is quite simple, but I'm sure there are others out there, if you know a different one just drop a comment:

1. First get the nested widgets right:

FlowPanel pnlMain = new FlowPanel(); //Main panel
FlowPanel pnlHeader = new FlowPanel();
DisclosurePanel pnlDisclosure = new DisclosurePanel();

pnlMain.add(pnlHeader);
pnlMain.add(pnlDisclosure);

2. Add a Label to the header, which will act as the expand/collapse button. You can use a PushButton which gives you more possibilities to style button states (on mouse over, down, up, etc.):

Label btnCollapseExpand = new Label();
btnCollapseExpand.setText('\u25BA' + "");
btnCollapseExpand.setTitle("expand/collapse");


pnlHeader.add(btnCollapseExpand);
pnlHeader.add(new Label("Title in disclosure panel"));

3. This is the key, add only Content to the disclosure panel (no header):

// Disclosure panel with no header
pnlDisclosure.setWidth("100%");
pnlDisclosure.setContent(new Label("Disclosure panel with a specific expand/collapse button"));

4. And don't forget to add the corresponding click handler to the button to change the disclosure panel state:

btnCollapseExpand.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
pnlDisclosure.setOpen(!pnlDisclosure.isOpen());
}
});

And that's it! You have now a DisclosurePanel and one button which invites the user to click on it. One extra enhancement if you want to change the button text/title when the panel opens/close, add the following two handlers:

pnlDisclosure.addOpenHandler(new OpenHandler() {
@Override
public void onOpen(OpenEvent event) {
btnCollapseExpand.setText('\u25BC' + "");
btnCollapseExpand.setTitle("collapse");
}
});

pnlDisclosure.addCloseHandler(new CloseHandler() {
@Override
public void onClose(CloseEvent event) {
btnCollapseExpand.setText('\u25BA' + "");
btnCollapseExpand.setTitle("expand");
}
});

Here is the source code of the custom widget, so go ahead and take a look!

Topics: Agile and Development

Subscribe to Email Updates