GWT

Implement sliding panel with GWT layout panel

  • Posted on: 14 June 2014
  • By: Zhijun Chen

Google Web Toolkit doesn't come with sliding widget which is quite common in other JavaScript library. However, using LayoutPanel provided by GWT, we can easily implement sliding widget by using CSS and animation effect. The following code gives an example of horizontal sliding widget.

 // import statements
public class SlidingPanel extends ResizeComposite implements HasWidgets, HasOneWidget {

  private final LayoutPanel layoutPanel = new LayoutPanel();
  private int currentIndex = -1;

  /**
   * Default constructor
   */
  public SlidingPanel() {
    initWidget(layoutPanel);
  }

  /**
   * Add a widget
   *
   * @param w the widget to be added
   */
  public void add(IsWidget w) {
    add(w.asWidget());
  }

  /**
   * Add a widget
   */
  public void add(Widget w) {
    layoutPanel.add(w);
    if (currentIndex < 0) {
      currentIndex = 0;
    } else {
      layoutPanel.setWidgetLeftWidth(w, 100, Unit.PCT, 100, Unit.PCT);
    }
  }

  /**
   * Clear the widgets
   */
  public void clear() {
    setWidget(null);
  }

  public Widget getWidget() {
    return layoutPanel.getWidget(currentIndex);
  }

  /**
   * @return widget iterator
   */
  public Iterator iterator() {
    return layoutPanel.iterator();
  }

  /**
   * Remove a widget
   *
   * @param w widget to be removed
   * @return result
   */
  public boolean remove(Widget w) {
    return layoutPanel.remove(w);
  }

  /**
   * Set the widget
   *
   * @param w the widget
   */
  public void setWidget(IsWidget w) {
    if (w != null) {
      setWidget(asWidgetOrNull(w));
    }
  }

  @Override
  public void setWidget(Widget widget) {
    int newIndex = layoutPanel.getWidgetIndex(widget);

    if (newIndex < 0) {
      newIndex = layoutPanel.getWidgetCount();
      add(widget);
    }

    show(newIndex);
  }

  private void show(int newIndex) {
    if (newIndex == currentIndex) {
      return;
    }

    boolean fromLeft = newIndex < currentIndex;
    final Widget current = layoutPanel.getWidget(currentIndex);
    Widget widget = layoutPanel.getWidget(newIndex);
    currentIndex = newIndex;

    layoutPanel.setWidgetLeftWidth(widget, 0, Unit.PCT, 100, Unit.PCT);
    if (fromLeft) {
      layoutPanel.setWidgetLeftWidth(current, 100, Unit.PCT, 100, Unit.PCT);
    } else {
      layoutPanel.setWidgetLeftWidth(current, -100, Unit.PCT, 100, Unit.PCT);
    }
    layoutPanel.animate(500);
  }
}

So now we've created a custom sliding widget, the way to use it is also very straightforward: Add all the widgets, and show one of the widgets when needed.

SlidingPanel slidingPanel = new SlidingPanel();
FlowPanel panel1 = new FlowPanel();
slidingPanel.add(panel1);
FlowPanel panel2 = new FlowPanel();
slidingPanel.add(panel2);

// slide when needed
slidingPanel.setWidget(panel2);

The custom sliding widget has been tested using two widgets.

Integrate jScrollPane with GWT

  • Posted on: 21 May 2014
  • By: Zhijun Chen

jScrollPane is a cross-browser jQuery plugin which converts a browser's default scrollbars into an HTML structure which can be easily skinned with CSS. It is very helpful if you need a cross-browser style scrollbar.

If you build your web application using Google Web Toolkit (GWT), the easiest way to integrate jScrollPane is using JavaScript Native Interface (JSNI) feature of GWT. JSNI allows you to integrate JavaScript directly into your application's Java source code. The detail guide for JSNI in GWT can be found here.

Download jScrollPane and related files from here and include them inside your main page as follows:

...
<head>
  <link type="text/css" href="style/jquery.jscrollpane.css" rel="stylesheet" />
  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
  <script type="text/javascript" src="script/jquery.mousewheel.js"></script>
  <script type="text/javascript" src="script/jquery.jscrollpane.min.js"></script>
  <script type="text/javascript">
    <!-- The following code will enable us to use jQuery as keyword instead of $ -->
    $.noConflict();
  </script>
</head>
...

Now that we are able to use jScrollPane, we can integrate it into GWT using the following JSNI code.

public native void initCustomScrollbar(String id) /*-{
    var settings = {
        autoReinitialise : true,
        horizontalDragMaxWidth : 0
    };

    $wnd.jQuery('#' + id).jScrollPane(settings);
}-*/;

We need to set an id on GWT widget then call this method when it is needed (could be inside a GWT DeferredCommand):

FlowPanel scrollPanel = new FlowPanel();
scrollPanel.getElement().setId('scrollPanel');
// This method may be needed to put int a scheduler deferred command
initCustomScrollbar('scrollPanel');

Now you should be able to wrap all methods in jScrollPane through JSNI by access api as follows:

var api = $wnd.jQuery('#' + id).data('jsp');