【问题标题】:JavaFX - TextArea, how to activate the textarea only on double click?JavaFX - TextArea,如何仅在双击时激活 textarea?
【发布时间】:2017-04-25 22:04:04
【问题描述】:

JavaFX 2.2 - JDK 1.8.0_121

我在一个矩形内有一个 TextArea,它也恰好有一个鼠标监听器。问题是当我点击 TextArea 时,它会消耗事件并且矩形没有得到点击。

以下面的代码为例:

Group g = new Group();

Rectangle rect = new Rectangle(100,100);

TextArea textArea = new TextArea("Test");
textArea.setTranslateX(rect.getX());
textArea.setTranslateY(rect.getY());
textArea.setMinWidth(rect.getWidth());
textArea.setMinHeight(rect.getHeight());

//Calling a method to add an onMouseClickedProperty() mouse listener to the rectangle
addMouseListener(rect) 

g.getChildren().addAll(rect, textArea);

在上述情况下,TextArea 占用的空间与矩形一样多,因此当我单击它时,TextArea 会消耗 onMouseClickedProperty() 事件。

有没有办法从 TextArea 中“禁用”或“删除”onMouseClickedProperty(),而是在发生双击时触发它?希望鼠标单击会被矩形消耗掉。

谢谢。

编辑:

我找到了一个可行的解决方案,它并不完美,但比 cmets 中讨论的要合适得多。

由于您无法阻止 TextArea 使用 MOUSED_PRESSED 事件,因此在 TextArea 区域执行之前处理事件的唯一方法是使用事件过滤器。

因此,使用上面的示例代码,我调用方法 addMouseListener(rect) 而不是仅使用鼠标侦听器,而是添加事件过滤器,而不是将其添加到矩形我将它添加到组中。

private void addMouseLisenter(Group group){

group.addEventFilter(MouseEvent.MOUSE_PRESSED,
                new EventHandler<MouseEvent>() {
                    public void handle(MouseEvent event) {
                        //Code here    
                    }
                 });
    }

这样,组和 TextArea 都可以点击鼠标。

注意:如果只希望组获得鼠标点击,可以添加 event.consume()。

我希望这可以帮助将来寻找类似东西的人。

【问题讨论】:

    标签: java javafx event-handling textarea mouselistener


    【解决方案1】:

    我很确定你必须拥有 MouseListener 不幸的是,如果你想让文本区域对鼠标做出反应,它必须拥有监听器,这是所有鼠标事件的主要类。

    就检测双击而言,还有另一个线程包含您正在寻找的答案answered by Uluk Biy

    mipa 提出的另一个答案可能会回答您关于检测单击和双击之间差异的问题,但是如果节点相互重叠。

    编辑

    也许在这种情况下,可能值得修改 mipa 的答案,尝试将其添加到您的代码中(在适用区域)

    Integer clickCount = 0;
    
    ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
    ScheduledFuture<?> scheduledFuture;
    
    root.setOnMouseClicked(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent e) {
                if (e.getButton().equals(MouseButton.PRIMARY) && clickCount < 1) {
                        scheduledFuture = executor.schedule(() -> clickAction(), 500, TimeUnit.MILLISECONDS);    
                }
                clickCount += 1;
            }
    });
    
    private void clickAction() {
        if (clickCount == 1) {
           //actions for single click
           clickCount = 0;
        } else if (clickCount > 1) {
           //action for multiple clicks
           clickCount = 0;
        }
    }
    

    【讨论】:

    • 之前找到了上面的答案,我尝试了它,希望它会覆盖单击并仅在双击时触发事件,但遗憾的是单击仍然没有触发。我想到了一个解决方法,还没有尝试过,我不是很热衷。我正在考虑将 TextArea 可见性设置为 false 并在其顶部有一个标签,当有人双击标签时,该标签将变为不可见并且 textarea 会出现。一旦失去焦点,来自 textarea 的文本将被传输回标签并将标签设置为可见,对此有什么想法吗?
    • 即使有了 mipa 的回答?这会创建一个计时器,它会等待第二次点击,然后再假定它只是单次点击?
    • 哦,对不起,完全错过了 mipas 答案的那一部分,我现在看看,我会告诉你的。谢谢。
    • 它不起作用,只需单击一下,他的代码就会工作并在 500 毫秒内打印消息,但 TextArea 会立即获得焦点,而不是等待 500 毫秒结束。
    • 修复您的编辑,您必须实例化执行程序,但即便如此,与 mipa 的答案一样会发生同样的事情。在 500 毫秒延迟后,单击代码将运行,但 TextArea 会立即获得焦点。感觉好像还有一些其他事件可以为 TextArea 处理这些事件。我什至尝试过 onMouseClickedProperty() 而不是 onMouseClicked() 但结果相同。
    【解决方案2】:

    我找到了比所讨论的更合适的解决方案,请检查我的问题中的 EDIT。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-26
      • 2013-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多