java - 如何在禁用 Swing D&D 时覆盖 JTextPane 的选择行为?

标签 java swing drag-and-drop jtextpane jtextcomponent

背景:我在我的(高度)自定义的 JTextPane 子类中使用自定义 AWT D&D。换句话说,我使用 pane.setDragEnabled(false) 禁用了 Swing 的 D&D,并使用了我自己的 DragSource、DragGestureListener 等。

问题:禁用 Swing 的 D&D 时,JTextPane 中的默认选择行为如下:

  1. 使用鼠标选择一些文本
  2. 鼠标在选区内按下以开始拖动

期望:选择不会丢失。 实际:按下鼠标后,选择立即丢失,没有机会开始拖动操作,因为现在没有可拖动的东西。

我已经将其部分追溯到 BasicTextUI$DragListener,因为这是调用 Pane 的 getDragEnabled() 方法的类,但 BasicTestUI 似乎对文本组件的选择没有太多作用。因此,我仍然不完全了解清除选择的位置,但我需要找到它以便消除该行为。

我采用了一种 hack,涉及从 carat 监听器设置持久高亮,因此即使选择丢失,我的拖动可以与之交互的高亮仍然存在。我对此并不满意,而且它还有其他副作用。

非常感谢任何指点。

最佳答案

在查看 JDK 源代码的多个小时后,我确定选择行为是由插入符控制的,而不是文本组件或 UI 层次结构中的任何内容。

适度定制的 Caret 似乎可以解决问题。请注意,如果您不重写 mouseDragged(),自定义拖动仍然有效,但在拖动开始后通常会在 Pane 中更改选择,使用户认为他们只是拖动了他们选择的文本的一部分。

              textPane.setCaret(new DefaultCaret() {
                @Override
                public void mousePressed(MouseEvent evt) {
                    int pos = textPane.viewToModel(evt.getPoint());
                    if (pos > textPane.getSelectionStart() && pos < textPane.getSelectionEnd()) {
                        return;
                    }
                    super.mousePressed(evt);
                }

                @Override
                public void mouseDragged(MouseEvent e) {
                    if (dragItem != null) return;
                    super.mouseDragged(e);
                }
            });

关于java - 如何在禁用 Swing D&D 时覆盖 JTextPane 的选择行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20427878/

相关文章:

java - Swing应用程序多线程设计模式和最佳实践

javascript - 通过拖放将 KnockoutJS 与 JQuery 结合使用

鼠标/拖动事件上的 JavaFX 飞盘运动

java - Spring CORS错误

java - 来电期间 Activity 生命周期的异常行为 : delayed onStop()

java - 如何在某些子句上禁用 JButton?

java - 使用 JPanel Java 自动调整 JFrame 的大小

使用实时事件进行 jQuery 拖放

java - 错误: int cannot be dereferenced in java

java - JBOSS eap 6.1.0 中的 Spring 框架 JNDI 配置问题