调用 modelToView() 方法冻结 Java Swing 应用程序
Calling modelToView() method freezes Java Swing application
我正在 Java 中创建音译工具。它几乎完成了。
但是,当我输入得太快时,GUI 会冻结。
因此,我调试了应用程序以查明命令发生的位置。
对方法 JTextField.modelToView(pos)
的调用导致了这一点,这进一步调用了 TextUI.modelToView(JTextComponent c, int pos)
.
看来,该方法首先通过调用AbstractDocument::readLock()
方法获取文本组件文档的锁,其源代码为:
public synchronized final void readLock() {
try {
while (currWriter != null) {
if (currWriter == Thread.currentThread()) {
// writer has full read access.... may try to acquire
// lock in notification
return;
}
wait();
}
numReaders += 1;
} catch (InterruptedException e) {
throw new Error("Interrupted attempt to aquire read lock");
}
}
如果当前线程不是写入线程,则调用 wait()
。
但是,我只是在按下 space 键时改变文档,我相信这发生在美国东部时间。而且,Swing
也会在 EDT 中对其进行变异。另外,我在调用 DocumentListener.insertUpdate(DocumentEvent)
时调用 JTextField.modelToView(pos)
。
那么,请问是什么原因,应用卡死了!
截图如下:
应用截图
当应用程序冻结时
如果我最小化和最大化 window
I am calling JTextField.modelToView(pos) when DocumentListener.insertUpdate(DocumentEvent) is invoked.
触发 DocumentEvent 时,文档尚未完全更新。将您的代码包装在 SwingUtilities.invokeLater(...)
中的 DocumentListener 中。这应该会导致您的事件代码在文档完成自身更新后执行。
我正在 Java 中创建音译工具。它几乎完成了。 但是,当我输入得太快时,GUI 会冻结。
因此,我调试了应用程序以查明命令发生的位置。
对方法 JTextField.modelToView(pos)
的调用导致了这一点,这进一步调用了 TextUI.modelToView(JTextComponent c, int pos)
.
看来,该方法首先通过调用AbstractDocument::readLock()
方法获取文本组件文档的锁,其源代码为:
public synchronized final void readLock() {
try {
while (currWriter != null) {
if (currWriter == Thread.currentThread()) {
// writer has full read access.... may try to acquire
// lock in notification
return;
}
wait();
}
numReaders += 1;
} catch (InterruptedException e) {
throw new Error("Interrupted attempt to aquire read lock");
}
}
如果当前线程不是写入线程,则调用 wait()
。
但是,我只是在按下 space 键时改变文档,我相信这发生在美国东部时间。而且,Swing
也会在 EDT 中对其进行变异。另外,我在调用 DocumentListener.insertUpdate(DocumentEvent)
时调用 JTextField.modelToView(pos)
。
那么,请问是什么原因,应用卡死了!
截图如下:
应用截图
当应用程序冻结时
如果我最小化和最大化 window
I am calling JTextField.modelToView(pos) when DocumentListener.insertUpdate(DocumentEvent) is invoked.
触发 DocumentEvent 时,文档尚未完全更新。将您的代码包装在 SwingUtilities.invokeLater(...)
中的 DocumentListener 中。这应该会导致您的事件代码在文档完成自身更新后执行。