背景:我在我的(高度)自定义的 JTextPane 子类中使用自定义 AWT D&D。换句话说,我使用 pane.setDragEnabled(false)
禁用了 Swing 的 D&D,并使用了我自己的 DragSource、DragGestureListener 等。
问题:禁用 Swing 的 D&D 时,JTextPane 中的默认选择行为如下:
- 使用鼠标选择一些文本
- 鼠标在选区内按下以开始拖动
期望:选择不会丢失。 实际:按下鼠标后,选择立即丢失,没有机会开始拖动操作,因为现在没有可拖动的东西。
我已经将其部分追溯到 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/