在Java/Swing中,有没有一种方法可以合法地“尝试在通知中进行变异”?
我想知道是否有某种魔法可以用来绕过 IllegalStateException 并允许 JTextField “尝试在通知中发生变化”,或者换句话说,如果触发其侦听器,则设置自己的文本。
供您参考,我正在尝试编写一个自动完成函数,该函数返回 12 个枚举范围内最有可能的匹配项,以响应用户在 JTextField 中的输入。
这是代码示例。您必须原谅我笨拙的算法,它会产生枚举结果。我用注释突出显示了产生异常的代码:
jtfElement1.addCaretListener(new CaretListener() {
@Override
public void caretUpdate(CaretEvent e) {
String s = jtfElement1.getText();
int[] attributes = new int[13];
// iterate through each enum
for (BaseEnumAttributes b: BaseEnumAttributes.values()) {
// iterate through the length of the current text in jtfElement1
for (int i = 0; i < s.length(); i++) {
if (s.length() <= b.toString().length()) {
if (b.toString().charAt(i) == s.charAt(i)) {
// increase the number of "hits" noted for that enum
attributes[b.ordinal()] = attributes[b.ordinal()] + 1;
}
}
}
}
int priorC = 0;
int rightC = 0;
// iterate through the "array" of enums to find the highest score
for (int j = 0; j < attributes.length; j++) {
if (attributes[j] > priorC) {
priorC = attributes[j];
rightC = j;
}
}
if (!s.equals("")) {
// assign to b the Enum corresponding to the "array" with highest score
BaseEnumAttributes b = BaseEnumAttributes.values()[rightC];
iController.updateInputElement1String(b.toString());
// THIS TRIGGERS EXCEPTION
jtfElement1.setText(b.toString());
}
}
});
I was wondering if there is some sort of magic I can use to get around an IllegalStateException and allow a JTextField to "attempt to mutate in notification", or in other words to set its own text if its listener is triggered.
For your information, I am trying to program an auto-complete function which returns the most likely match in a range of 12 enums in response to a user's input in the JTextField.
Here is the code sample. You'll have to pardon my clumsy algorithm which creaks out enum results. I've highlighted the code which produces the exception with a comment:
jtfElement1.addCaretListener(new CaretListener() {
@Override
public void caretUpdate(CaretEvent e) {
String s = jtfElement1.getText();
int[] attributes = new int[13];
// iterate through each enum
for (BaseEnumAttributes b: BaseEnumAttributes.values()) {
// iterate through the length of the current text in jtfElement1
for (int i = 0; i < s.length(); i++) {
if (s.length() <= b.toString().length()) {
if (b.toString().charAt(i) == s.charAt(i)) {
// increase the number of "hits" noted for that enum
attributes[b.ordinal()] = attributes[b.ordinal()] + 1;
}
}
}
}
int priorC = 0;
int rightC = 0;
// iterate through the "array" of enums to find the highest score
for (int j = 0; j < attributes.length; j++) {
if (attributes[j] > priorC) {
priorC = attributes[j];
rightC = j;
}
}
if (!s.equals("")) {
// assign to b the Enum corresponding to the "array" with highest score
BaseEnumAttributes b = BaseEnumAttributes.values()[rightC];
iController.updateInputElement1String(b.toString());
// THIS TRIGGERS EXCEPTION
jtfElement1.setText(b.toString());
}
}
});
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您最好使用文档过滤器或自定义文档。
如果文档在事件分派期间不保持不变,其他侦听器期望看到什么?
You are probably better off using a document filter or a custom document.
What are other listeners expected to see if the document doesn't stay the same during event dispatch?
使用 SwingUtilities.invokeLater() 将所有修改放在那里
Use SwingUtilities.invokeLater() placing all the modifications there
也许您可以在 caretUpdate() 终止后使用线程来延迟 setText() 运行。
Maybe you can delay the setText() with a Thread to run after caretUpdate() has terminated.
我发现了同样的问题,但我找到了一个简单的解决方案:
当您将文本设置为 jTextField 时,通过布尔值 if(false) 锁定 caretUpdate() ,然后解锁它。 。像这样的东西:
布尔插入符= true;
私有无效 listValueChanged(javax.swing.event.ListSelectionEvent evt) {
插入符号=假;
name.setText((String)list.getSelectedValue());
插入符号=真;
}
i'm found on the same problem but i found an easy solution:
lock the caretUpdate() by a boolean if(false) while u'r setting the text to the jTextField than unlock it after . . something like this:
boolean caret = true;
private void listValueChanged(javax.swing.event.ListSelectionEvent evt) {
caret = false;
name.setText((String)list.getSelectedValue());
caret = true;
}
创建自定义文档并覆盖 insertString()
...
请注意,调用 setText 将导致递归调用 insertString(),因此请确保有停止条件。
Create a custom Document and override insertString( )
...
Note that calling setText will result in a recursive call to insertString( ), so make sure you have a stopping condition.
我很惊讶没有人回答这个问题,但是您最好实现一个可编辑的 JSpinner 与 SpinnerListModel ?
I'm surprised no one has answered this, but would'nt you have been better off implementing an editable JSpinner with a SpinnerListModel?