在JTextArea上调度关键事件不会移动插入符号

时间:2015-05-08 08:26:37

标签: java swing simulation jtextarea

我想在JTextArea上模拟按键。我会使用Robot类,但我想输入的窗口没有焦点。所以我有这样的场景:

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后,插入符号没有向右移动,这导致在H之前输入L:该区域中的最终文本是LH,但我希望它是HL。

我可以在H和L之间发送一个新的键事件,它会将插入符号向右移动(右箭头)或调用setCaretPosition,这样可行,但我正在寻找一个不会移动插入符号的解决方案手动和行为就像一个人打字(我正在制作测试人员来测试学生的作业)。

有什么想法吗?

2 个答案:

答案 0 :(得分:4)

自定义插入符以始终更新其位置。

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

来自DefaultCaret JavaDoc

  

允许以下更新政策:

     

NEVER_UPDATE:无论文档更新如何,插入符都保留在文档中的相同绝对位置,除非文档长度因删除而小于当前插入符号位置。在这种情况下,插入位置被调整到文档的末尾。使用此策略时,插入符号不会通过滚动关联的视图来保持自己可见。

     

ALWAYS_UPDATE:插入符始终跟踪文档更改。对于常规更改,如果插入发生在其当前位置之前或当前位置,则增加其位置;如果在其当前位置之前发生移除,则减少位置。对于撤消/重做更新,它总是移动到发生更新的位置。插入符也试图通过调用adjustVisibility方法保持自己可见。

     

UPDATE_WHEN_ON_EDT:如果在事件调度线程上执行文档更新,则表现为ALWAYS_UPDATE;如果在其他线程上执行更新,则表现为NEVER_UPDATE。

     

默认属性值为UPDATE_WHEN_ON_EDT。

答案 1 :(得分:0)

史蒂夫改变默认插入符号的解决方案非常有效,但还有另一个解决方案就是执行主线程中的所有按键操作,如下所示:

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时,它们会自动移动插入符号。 到目前为止,这似乎是我最好的解决方案。