PDA

View Full Version : [2.0] Event Collapse / Expand not fired when using BorderLayout



mtarantini
24 Jul 2009, 1:12 AM
Hi,

Is it possible to fire the Collapse / Expand Event when using BorderLayout ?

Below the snippet code :



package com.test.client;

import com.extjs.gxt.ui.client.Style.LayoutRegion;
import com.extjs.gxt.ui.client.Style.Scroll;
import com.extjs.gxt.ui.client.event.BaseEvent;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.util.Margins;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.Info;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.layout.BorderLayout;
import com.extjs.gxt.ui.client.widget.layout.BorderLayoutData;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.RootPanel;

/*
* * Entry point classes define <code>onModuleLoad()</code>.
*/
public class Test implements EntryPoint
{

/**
* This is the entry point method.
*/
public void onModuleLoad()
{
RootPanel.get().add(new BorderLayoutExample());
}

public class BorderLayoutExample extends LayoutContainer
{

public BorderLayoutExample()
{

setSize("100%", "100%");
final BorderLayout layout = new BorderLayout();
setLayout(layout);

ContentPanel north = new ContentPanel();
ContentPanel west = new ContentPanel();
ContentPanel center = new ContentPanel();
center.setHeading("BorderLayout Example");
center.setScrollMode(Scroll.AUTOX);

FlexTable table = new FlexTable();
table.getElement().getStyle().setProperty("margin", "10px");
table.setCellSpacing(8);
table.setCellPadding(4);

for (int i = 0; i < LayoutRegion.values().length; i++)
{
final LayoutRegion r = LayoutRegion.values()[i];
if (r == LayoutRegion.CENTER)
{
continue;
}
SelectionListener<ButtonEvent> sl = new SelectionListener<ButtonEvent>()
{

@Override
public void componentSelected(ButtonEvent ce)
{
String txt = ce.getButton().getText();
if (txt.equals("Expand"))
{
layout.expand(r);
}
else if (txt.equals("Collapse"))
{
layout.collapse(r);
}
else if (txt.equals("Show"))
{
layout.show(r);
}
else
{
layout.hide(r);
}

}
};
table.setHTML(i, 0, "<div style='font-size: 12px; width: 100px'>" + r.name() + ":</span>");
table.setWidget(i, 1, new Button("Expand", sl));
table.setWidget(i, 2, new Button("Collapse", sl));
table.setWidget(i, 3, new Button("Show", sl));
table.setWidget(i, 4, new Button("Hide", sl));
}
center.add(table);

ContentPanel east = new ContentPanel();
ContentPanel south = new ContentPanel();
south.addListener(Events.Collapse, new Listener<BaseEvent>()
{

public void handleEvent(BaseEvent be)
{
Info.display("Collapse", "Collapse");
};
});
south.addListener(Events.Expand, new Listener<BaseEvent>()
{

public void handleEvent(BaseEvent be)
{
Info.display("Expand", "Expand");
};
});

BorderLayoutData northData = new BorderLayoutData(LayoutRegion.NORTH, 100);
northData.setCollapsible(true);
northData.setFloatable(true);
northData.setHideCollapseTool(true);
northData.setSplit(true);
northData.setMargins(new Margins(5, 5, 0, 5));

BorderLayoutData westData = new BorderLayoutData(LayoutRegion.WEST, 150);
westData.setSplit(true);
westData.setCollapsible(true);
westData.setMargins(new Margins(5));

BorderLayoutData centerData = new BorderLayoutData(LayoutRegion.CENTER);
centerData.setMargins(new Margins(5, 0, 5, 0));

BorderLayoutData eastData = new BorderLayoutData(LayoutRegion.EAST, 150);
eastData.setSplit(true);
eastData.setCollapsible(true);
eastData.setMargins(new Margins(5));

BorderLayoutData southData = new BorderLayoutData(LayoutRegion.SOUTH, 100);
southData.setSplit(true);
southData.setCollapsible(true);
southData.setFloatable(true);
southData.setMargins(new Margins(0, 5, 5, 5));

add(north, northData);
add(west, westData);
add(center, centerData);
add(east, eastData);
add(south, southData);
}
}
}



I took the BorderLayoutExample and just add a listener on the South Panel (named south).

The event are not fired when collapsing / expanding the content panel.

regards.

mtarantini
26 Jul 2009, 11:00 PM
So, is it possible to fix the problem in the BorderLayout Class..by adding the fire event ?

