1

我似乎遇到了 JTextPane 的问题。我已扩展 JTextPane 以呈现浮动图像,因为 JTextPane 图标功能不适合我的目的。我希望用户能够单击图像,并执行某些事件。但是,当我单击图像时,即使我使用 evt.consume(),插入符号和选择也会在 JTextPane 中更新。我通常希望与图像交互的单击和鼠标事件根本不会影响插入符号的位置或选择。相关代码:

public class JTextPaneImg extends JTextPane {

    public JTextPaneImg(){
        super();
        addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                formMousePressed(evt);
            }
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                formMouseReleased(evt);
            }
        });
    }

    private void formMousePressed(java.awt.event.MouseEvent evt) {                                  
        if (imgBound.contains(evt.getPoint())) {
             evt.consume();
             //Do some stuff in here to interact with the image
             // but the event still undesirably interacts with selection/caret
        }
    }   


    private void formMouseReleased(java.awt.event.MouseEvent evt) {                                  
        if (imgBound.contains(evt.getPoint())) {
             evt.consume();
             //Do some stuff in here to interact with the image
             // but the event still undesirably interacts with selection/caret
        }
    }   
}

我什至调用了 getMouseListeners 并验证我自己的鼠标侦听器是数组中的最后一个,我读到侦听器是从最高到最低索引调用的,这意味着如果我的侦听器调用消耗,它应该是最后一个对事件采取行动的。为什么我的鼠标单击事件仍在更新插入符号呢?这是外观和感觉的问题吗?

4

2 回答 2

1

我读到侦听器是从最高到最低索引调用的,这意味着如果我的侦听器调用消耗,它应该是最后一个对事件采取行动

不保证此订单。唯一可以保证的是所有听众都会收到通知。我相信由每个听众来检查事件是否被消耗。至少这是我的理解

您也许可以使用全局事件分派器来防止将事件分派到组件。请记住,所有事件都通过调度程序,因此代码应该是高效的,这样您就不会减慢队列速度。

或者您可以使用鼠标滚轮控制器上提供的技术,该技术从组件中删除所有侦听器并将其替换为您的自定义侦听器。然后,您可以决定何时将事件转发给其他侦听器。

或者,也许您的图像应该绘制在视口上,而不是文本窗格上。

于 2010-11-09T06:26:16.253 回答
0

通过创建我自己的插入符号来解决。问题是 DefaultCaret 实现不检查 e.isConsumed 鼠标事件,因此您必须覆盖并添加 isconsumed 检查。现在我的文本窗格的行为符合预期,因为我在构造函数中有以下代码:

    this.setCaret(new DefaultCaret() {

        @Override
        protected void positionCaret(MouseEvent e) {
            if (!e.isConsumed()) super.positionCaret(e);
        }

        @Override
        protected void moveCaret(MouseEvent e) {
            if (!e.isConsumed()) super.moveCaret(e);
        }
    });

这是我没有完全理解插入符号在事件模型中的作用的错。但是,如果你问我这有点愚蠢。从我读过的文档中,约定是让所有听众只有在 !e.isConsumed() 时才能切实行动。

于 2010-11-09T06:36:32.660 回答