Щелчок средней кнопкой мыши по Vaadin Grid

Я пытаюсь имитировать нормальное поведение браузера в моей сетке vaadin, которая включает щелчок средней кнопкой мыши, чтобы открыть новую вкладку:

addItemClickListener(e -> {
            boolean newTab = e.getMouseEventDetails().getButton() == MouseEventDetails.MouseButton.MIDDLE || e.getMouseEventDetails().isCtrlKey();
            //open in window or new tab
        }); 

Однако средняя кнопка мыши не регистрируется vaadin. Как я мог заставить это работать?


person F43nd1r    schedule 08.01.2018    source источник


Ответы (2)


Эта функция была включена в vaadin-grid (который входит в Vaadin 10) и не будет работать в Vaadin 8.

Для Vaadin 8 вы можете либо перехватить событие с помощью некоторого клиентского расширения, либо использовать ComponentRenderer для добавления Panel к каждому компоненту (что работает, но не идеально , потому что это снижает производительность):

grid.addColumn(item->{
    Panel p = new Panel(item.getName());
    p.setStyleName(ValoTheme.PANEL_BORDERLESS);
    p.addClickListener(ev->{
        System.out.println(ev.getButtonName());             
    });
    return p;
}).setRenderer(new ComponentRenderer());

С другой стороны, клиентское расширение позволяет прослушивать события javascript (например, MouseEvent) и в ответ запускать событие сервера. Создание расширения - довольно сложная тема (поскольку в нем используется часть API, которая обычно скрыта от разработчика), но оно обеспечивает прямой доступ к визуализированной модели DOM, что в противном случае невозможно.

Следующие ресурсы из документации могут дать вам отправную точку: Создание расширения компонента (которое описывает простое расширение только с кодом Java) и Интеграция компонентов JavaScript и Extension (в котором объясняется, как добавить собственный код JavaScript в ваше расширение).

person Javier    schedule 08.01.2018
comment
Vaadin 10 еще нестабилен, поэтому я хотел бы остановиться на 8. Использование ComponentRenderer делает загрузку сетки необычно медленной. Как можно поймать средний щелчок в клиентском расширении? - person F43nd1r; 16.01.2018
comment
Я попытался немного расширить клиентские расширения, это обширная тема. - person Javier; 16.01.2018
comment
Я опубликовал свое решение ниже, но поскольку этот ответ является более общим и, вероятно, более полезным для других, я собираюсь его принять. - person F43nd1r; 16.01.2018
comment
Теперь, когда vaadin 10 отсутствует, как будет выглядеть решение в vaadin 10? - person F43nd1r; 13.07.2018

Как я решил проблему в моем конкретном случае:

На стороне сервера:

public class MyGrid<T> extends Grid<T> {
    public MyGrid(String caption, DataProvider<T, ?> dataProvider) {
        super(caption, dataProvider);
        MiddleClickExtension.extend(this);
    }

    public static class MiddleClickExtension<T> extends AbstractGridExtension<T> {
        private MiddleClickExtension(MyGrid<T> grid) {
            super.extend(grid);
            registerRpc((rowKey, columnInternalId, details) -> grid.fireEvent(
                    new ItemClick<>(grid, grid.getColumnByInternalId(columnInternalId), grid.getDataCommunicator().getKeyMapper().get(rowKey), details)),
                    MiddleClickGridExtensionConnector.Rpc.class);
        }

        public static void extend(MyGrid<?> grid) {
            new MiddleClickExtension<>(grid);
        }

        @Override
        public void generateData(Object item, JsonObject jsonObject) {
        }

        @Override
        public void destroyData(Object item) {
        }

        @Override
        public void destroyAllData() {
        }

        @Override
        public void refreshData(Object item) {
        }
    }
}

На стороне клиента:

@Connect(MyGrid.MiddleClickExtension.class)
public class MiddleClickGridExtensionConnector extends AbstractExtensionConnector {
    @Override
    protected void extend(ServerConnector target) {
        getParent().getWidget().addDomHandler(event -> {
            if (event.getNativeButton() == NativeEvent.BUTTON_MIDDLE) {
                event.preventDefault();
                CellReference<JsonObject> cell = getParent().getWidget().getEventCell();
                getRpcProxy(Rpc.class).middleClick(cell.getRow().getString(DataCommunicatorConstants.KEY), getParent().getColumnId(cell.getColumn()),
                        MouseEventDetailsBuilder.buildMouseEventDetails(event.getNativeEvent(), event.getRelativeElement()));
            }
        }, MouseDownEvent.getType());
    }

    @Override
    public GridConnector getParent() {
        return (GridConnector) super.getParent();
    }

    public interface Rpc extends ServerRpc {
        void middleClick(String rowKey, String columnInternalId, MouseEventDetails details);
    }
}
person F43nd1r    schedule 16.01.2018