Java 当滚动窗格包装文本窗格时,如何防止JScrollPane箭头键处理移动插入符号

Java 当滚动窗格包装文本窗格时,如何防止JScrollPane箭头键处理移动插入符号,java,swing,jscrollpane,jtextpane,caret,Java,Swing,Jscrollpane,Jtextpane,Caret,我有以下要求: 我需要一个可滚动的JTextPane。用户可以在此文本窗格中键入,也可以在其中插入用户未键入的文本。想象一下IM窗口之类的东西。尽管窗口必须是可滚动的,以允许用户查看以前键入的文本,但插入符号不应从文本末尾的位置移动。用户输入的任何文本都将始终显示在末尾 在JTextPane中,当用户使用滚动条滚动时,插入符号不移动。视口已调整。但是,当用户按下向上和向下箭头键时,JTextPane插入符号将随之移动(无论窗口是否滚动) 我想要的是,向上箭头键的功能与用鼠标向上移动滚动条的功能相

我有以下要求:

我需要一个可滚动的JTextPane。用户可以在此文本窗格中键入,也可以在其中插入用户未键入的文本。想象一下IM窗口之类的东西。尽管窗口必须是可滚动的,以允许用户查看以前键入的文本,但插入符号不应从文本末尾的位置移动。用户输入的任何文本都将始终显示在末尾

在JTextPane中,当用户使用滚动条滚动时,插入符号不移动。视口已调整。但是,当用户按下向上和向下箭头键时,JTextPane插入符号将随之移动(无论窗口是否滚动)

我想要的是,向上箭头键的功能与用鼠标向上移动滚动条的功能相同。箭头键应该与插入符号无关

我尝试了以下方法,但没有成功: 1) 将“无操作”操作添加到my text pane类的Keymap中(使用JTextPane.addKeymap()和Keymap.AddActionForkeyStrope())。这会阻止插入符号移动,但会阻止动作传递到滚动窗格以滚动视图。 2) 从my text pane类的keymap中删除箭头键。这会影响我的应用程序中的所有JTextPane,这不是我想要的

我想要的是在我的TextPane键映射中添加一个操作,该操作只调用ScrollPane操作来表示向上和向下箭头

实现这一目标的最佳方式是什么

我想到的一种可能性是实现一个KeyListener(在keymap之前接收按键笔划)来捕捉这些按键,然后手动实现滚动。 但这似乎需要我计算字体大小等。有没有更简单的方法


理想的情况是,如果有某种方法可以将插入符号“锚定”到文本的任何结尾。

您必须修改
键绑定

试着从这个开始

InputMap im = textArea.getInputMap(WHEN_FOCUSED);
ActionMap am = textArea.getActionMap();

am.get("caret-down").setEnabled(false);
am.get("caret-up").setEnabled(false);
既然你已经开始工作了,你需要担心所有这些

selection-up = shift pressed UP
caret-next-word = ctrl pressed RIGHT
selection-previous-word = shift ctrl pressed LEFT
selection-up = shift pressed KP_UP
caret-down = pressed DOWN
caret-previous-word = ctrl pressed LEFT
caret-end-line = pressed END
selection-page-up = shift pressed PAGE_UP
caret-up = pressed KP_UP
delete-next = pressed DELETE
caret-begin = ctrl pressed HOME
selection-backward = shift pressed LEFT
caret-end = ctrl pressed END
delete-previous = pressed BACK_SPACE
selection-next-word = shift ctrl pressed RIGHT
caret-backward = pressed LEFT
caret-backward = pressed KP_LEFT
selection-forward = shift pressed KP_RIGHT
delete-previous = ctrl pressed H
unselect = ctrl pressed BACK_SLASH
insert-break = pressed ENTER
selection-begin-line = shift pressed HOME
caret-forward = pressed RIGHT
selection-page-left = shift ctrl pressed PAGE_UP
selection-down = shift pressed DOWN
page-down = pressed PAGE_DOWN
delete-previous-word = ctrl pressed BACK_SPACE
delete-next-word = ctrl pressed DELETE
selection-backward = shift pressed KP_LEFT
selection-page-right = shift ctrl pressed PAGE_DOWN
caret-next-word = ctrl pressed KP_RIGHT
selection-end-line = shift pressed END
caret-previous-word = ctrl pressed KP_LEFT
caret-begin-line = pressed HOME
caret-down = pressed KP_DOWN
selection-forward = shift pressed RIGHT
selection-end = shift ctrl pressed END
selection-previous-word = shift ctrl pressed KP_LEFT
selection-down = shift pressed KP_DOWN
insert-tab = pressed TAB
caret-up = pressed UP
selection-begin = shift ctrl pressed HOME
selection-page-down = shift pressed PAGE_DOWN
delete-previous = shift pressed BACK_SPACE
caret-forward = pressed KP_RIGHT
selection-next-word = shift ctrl pressed KP_RIGHT
page-up = pressed PAGE_UP

您必须修改
KeyBindings

试着从这个开始

InputMap im = textArea.getInputMap(WHEN_FOCUSED);
ActionMap am = textArea.getActionMap();

am.get("caret-down").setEnabled(false);
am.get("caret-up").setEnabled(false);
既然你已经开始工作了,你需要担心所有这些

