11 febbraio 2012

GWT: SplitLayoutPanel, double(or single) click to show/hide panel

La classe seguente consente di chiudere o mostrare i pannelli di uno SplitLayoutPanel tramite un doppio click sugli "splitters" (le barre per ridimensionare i pannelli). 
Il doppio click viene riconosciuto se l'intervallo tra un click e quello successivo non supera un secondo (primo valore evidenziato in giallo espresso in millisecondi). 
L'animazione che mostra o nasconde il pannello dura 500 millisecondi (secondo valore evidenziato in giallo).


public class SplitLayoutPanelExt extends SplitLayoutPanel {


  private class ClickSplitter {
  private Widget widget;
    private Widget splitter;
    private long t = 0;
    public ClickSplitter(Widget w, Widget splitter){
    this.widget = w;
     this.splitter = splitter;
   }
    public void onAttach(){
    DOM.setEventListener(splitter.getElement(), new EventListener() {
    @Override
     public void onBrowserEvent(Event event) {
     if(Event.ONMOUSEDOWN==event.getTypeInt()){
       long t2 = (new Date()).getTime();
         if(t2-t>1000) { t = t2; splitter.onBrowserEvent(event); return; }
         LayoutData layout = (LayoutData)widget.getLayoutData();
         if(layout.size>0){
            layout.oldSize = layout.size;
           layout.size = 0;
           }else {
          layout.size = layout.oldSize;
           layout.oldSize = 0;
           }
          t=0;
           animate(500);
          event.preventDefault();
          }else {
          splitter.onBrowserEvent(event);
          }
        }
      });
    }
  }


private List<ClickSplitter> clickSplitterList = new ArrayList< ClickSplitter >();

public void addWestClosable( Widget widget, double size) {
  super.addWest(widget, size);
  addClickSplitter(widget);
}


  public void addEastClosable( Widget widget, double size){
    super.addEast(widget, size);
    addClickSplitter(widget);
}

public void addNorthClosable(Widget widget, double size){
  super.addNorth(widget, size);
    addClickSplitter(widget);
}

public void addSouthClosable(Widget widget, double size){
  super.addSouth(widget, size);
  addClickSplitter(widget);
}


  private void  addClickSplitter(Widget widget){
    int idx = super.getWidgetIndex(widget);
   if(idx>-1 && idx < getWidgetCount()-1){
      Widget splitter = super.getWidget(idx+1);
     clickSplitterList.add(new ClickSplitter(widget, splitter));
    }
}


  @Override
  protected void onAttach() {
   super.onAttach();
    for(ClickSplitter clickSplitter: clickSplitterList){
      clickSplitter.onAttach();
    }
}
}


Example:

/**
* This is the entry point method.
*/
public void onModuleLoad() {

SplitLayoutPanelExt splitLayoutPanelExt = new SplitLayoutPanelExt();

splitLayoutPanelExt.addWestClosable(new Label("west panel"), 200);
splitLayoutPanelExt.addWestClosable(new Label("west2 panel"), 200);
splitLayoutPanelExt.addEastClosable(new Label("east panel"), 200);
splitLayoutPanelExt.addEastClosable(new Label("east2 panel"), 200);
splitLayoutPanelExt.addNorthClosable(new Label("north panel"), 100);
splitLayoutPanelExt.addSouthClosable(new Label("south panel"), 100);
splitLayoutPanelExt.add(new Label("center panel"));

RootLayoutPanel.get().add(splitLayoutPanelExt);

}

Variante single click
Per mostrare/nascondere i pannelli con un click singolo, sostituire il metodo "onBrowserEvent" con il seguente codice:

    @Override
     public void onBrowserEvent(Event event) {
     if(Event.ONMOUSEDOWN==event.getTypeInt()){
                   t = (new Date()).getTime();
               }else if(Event.ONMOUSEUP==event.getTypeInt()) {
                   long t2 = (new Date()).getTime();
         if(t2-t>200) { t = 0; splitter.onBrowserEvent(event); return; }
         LayoutData layout = (LayoutData)widget.getLayoutData();
         if(layout.size>0){
            layout.oldSize = layout.size;
           layout.size = 0;
           }else {
          layout.size = layout.oldSize;
           layout.oldSize = 0;
           }
          t=0;
           animate(500);
          }
          splitter.onBrowserEvent(event);
        }