Equivalent in Java would be something like:
list1.getElement().addEventListener("scroll", e -> {
list2.scrollToIndex(e.getEventData().get("event.target.firstVisibleIndex").intValue());
}).addEventData("event.target.firstVisibleIndex").debounce(200);
or
list1.getElement().addEventListener("scroll", e -> {
list1.getElement().executeJs("return this.firstVisibleIndex").then(Integer.class, firstVisibleIndex -> {
list2.scrollToIndex(firstVisibleIndex);
});
}).debounce(200);
but the UX isn’t as nice as syncrhonizing on the client. You don’t want to be sending every scroll event to the server after all.