Thx.

sven
27 Jul 2009, 1:31 AM
The expand and collapse in borderlaoyut are not real expand/collapse. You can extend borderlayout and add this events do borderlaoyut.

Luming Lai
4 Sep 2009, 8:45 AM
I can't seem to find a way with 2.0 to do this (ie: override).

With the 1.x version, we extended a panel and (after much fumbling around) managed to find an event we could listen to (BeforeStateChange) and use that to notify our classes, but with the new one, that event is no longer fired, since Component#saveState now has a "if (stateful && state != null)" check before triggering the event.

So, here we are, onCollapse, onExpand, setCollapsed, createCollapsePanel (which are called on expand and collapse events), layoutContainer (which holds the remove and add events) and stateful are all private, state is managed via a Map (we could have potentially created our own map implementation, which would notify us of this event).

The state cannot be queried from any user-supplied object either, since you can't access anything that participates in the event.

Eventually we did manage to override the saveState method on the panel which is being collapsed, so that we can cache the old value behind the "collapsed" and compare the new value to it to learn of the collapse/expand events, but this was nearly half a day's worth of effort for something which should be obvious.

I would be happy to listen to an event, provide a callback or at least have some sort of an override for a protected method, but all of these are unavailable with the current configuration.

This post serves the primary purpose that others don't waste their time looking for a solution for this and the secondary to ask for a better hook on this event so that we can remove this very counterintuitive hack in our system eventually.

Thanks

Luming Lai
7 Sep 2009, 7:11 AM
Also, I forgot to mention the fact that you also have to override getState() in 2.0 (so that it always returns a stateful map), since not doing so will result in not getting the values set on the panel earlier, which is the only way to get to this information.

Our internal overriding class is:



protected class PreviewContainerPanel extends ContentPanel {
private Object oldValue = null;
private Map<String, Object> stateMap;

public Map<String, Object> getState() {
if(stateMap == null) {
stateMap = new FastMap<Object>();
}
return stateMap;
}

public void saveState() {
super.saveState();
Object newValue = getState().get(COLLAPSED_KEY);
if(oldValue != newValue) {
onPreviewPanelExpanded(newValue != null);
}
oldValue = newValue;
}
}
This one has to be the worst hack I had to put in my code because of GXT's inadequacy yet. How this is not qualified to be a bug is beyond me.

sven
7 Sep 2009, 7:19 AM
You dont need to do that. You can simple set stateful to true.

Luming Lai
7 Sep 2009, 7:29 AM
Okay, so I can set stateful to true. Is this the officially sanctioned way of listening to a collapse event (ie: without the manual map)?

sven
7 Sep 2009, 7:45 AM
I dont understand what stateful has to do with a collapseevent?

BorderLayout is not firing collapseevents.

Luming Lai
7 Sep 2009, 7:57 AM
My point exactly. No events, no callbacks, not even non-private methods. Hence, I had to look for something which _was_ overridable from the methods in the chain, hence the override of saveState, which does get reliably called on the panel on each collapse/expand event, which we _had to have_.

bwoody
29 Sep 2009, 11:50 AM
The expand and collapse in borderlaoyut are not real expand/collapse. You can extend borderlayout and add this events do borderlaoyut.


I don't see a way to extend BorderLayout to add expand/collapse events since the methods onExpand and onCollapse are private.

sven
29 Sep 2009, 11:59 AM
We already added them and they will be part of 2.0.3

mackenda
4 Oct 2009, 10:44 AM
Have you resolved this issue? Is there a way to trap the Collapse / Expand event?

mbaumbach
27 Jan 2010, 12:45 PM
This is a pretty old thread, but I was looking for how to do this and here's how to do it now:


BorderLayout layout = new BorderLayout();
layout.addListener(Events.Collapse, new Listener<BorderLayoutEvent>() {
public void handleEvent(BorderLayoutEvent be) {
// be.getPanel() will return the panel that collapsed
}
});

mratzloff
21 May 2010, 4:02 PM
This is a pretty old thread, but I was looking for how to do this and here's how to do it now:


BorderLayout layout = new BorderLayout();
layout.addListener(Events.Collapse, new Listener<BorderLayoutEvent>() {
public void handleEvent(BorderLayoutEvent be) {
// be.getPanel() will return the panel that collapsed
}
});Thanks for posting that solution, mbaumbach! =D>