How to make UI receive scroll events

家住魔仙堡 提交于 2019-12-11 15:48:23

问题


In my vaadin application I need to implement a fixed header, that changes size depending on the scroll position of the UI.

While there are geters for scroll position in Vaadin 8, there seems to be no functionallity implemented to listen for scroll events. So I tried to implement a JavaScript connector, that just informs the server-side UI, that the user has scrolled, so the server-side UI can then notify the Header as a scrollListener.

So far thats what I planned, but I just can't find out, how to implement my connector in a way that it.

  1. is active after the site got requested by a Client.
  2. is able to call my server-side UI.onScrollEvent() method.

Does anyone know, how the described behavior could be implemented?

Thank you for your help in advance.


回答1:


I have done this once few years ago by extending the layout component that wrapped the part of UI where I needed this. In GWT there is gwtproject.org/javadoc/latest/com/google/gwt/event/dom/client/… which can be used in DOM handler. So yes, GWT provides suitable client side event. I then used RPC call to server side, where I triggered the corresponding server side event, which I could listen in other parts of the app. The code is not public, but there is LazyLayout add-on that has similar type of implementation, which you could check as reference for your implementation.

https://github.com/alump/LazyLayouts/blob/master/lazylayouts-addon/src/main/java/org/vaadin/alump/lazylayouts/client/LazyVerticalLayoutConnector.java




回答2:


After I ran into a few issues with implementaton of a custom widget to achieve, I went for a different approach, using extensions in a vaadin-sense. Here is the truncated code for what I did.

(Vaadin requires the client-side connector code shown later in this post to be in a Widget package. I'm not entirely sure if the server-side component has to be in one too, but for conformity reasons with the usual widget-skeleton I put it into one)

So in the package for the widget:

package my.company.project.scrollUI;

import com.vaadin.server.AbstractExtension;
import com.vaadin.ui.UI;

import my.company.project.scrollUI.client.scrollUI.ScrollUIServerRpc;

public class ScrollUI extends AbstractExtension {

  private ScrollUIServerRpc rpc = new ScrollUIServerRpc() {

    @Override
    public void onScroll() {
      //do whatever you need for your implementation
      ... 
    }

  };

  public ScrollUI() {
    registerRpc(rpc);
  }

  public void extend(UI ui) {
    super.extend(ui);
  }

}

as usual the .gwt.xml file in the package folder, nothing special here:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.5.1//EN" "http://google-web-toolkit.googlecode.com/svn/tags/2.5.1/distro-source/core/src/gwt-module.dtd">
<module>
  <inherits name="com.vaadin.DefaultWidgetSet" />
</module>

In the package for the client-side code to be compiled to JavaScript:

package my.company.project.scrollUI.client.scrollUI;

import com.vaadin.shared.communication.ServerRpc;

public Interface ScrollUIServerRpc extends ServerRpc {

  public void onScroll();

}

And finally the connector for the extension:

package my.company.project.scrollUI.client.scrollUI;

import com.google.gwt.event.dom.client.ScrollEvent;
import com.google.gwt.event.dom.client.ScrollHandler;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.ComponentConnector;
import com.vaadin.client.ServerConnector;
import com.vaadin.client.communication.RpcProxy;
import com.vaadin.client.extensions.AbstractExtensionConnector;
import com.vaadin.shared.ui.Connect;

@Connect(ScrollUI.class)
public class ScrollUIConnector extends AbstractExtensionConnector {

  ScrollUIServerRpc rpc = RpcProxy.create(ScrollUIServerRpc.class, this);

  @Override
  protected void extend(ServerConnector target) {
    final Widget ui = ((ComponentConnector) target).getWidget();

    ui.addDomHandler(new ScrollHandler() {

      @Override
      public void onScroll(ScrollEvent event) {
        rpc.onScroll();
      }

    }, ScrollEvent.getType());

  }

}

Now don't forget to compile the Widgetset and everything is good to go to be used for your actual UI like all other vaadin extensions:

public class MyUI extends com.vaadin.ui.UI {

  @Override
  protected void init(VaadinRequest vaadinRequest) {
    ScrollUI scrollUI = new ScrollUI();
    scrollUI.extend(this);

    //everything else that needs to be done
    ...
  }

  //everything else that Needs to be done
  ...

}

I hope this was helpfull for anyone with a similar issue.



来源:https://stackoverflow.com/questions/51363742/how-to-make-ui-receive-scroll-events

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!