简体   繁体   English

在JTextArea上分发关键事件不会移动插入符号

[英]Dispatching key events on JTextArea doesn't move the caret

I want to simulate key presses on a JTextArea. 我想模拟JTextArea上的按键。 I would use the Robot class, but the window I want to type in doesn't have focus. 我将使用Robot类,但要输入的窗口没有焦点。 So I have a scenario like this: 所以我有这样的情况:

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'));
  }
}

But after the H is typed, the caret is not moved right, which causes L to be typed before H: the final text in the area is LH, but I want it to be HL. 但是在键入H之后,插入记号不会向右移动,这导致L在H之前键入:该区域中的最终文本是LH,但我希望它是HL。

I can dispatch a new key event in between H and L that would move the caret right (the right arrow) or call setCaretPosition and that would work, but I am searching for a solution that doesn't move the caret manually and behaves just like a person typing (I am making a tester for testing assignments from students). 我可以在H和L之间调度一个新的按键事件,该事件将向右移动插入符号(向右箭头)或调用setCaretPosition都可以,但是我正在寻找一种解决方案,该解决方案不能手动移动插入符号并且其行为类似于一个打字的人(我正在为测试学生的作业做一个测试员)。

Any ideas? 有任何想法吗?

Customise the caret to always update its position. 自定义插入符号以始终更新其位置。

final DefaultCaret caret = new DefaultCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
text.setCaret(caret);

From the DefaultCaret JavaDoc 从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. NEVER_UPDATE:插入符在文档中的绝对位置保持不变,而不考虑任何文档更新,除非文档长度由于移除而变得小于当前插入符的位置。 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. ALWAYS_UPDATE:脱字号始终跟踪文档更改。 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. 插入符号还尝试通过调用AdjustVisibility方法保持其可见性。

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. UPDATE_WHEN_ON_EDT:如果在事件调度线程上执行文档更新,则类似于ALWAYS_UPDATE;如果在其他线程上执行更新,则类似于NEVER_UPDATE。

The default property value is UPDATE_WHEN_ON_EDT. 默认属性值为UPDATE_WHEN_ON_EDT。

Steve's solution with changing the default caret works very well, but there is also another solution and that is to execute all the key presses in the main thread like this: 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'));
  }
});

It seems that when the KeyEvents are dispatched in the main thread, they automatically move the caret. 似乎在主线程中调度KeyEvent时,它们会自动移动插入符号。 This seems like the best solution to me so far. 到目前为止,这似乎是我最好的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM