Щелчок NatTable не слышен слушателем - PullRequest
0 голосов
/ 04 марта 2020

Следующий SSCCE:

  • создает Natxable 1x1 с меткой «BUTTON», примененной к отдельной содержащей ячейке
  • добавляет ButtonCellPainter, который работает (ячейка выглядит как кнопка )
  • пытается добавить прослушиватель щелчков, который не работает (иначе я бы увидел "ТЫ ЗДЕСЬ" в stderr)

Бит, который я запутался, находится между START OF CONFUSION & END OF CONFUSION строки комментариев - остальное - материал для настройки примера. Я пытался следовать предоставленному примеру Rendering_cells_as_a_link_and_button, но, очевидно, я кое-что здесь напутал.

Производительность и эстетика NatTable действительно потрясающие; было бы неплохо, чтобы кто-то указал на мою ошибку здесь, чтобы я мог добавить это в свой проект: -)

import org.eclipse.nebula.widgets.nattable.*;
import org.eclipse.nebula.widgets.nattable.config.*;
import org.eclipse.nebula.widgets.nattable.data.*;
import org.eclipse.nebula.widgets.nattable.grid.layer.*;
import org.eclipse.nebula.widgets.nattable.hideshow.*;
import org.eclipse.nebula.widgets.nattable.layer.*;
import org.eclipse.nebula.widgets.nattable.layer.cell.*;
import org.eclipse.nebula.widgets.nattable.painter.cell.*;
import org.eclipse.nebula.widgets.nattable.selection.*;
import org.eclipse.nebula.widgets.nattable.ui.action.*;
import org.eclipse.nebula.widgets.nattable.ui.binding.*;
import org.eclipse.nebula.widgets.nattable.ui.matcher.*;
import org.eclipse.nebula.widgets.nattable.viewport.*;
import org.eclipse.swt.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;

public class NatTableTest extends Dialog implements IDataProvider, IConfigLabelAccumulator {

    @Override protected Control createDialogArea(Composite parent) {
        Composite toReturn = (Composite) super.createDialogArea(parent);
        toReturn.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        IDataProvider dataProvider = this; 
        DataLayer bodyDataLayer = new DataLayer(dataProvider);
        bodyDataLayer.setConfigLabelAccumulator(this);
        RowHideShowLayer rowHideShowLayer = new RowHideShowLayer(bodyDataLayer);
        SelectionLayer selectionLayer = new SelectionLayer(rowHideShowLayer);
        ViewportLayer viewportLayer = new ViewportLayer(selectionLayer);
        DataLayer rowDataLayer = new DefaultRowHeaderDataLayer(dataProvider);
        ILayer rowLayer = new RowHeaderLayer(rowDataLayer, viewportLayer, selectionLayer);
        DataLayer headerDataLayer = new DefaultColumnHeaderDataLayer(dataProvider);
        ILayer headerLayer = new ColumnHeaderLayer(headerDataLayer, viewportLayer, selectionLayer);
        DataLayer cornerDataLayer = new DataLayer(dataProvider);
        ILayer cornerLayer = new CornerLayer(cornerDataLayer, rowLayer, headerLayer);
        GridLayer gridLayer = new GridLayer(viewportLayer, headerLayer, rowLayer, cornerLayer);
        NatTable nattable = new NatTable(toReturn, gridLayer, false);
        nattable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        nattable.addConfiguration(new DefaultNatTableStyleConfiguration());

        // ================================================== START OF CONFUSION

        ButtonCellPainter buttonPainter = new ButtonCellPainter(new TextPainter());

        buttonPainter.addClickListener(new IMouseAction(){
            @Override public void run(NatTable table, MouseEvent event) {
                System.err.println("YOU ARE HERE");
            }
        });     

        nattable.addConfiguration(new AbstractUiBindingConfiguration(){
            @Override public void configureUiBindings(UiBindingRegistry registry) {
                CellLabelMouseEventMatcher mouseEventMatcher = new CellLabelMouseEventMatcher("BODY",1,"BUTTON");
                registry.registerMouseDownBinding(mouseEventMatcher, buttonPainter);
            }
        });

        IConfigRegistry configRegistry = new ConfigRegistry();

        configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_PAINTER, buttonPainter, "NORMAL","BUTTON");

        nattable.setConfigRegistry(configRegistry);

        // ================================================== END OF CONFUSION

        nattable.configure();
        return toReturn;
    }

    public NatTableTest(Shell parentShell) {super(parentShell);}

    // IDataProvider methods
    @Override public int getRowCount() {return 1;}
    @Override public int getColumnCount() {return 1;}
    @Override public Object getDataValue(int var1, int var2) {return "X";}
    @Override public void setDataValue(int var1, int var2, Object var3) {}

    // IConfigLabelAccumulator methods
    @Override public void accumulateConfigLabels(LabelStack labels, int col, int row) {labels.addLabel("BUTTON");}

}

edit: при отладке кажется, что в приведенном ниже (из UiBindingRegistry NatTable) regionLabels содержит только BODY:

    private IMouseAction getMouseEventAction(MouseEventTypeEnum mouseEventType, MouseEvent event) {
        try {
            LinkedList<MouseBinding> mouseEventBindings = (LinkedList) this.mouseBindingsMap.get(mouseEventType);
            if (mouseEventBindings != null) {
                LabelStack regionLabels = this.natTable.getRegionLabelsByXY(event.x, event.y);
                Iterator var6 = mouseEventBindings.iterator();

                while (var6.hasNext()) {
                    MouseBinding mouseBinding = (MouseBinding) var6.next();
                    if (mouseBinding.getMouseEventMatcher().matches(this.natTable, event, regionLabels)) {
                        return mouseBinding.getAction();
                    }
                }
            }
        } catch (Exception var7) {
            log.error("Exception on retrieving a mouse event action", var7);
        }

        return null;
    }

... не следует также возвращать сюда BUTTON, поскольку метка добавлена ​​в эту ячейку (я могу сказать, что регион добавлен правильно, так как ячейка отображается как кнопка)?

NatTable - 2.0.0.201910310701

1 Ответ

1 голос
/ 04 марта 2020

Проблема в том, что действия в один клик являются эксклюзивными. Итак, первый матч выигрывает. В вашем случае срабатывает SelectCellAction, который зарегистрирован DefaultSelectionBindings. А поскольку выбор срабатывает, щелчок кнопки пропускается.

В своем коде вы можете просто исправить это, используя registerFirstMouseDownBinding()

nattable.addConfiguration(new AbstractUiBindingConfiguration(){
        @Override public void configureUiBindings(UiBindingRegistry registry) {
            CellLabelMouseEventMatcher mouseEventMatcher = new CellLabelMouseEventMatcher("BODY",1,"BUTTON");
            registry.registerFirstMouseDownBinding(mouseEventMatcher, buttonPainter);
        }
    });

Таким образом, ваша привязка регистрируется поверх реестр и поэтому проверен первым. Поскольку наша проверка имеет больше условий (метка региона, маска состояния, кнопка мыши И метка ячейки), она запускается только в ячейках с меткой КНОПКА в области ТЕЛА. Ячейка кнопки тогда не может быть выбрана, что является правильным ИМХО. Но вы все равно можете выбрать другие ячейки, которые не имеют метки ячейки BUTTON.

Относительно вашего второго вопроса: Нет, метка BUTTON НЕ должна быть частью меток региона. Это метка ячейки, а не метка региона.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...