我希望消息框在用户更改文本字段中的值后立即出现。目前,我需要按回车键来弹出消息框。我的代码有什么问题吗?
textField.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
if (Integer.parseInt(textField.getText())<=0){
JOptionPane.showMessageDialog(null,
"Error: Please enter number bigger than 0", "Error Message",
JOptionPane.ERROR_MESSAGE);
}
}
}
任何帮助都将不胜感激!
这里是@Boann的答案的Kotlin移植,这是一个很好的解决方案,对我来说一直很有效。
import java.beans.*
import javax.swing.*
import javax.swing.event.*
import javax.swing.text.*
/**
* Installs a listener to receive notification when the text of this
* [JTextComponent] is changed. Internally, it installs a [DocumentListener] on the
* text component's [Document], and a [PropertyChangeListener] on the text component
* to detect if the `Document` itself is replaced.
*
* @param changeListener a listener to receive [ChangeEvent]s when the text is changed;
* the source object for the events will be the text component
*/
fun JTextComponent.addChangeListener(changeListener: ChangeListener) {
val dl: DocumentListener = object : DocumentListener {
private var lastChange = 0
private var lastNotifiedChange = 0
override fun insertUpdate(e: DocumentEvent) = changedUpdate(e)
override fun removeUpdate(e: DocumentEvent) = changedUpdate(e)
override fun changedUpdate(e: DocumentEvent) {
lastChange++
SwingUtilities.invokeLater {
if (lastNotifiedChange != lastChange) {
lastNotifiedChange = lastChange
changeListener.stateChanged(ChangeEvent(this))
}
}
}
}
addPropertyChangeListener("document") { e: PropertyChangeEvent ->
(e.oldValue as? Document)?.removeDocumentListener(dl)
(e.newValue as? Document)?.addDocumentListener(dl)
dl.changedUpdate(null)
}
document?.addDocumentListener(dl)
}
你可以在任何文本组件上使用它,如下所示:
myTextField.addChangeListener { event -> myEventHandler(event) }
就像他的代码一样,也是公有领域。
我知道这涉及到一个非常老的问题,然而,它也给我带来了一些问题。正如kleopatra在上面的评论中回应的那样,我用JFormattedTextField解决了这个问题。然而,解决方案需要更多的工作,但更整洁。
在默认情况下,JFormattedTextField不会在字段中的每个文本更改后触发属性更改。JFormattedTextField的默认构造函数不创建格式化程序。
但是,要执行OP建议的操作,需要使用格式化程序,它将在字段的每次有效编辑之后调用commitEdit()方法。commitEdit()方法触发了我所看到的属性更改,如果没有格式化器,这将在焦点更改或按下enter键时默认触发。
详情见http://docs.oracle.com/javase/tutorial/uiswing/components/formattedtextfield.html#value。
创建一个默认的formatter (DefaultFormatter)对象,通过它的构造函数或setter方法传递给JFormattedTextField。默认格式化器的一个方法是setCommitsOnValidEdit(布尔提交),它设置格式化器在每次修改文本时触发commitEdit()方法。然后可以使用PropertyChangeListener和propertyChange()方法来获取。
只需创建一个扩展DocumentListener并实现所有DocumentListener方法的接口:
@FunctionalInterface
public interface SimpleDocumentListener extends DocumentListener {
void update(DocumentEvent e);
@Override
default void insertUpdate(DocumentEvent e) {
update(e);
}
@Override
default void removeUpdate(DocumentEvent e) {
update(e);
}
@Override
default void changedUpdate(DocumentEvent e) {
update(e);
}
}
然后:
jTextField.getDocument().addDocumentListener(new SimpleDocumentListener() {
@Override
public void update(DocumentEvent e) {
// Your code here
}
});
或者你甚至可以使用lambda表达式:
jTextField.getDocument().addDocumentListener((SimpleDocumentListener) e -> {
// Your code here
});