在 JTextArea 上调度关键事件不会移动插入符号
Dispatching key events on JTextArea doesn't move the caret
我想在 JTextArea 上模拟按键。我会使用机器人 class,但我想输入的 window 没有焦点。所以我有这样的场景:
public class Test {
public static void main(String[] args) {
Frame frame = new Frame();
JTextArea text = new JTextArea();
frame.add(text);
frame.pack();
frame.setVisible(true);
text.dispatchEvent(new KeyEvent(text,
KeyEvent.KEY_TYPED, 0,
0,
KeyEvent.VK_UNDEFINED, 'H'));
text.dispatchEvent(new KeyEvent(text,
KeyEvent.KEY_TYPED, 0,
0,
KeyEvent.VK_UNDEFINED, 'L'));
}
}
但是输入H后,插入符号没有向右移动,导致L在H之前输入:该区域的最终文本是LH,但我希望它是HL。
我可以在 H 和 L 之间发送一个新的键事件,将插入符号向右移动(向右箭头)或调用 setCaretPosition 并且这会起作用,但我正在寻找一个不移动插入符号的解决方案手动操作,就像一个人打字一样(我正在制作一个测试器来测试学生的作业)。
有什么想法吗?
自定义插入符号以始终更新其位置。
final DefaultCaret caret = new DefaultCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
text.setCaret(caret);
来自 DefaultCaret JavaDoc
The following update policies are allowed:
NEVER_UPDATE: the caret stays at the same absolute position in the document regardless of any document updates, except when document length becomes less than the current caret position due to removal. In that case caret position is adjusted to the end of the document. The caret doesn't try to keep itself visible by scrolling the associated view when using this policy.
ALWAYS_UPDATE: the caret always tracks document changes. For regular changes it increases its position if an insertion occurs before or at its current position, and decreases position if a removal occurs before its current position. For undo/redo updates it is always moved to the position where update occurred. The caret also tries to keep itself visible by calling adjustVisibility method.
UPDATE_WHEN_ON_EDT: acts like ALWAYS_UPDATE if the document updates are performed on the Event Dispatching Thread and like NEVER_UPDATE if updates are performed on other thread.
The default property value is UPDATE_WHEN_ON_EDT.
Steve 更改默认插入符号的解决方案非常有效,但还有另一种解决方案,即在主线程中执行所有按键操作,如下所示:
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
// dispatch the event now
text.dispatchEvent(new KeyEvent(text, KeyEvent.KEY_TYPED, 0, 0, KeyEvent.VK_UNDEFINED, 'H'));
}
});
似乎在主线程中调度 KeyEvents 时,它们会自动移动插入符号。
到目前为止,这对我来说似乎是最好的解决方案。
我想在 JTextArea 上模拟按键。我会使用机器人 class,但我想输入的 window 没有焦点。所以我有这样的场景:
public class Test {
public static void main(String[] args) {
Frame frame = new Frame();
JTextArea text = new JTextArea();
frame.add(text);
frame.pack();
frame.setVisible(true);
text.dispatchEvent(new KeyEvent(text,
KeyEvent.KEY_TYPED, 0,
0,
KeyEvent.VK_UNDEFINED, 'H'));
text.dispatchEvent(new KeyEvent(text,
KeyEvent.KEY_TYPED, 0,
0,
KeyEvent.VK_UNDEFINED, 'L'));
}
}
但是输入H后,插入符号没有向右移动,导致L在H之前输入:该区域的最终文本是LH,但我希望它是HL。
我可以在 H 和 L 之间发送一个新的键事件,将插入符号向右移动(向右箭头)或调用 setCaretPosition 并且这会起作用,但我正在寻找一个不移动插入符号的解决方案手动操作,就像一个人打字一样(我正在制作一个测试器来测试学生的作业)。
有什么想法吗?
自定义插入符号以始终更新其位置。
final DefaultCaret caret = new DefaultCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
text.setCaret(caret);
来自 DefaultCaret JavaDoc
The following update policies are allowed:
NEVER_UPDATE: the caret stays at the same absolute position in the document regardless of any document updates, except when document length becomes less than the current caret position due to removal. In that case caret position is adjusted to the end of the document. The caret doesn't try to keep itself visible by scrolling the associated view when using this policy.
ALWAYS_UPDATE: the caret always tracks document changes. For regular changes it increases its position if an insertion occurs before or at its current position, and decreases position if a removal occurs before its current position. For undo/redo updates it is always moved to the position where update occurred. The caret also tries to keep itself visible by calling adjustVisibility method.
UPDATE_WHEN_ON_EDT: acts like ALWAYS_UPDATE if the document updates are performed on the Event Dispatching Thread and like NEVER_UPDATE if updates are performed on other thread.
The default property value is UPDATE_WHEN_ON_EDT.
Steve 更改默认插入符号的解决方案非常有效,但还有另一种解决方案,即在主线程中执行所有按键操作,如下所示:
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
// dispatch the event now
text.dispatchEvent(new KeyEvent(text, KeyEvent.KEY_TYPED, 0, 0, KeyEvent.VK_UNDEFINED, 'H'));
}
});
似乎在主线程中调度 KeyEvents 时,它们会自动移动插入符号。 到目前为止,这对我来说似乎是最好的解决方案。