SWT MouseDown事件对于自定义选择控件太占主导地位 [英] SWT MouseDown event too dominant for custom selecting controls

查看:73
本文介绍了SWT MouseDown事件对于自定义选择控件太占主导地位的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我制作了UI/编辑器,您可以在下图中看到.文字以StyledText s显示.黑线是自定义边框,实际上是Label并在其上绘制了线条.

I have made the UI/Editor you can see in the picture below. The Text is displayed by StyledTexts. The black lines are custom borders that are in fact Labels with lines drawn on them.

现在,我的目标是提供一个选择,允许用户选择Control来删除它们或向其中添加其他内容.第二张图片显示了示例选择.因此,从各种MouseEvent开始,这比我最初想象的要复杂.

Now my goal is to provide a selection that allows the user to select the Controls to delete them or add others to them. The second image shows a example selection. So started with all kinds of MouseEvents this is more complicated than I initially thought.

当在任何Control上触发MouseDown事件时,我无法跟踪用户想要选择的任何其他Control,因为MouseMove事件包含与触发MouseDown相同的控件事件,直到释放鼠标为止.我需要跟踪进行中的选择,以提供所选Control的视觉反馈.下面的代码显示了一个最小的示例来演示此行为.

When the MouseDown event is fired on any Control I am not able to track any other Controls that the user wants to select because the MouseMove event contains the same control that fired the MouseDown event until the mouse gets released. I need to track to ongoing selection to provide the visual feedback for the selected Controls. The code below shows a minimal example to demonstrate the behavior.

public class Tester {

    public static void main(String[] args)
    {
        Display display = new Display();
        final Shell shell = new Shell(display);
        shell.setLayout(new FillLayout());
        shell.setText("Stackoverflow");

        Composite comp = new Composite(shell, SWT.NONE);
        comp.setLayout(new GridLayout(1, true));
        SelectionListener listener = new SelectionListener();

        StyledText text = new StyledText(comp, SWT.NONE);
        text.setText("first text");
        attachListener(text, listener);
        text = new StyledText(comp, SWT.NONE);
        text.setText("second text");
        attachListener(text, listener);


        shell.pack();
        shell.open();
        while (!shell.isDisposed())
        {
            if (!display.readAndDispatch())
                display.sleep();
        }
        display.dispose();
    }

    private static void attachListener(Control control, Listener listener) {
        if(control != null && !control.isDisposed()){
            control.addListener(SWT.MouseDown, listener);
            control.addListener(SWT.MouseMove, listener);
            control.addListener(SWT.MouseEnter, listener);
            control.addListener(SWT.MouseUp, listener);
        }
    }

    static class SelectionListener implements Listener {

        Event lastEvent = null;

        @Override
        public void handleEvent(Event event) {
            switch(event.type){

            case SWT.MouseDown:
                lastEvent = event;
                break;

            case SWT.MouseMove:
                if(lastEvent != null){
                    if(event.widget == lastEvent.widget)
                        System.out.println("the same!!!");
                    else
                        System.out.println("not the same!!!");
                }
                break;

            case SWT.MouseEnter:
                //this also does not fire when MouseDown is fired
                System.out.println("entering");
                break;

            case SWT.MouseUp:
                lastEvent = null;
                break;
            }
        }

    }
}

因此,基本上,我正在寻求帮助.也许有一种更好/更简单的方法可以实现这一目标.我还试图弄清楚swt在支持多选的表或其他控件中是如何做到的.但是很难找到特定的代码,或者很难为表之类的nativ控件调用本机方法.因此,如果有人有想法,请分享.

So basically I am reaching out for help. Maybe there is a better/simpler way to achieve this. I was also trying to figure out how swt is doing this in tables or other controls that support multiple selection. But its hard to find the specific code or they call native methods for nativ controls such as tables. So if anyone has an idea please share.

推荐答案

我找到了解决问题的方法.您可以自己发布MouseUp事件.之后,所有事件再次发生.唯一困难的部分是区分您自己的自定义事件和普通用户/系统事件.我能够创建/找到一些标准来识别自定义事件.以下代码/文档对此进行了更详细的说明:

I found a solution for my problem. You can post a MouseUp event yourself. After that all events are coming through again. The only difficult part is to distinguish between your own custom event and a normal user/system event. I was able create/find some criteria to identify the custom event. The following code/doc explains this in more detail:

/**
     * Sets up a custom {@code SWT.MouseUp} event and fires it. This is needed because a {@code SWT.MouseDown} is consuming all
     * other events until a {@code SWT.MouseUp} event is fired. This means that it is not possible to get a e.g. 
     * {@code SWT.MouseEnter} event when entering a certain StyledText which is needed for selection. Therefore a custom {@code SWT.MouseUp} 
     * event is fired to simulate the releasing of the button on system level so that all other events can come through again. The real problem here
     * is to distinguish between the custom event for simulation and a normal event produced by the user. Firing the event via Display.post(Event)
     * does not fire the handed over event parameter. The system actually creates a new event instance. Therefore 2 criteria are used to distinguish the custom event:
     *  <ul>
     *      <ol>1. The selection can only be started by dragging a border control. 
     *          A {@code SWT.DragDetect} event starts the hole selection process. All events coming in before this event are ignored.</ol>
     *      <ol>2. The actual distinguishing of the {@code SWT.MouseUp} is performed on the cursor coordinates and the referenced/dragged {@code widget}.
     *          The dragging event has to be started on this widget.</ol>
     *  </ul>
     * @param the starting {@code SWT.DragDetect} event
     * @see #isCustomMouseUpEvent(Event)
     */
    private void fireCustomMouseUpEvent(Event dragDetectEvent){
        customMouseUpEvent = new Event();
        customMouseUpEvent.type = SWT.MouseUp;
        customMouseUpEvent.button = 1; //left mouse button
        customMouseUpEvent.widget = dragDetectEvent.widget;

        if(dragDetectEvent.widget instanceof Control){
            startingControl = (Control) dragDetectEvent.widget;
            //get cursor location relative to widget to be comparable later with the event fired by the system
            Point cursorLocation = startingControl.toControl(startingControl.getDisplay().getCursorLocation());
            customMouseUpEvent.x = cursorLocation.x;
            customMouseUpEvent.y = cursorLocation.y;
        }

        /*
         * note: set attributes like Event.data or Event.x are not present 
         * in the actually firing event. SWT or the system is creating a complete new
         * event instance without those manually added information.
         */
//      mouseUpEvent.data = SELECTION_START_EVENT_IDENTIFIER;
        if(dragDetectEvent.widget.getDisplay().post(customMouseUpEvent))
            System.out.println("custom MouseUp event fired!");
    }

    private boolean isCustomMouseUpEvent(Event event) {
        return customMouseUpEvent != null && event.widget == customMouseUpEvent.widget && 
                customMouseUpEvent.x == event.x && customMouseUpEvent.y == event.y;
    }

这篇关于SWT MouseDown事件对于自定义选择控件太占主导地位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