selection-up = shift pressed UP
caret-next-word = ctrl pressed RIGHT
selection-previous-word = shift ctrl pressed LEFT
selection-up = shift pressed KP_UP
caret-down = pressed DOWN
caret-previous-word = ctrl pressed LEFT
caret-end-line = pressed END
selection-page-up = shift pressed PAGE_UP
caret-up = pressed KP_UP
delete-next = pressed DELETE
caret-begin = ctrl pressed HOME
selection-backward = shift pressed LEFT
caret-end = ctrl pressed END
delete-previous = pressed BACK_SPACE
selection-next-word = shift ctrl pressed RIGHT
caret-backward = pressed LEFT
caret-backward = pressed KP_LEFT
selection-forward = shift pressed KP_RIGHT
delete-previous = ctrl pressed H
unselect = ctrl pressed BACK_SLASH
insert-break = pressed ENTER
selection-begin-line = shift pressed HOME
caret-forward = pressed RIGHT
selection-page-left = shift ctrl pressed PAGE_UP
selection-down = shift pressed DOWN
page-down = pressed PAGE_DOWN
delete-previous-word = ctrl pressed BACK_SPACE
delete-next-word = ctrl pressed DELETE
selection-backward = shift pressed KP_LEFT
selection-page-right = shift ctrl pressed PAGE_DOWN
caret-next-word = ctrl pressed KP_RIGHT
selection-end-line = shift pressed END
caret-previous-word = ctrl pressed KP_LEFT
caret-begin-line = pressed HOME
caret-down = pressed KP_DOWN
selection-forward = shift pressed RIGHT
selection-end = shift ctrl pressed END
selection-previous-word = shift ctrl pressed KP_LEFT
selection-down = shift pressed KP_DOWN
insert-tab = pressed TAB
caret-up = pressed UP
selection-begin = shift ctrl pressed HOME
selection-page-down = shift pressed PAGE_DOWN
delete-previous = shift pressed BACK_SPACE
caret-forward = pressed KP_RIGHT
selection-next-word = shift ctrl pressed KP_RIGHT
page-up = pressed PAGE_UP

如果您让用户放置插入符号,例如让他选择并复制一些文本,该怎么办


我会添加一个DocumentFilter(或覆盖文档的insertString()方法),并在所有情况下在doc.getLength()位置执行插入,并在插入后将插入符号重置为doc.getLength()位置。

如果您允许用户放置插入符号,例如让他选择并复制一些文本,会怎么样


我将添加一个DocumentFilter(或重写文档的insertString()方法),并在所有情况下在doc.getLength()位置执行插入,并在插入后将插入符号重置为doc.getLength()位置。

此组件不支持剪切/复制/粘贴,因此,此答案与案例无关。此组件不支持剪切/复制/粘贴,因此此答案与案例无关。此方法存在两个问题(我认为-没有尝试过)。此方法存在两个问题(我认为-没有尝试过)。1.我相信,JTextArea.getActionMap()检索到的动作映射是对来自外观的所有JTextArea的动作映射的引用,因此这样做将禁用所有此类组件的命令。2.仅禁用插入符号向上和向下是不够的。我们还需要使按键实现“ScrollPane.unitScrollUp”和“ScrollPane.unitScrollDown”。看起来很多标准的外观和感觉都没有考虑到需要无鼠标操作模式的场景。你的第一点是无效的。我一直在使用这种技术&它只会影响所讨论对象的实例。在我的测试中,当我向上或向下按时,插入符号会重新定位,但我能够滚动文本区域,我不知道这是否是您想要的功能。第三,对于KeyListeners,您无法确切地知道您在事件链中的什么位置被调用(或者如果所有OSs/look&feels的调用链都是相同的),那么,我可以纠正一下。我得试试这个。如果这个解决方案有效,它正是我想要的,而且比KeyListener的乱七八糟要好得多。我以前也有过类似的经历,但现在我明白了其中的区别。我正在从动作地图中删除动作,而你只是在禁用它。是的,这是蜜蜂的膝盖!我认为这种方法有两个问题(我认为-没有尝试过)。我认为这种方法有两个问题(我认为-没有尝试过)。1.我相信,JTextArea.getActionMap()检索到的动作映射是对来自外观的所有JTextArea的动作映射的引用,因此这样做将禁用所有此类组件的命令。2.仅禁用插入符号向上和向下是不够的。我们还需要使按键实现“ScrollPane.unitScrollUp”和“ScrollPane.unitScrollDown”。看起来很多标准的外观和感觉都没有考虑到需要无鼠标操作模式的场景。你的第一点是无效的。我一直在使用这种技术&它只会影响所讨论对象的实例。在我的测试中,当我向上或向下按时,插入符号会重新定位,但我能够滚动文本区域,我不知道这是否是您想要的功能。第三,对于KeyListeners,您无法确切地知道您在事件链中的什么位置被调用(或者如果所有OSs/look&feels的调用链都是相同的),那么,我可以纠正一下。我得试试这个。如果这个解决方案有效,它正是我想要的,而且比KeyListener的乱七八糟要好得多。我以前也有过类似的经历,但现在我明白了其中的区别。我正在从动作图中删除动作,而你