我正在调整此处的代码:
Value Change Listener to JTextField
编辑2
当我按向上微调箭头时,以下代码给出了无限循环的对话框:
STRING: STRING:10 VALS:10 串: STRING:10 VALS:10 串: STRING:10 VALS:10 .....
警告您需要使用taskmanager来杀死它。
public static void main(String[] args) {
// TODO Auto-generated method stub
JFrame F = new JFrame();
F.setVisible(true);
JPanel p = new JPanel();
final JSpinner spin2 = new JSpinner();
spin2.setModel(new SpinnerNumberModel(10, 10, 100, 1));
JComponent comp = spin2.getEditor();
JFormattedTextField field = (JFormattedTextField) comp.getComponent(0);
DefaultFormatter formatter = (DefaultFormatter) field.getFormatter();
formatter.setCommitsOnValidEdit(true);
((JSpinner.DefaultEditor)spin2.getEditor()).getTextField().getDocument().addDocumentListener(new DocumentListener() {
public void changedUpdate(DocumentEvent e) {
warn();
}
public void removeUpdate(DocumentEvent e) {
warn();
}
public void insertUpdate(DocumentEvent e) {
warn();
}
public void warn() {
String text = ((JSpinner.DefaultEditor)spin2.getEditor()).getTextField().getText();
JOptionPane.showMessageDialog(null, "STRING: "+text, "Error Massage", JOptionPane.ERROR_MESSAGE);
if (text != null && !text.trim().isEmpty()) {
int stringValue = Integer.parseInt(((JSpinner.DefaultEditor)spin2.getEditor()).getTextField().getText());
JOptionPane.showMessageDialog(null,
"VALS: "+spin2.getValue(), "Error Massage",
JOptionPane.ERROR_MESSAGE);
if (stringValue<10 || stringValue >100){
JOptionPane.showMessageDialog(null,
"Error: Number outside bounds", "Error Massage",
JOptionPane.ERROR_MESSAGE);
}
}
}
});
p.add(spin2);
F.add(p);
F.pack();
F.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
编辑3
当无效时,背景变为红色,当字段失去焦点时,BUT值将恢复为之前(如果无效)。我希望能够在这一点上建立一个JOptionPane,表示值仍然无效,而不是恢复到之前:
((JSpinner.DefaultEditor)Position.getEditor()).getTextField().addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
//LOG.info("" + evt);
if ("editValid".equals(evt.getPropertyName())) {
if (Boolean.FALSE.equals(evt.getNewValue())) {
SpinnerNumberModel model = (SpinnerNumberModel) Position.getModel();
((JSpinner.DefaultEditor)Position.getEditor()).getTextField().setBackground(Color.RED);
((JSpinner.DefaultEditor)Position.getEditor()).getTextField().setToolTipText("Amount must be in range [ " + model.getMinimum() + " ... " + model.getMaximum() + " ] for this symbol");
}
else{
((JSpinner.DefaultEditor)Position.getEditor()).getTextField().setBackground(Color.WHITE);
}
}
}
});
/////////////////////////////////////////////// ////////////////////////////////////////////////// /
原始问题
但是如果我使用微调器放入低于下限的值。我在文本字段中得到一个“(”,这个错误:
线程中的异常“AWT-EventQueue-0”java.lang.NumberFormatException:对于输入字符串:“” at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) 在java.lang.Integer.parseInt(Integer.java:504) 在java.lang.Integer.parseInt(Integer.java:527) 在com.NResearch.ValueAtRisk.Sigma $ 7.warn(Sigma.java:626) 在com.NResearch.ValueAtRisk.Sigma $ 7.removeUpdate(Sigma.java:619) 在javax.swing.text.AbstractDocument.fireRemoveUpdate(AbstractDocument.java:260) 在javax.swing.text.AbstractDocument.handleRemove(AbstractDocument.java:623) 在javax.swing.text.AbstractDocument.remove(AbstractDocument.java:591) 在javax.swing.text.AbstractDocument.replace(AbstractDocument.java:667) at javax.swing.text.JTextComponent.setText(JTextComponent.java:1718) 在javax.swing.JFormattedTextField $ AbstractFormatter.install(JFormattedTextField.java:949) 在javax.swing.text.DefaultFormatter.install(DefaultFormatter.java:124) 在javax.swing.text.InternationalFormatter.install(InternationalFormatter.java:285) 在javax.swing.JFormattedTextField.setFormatter(JFormattedTextField.java:465) 在javax.swing.JFormattedTextField.setValue(JFormattedTextField.java:789) 在javax.swing.JFormattedTextField.processFocusEvent(JFormattedTextField.java:636) at java.awt.Component.processEvent(Component.java:6261) at java.awt.Container.processEvent(Container.java:2229) at java.awt.Component.dispatchEventImpl(Component.java:4861) at java.awt.Container.dispatchEventImpl(Container.java:2287) at java.awt.Component.dispatchEvent(Component.java:4687) at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1895) at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:938) at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:570) at java.awt.Component.dispatchEventImpl(Component.java:4731) at java.awt.Container.dispatchEventImpl(Container.java:2287) at java.awt.Component.dispatchEvent(Component.java:4687) at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:735) at java.awt.EventQueue.access $ 200(EventQueue.java:103) at java.awt.EventQueue $ 3.run(EventQueue.java:694) at java.awt.EventQueue $ 3.run(EventQueue.java:692) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain $ 1.doIntersectionPrivilege(ProtectionDomain.java:76) at java.security.ProtectionDomain $ 1.doIntersectionPrivilege(ProtectionDomain.java:87) at java.awt.EventQueue $ 4.run(EventQueue.java:708) at java.awt.EventQueue $ 4.run(EventQueue.java:706) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain $ 1.doIntersectionPrivilege(ProtectionDomain.java:76) at java.awt.EventQueue.dispatchEvent(EventQueue.java:705) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138) at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
final JSpinner spin2 = new JSpinner();
spin2.setModel(new SpinnerNumberModel(10, 10, 100, 1));
JComponent comp = spin2.getEditor();
JFormattedTextField field = (JFormattedTextField) comp.getComponent(0);
DefaultFormatter formatter = (DefaultFormatter) field.getFormatter();
formatter.setCommitsOnValidEdit(true);
((JSpinner.DefaultEditor)spin2.getEditor()).getTextField().getDocument().addDocumentListener(new DocumentListener() {
public void changedUpdate(DocumentEvent e) {
warn();
}
public void removeUpdate(DocumentEvent e) {
warn();
}
public void insertUpdate(DocumentEvent e) {
warn();
}
public void warn() {
int stringValue = Integer.parseInt(((JSpinner.DefaultEditor)spin2.getEditor()).getTextField().getText());
JOptionPane.showMessageDialog(null,
"VALS: "+spin2.getValue(), "Error Massage",
JOptionPane.ERROR_MESSAGE);
if (stringValue<10 || stringValue >100){
JOptionPane.showMessageDialog(null,
"Error: Please enter number bigger than 0", "Error Massage",
JOptionPane.ERROR_MESSAGE);
}
}
});
答案 0 :(得分:3)
自定义DocumentListeners和formattedTextField不能很好地相互配合,最好不要混合。相反,在文本字段上使用PropertyChangeListener来侦听其editValid属性的更改:每当更改为false时,您都可以通知用户
field.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
LOG.info("" + evt);
if ("editValid".equals(evt.getPropertyName())
&& Boolean.FALSE.equals(evt.getNewValue())) {
SpinnerNumberModel model = (SpinnerNumberModel) spin2.getModel();
JOptionPane.showMessageDialog(null,
"Error: Number must be in range [" + model.getMinimum() + " ..." + model.getMaximum() + "]",
"Error Massage",
JOptionPane.ERROR_MESSAGE);
}
}
});
顺便说一下,个人而言,我同意Mad的观点 - 这种侵扰性通知往往会让我烦恼,也许也会影响你的用户..
答案 1 :(得分:2)
您有几个基本选择。
String
就个人而言,我想同时做两件事......
public void warn() {
String text = ((JSpinner.DefaultEditor)spin2.getEditor()).getTextField().getText();
if (text != null && !text.trim().isEmpty()) {
try {
int stringValue = Integer.parseInt(text);
JOptionPane.showMessageDialog(null,
"VALS: "+spin2.getValue(), "Error Massage",
JOptionPane.ERROR_MESSAGE);
if (stringValue<10 || stringValue >100){
JOptionPane.showMessageDialog(null,
"Error: Please enter number bigger than 0", "Error Massage",
JOptionPane.ERROR_MESSAGE);
}
} catch (NumberFormatException exp) {
exp.printStackTrace();
}
}
}
现在,作为用户,这可能只会让我烦恼。突出显示字段,发出哔哔声,更改工具提示,当然,在我脸上抛出一个对话框......嗯......
您可以查看Validating Input,这样您就可以在字段失去焦点时验证输入,这个人可能是更好的选择。
如果您不特别需要JSpinner
的功能(在序列中上下运行值),您可以查看使用DocumentFilter
({{3} }}),它将允许您控制进入该字段的内容。您应该知道将DocumentFilter
添加到JSpinner
...:P
答案 2 :(得分:0)
Exception表示传递给Integer.parseInt(..)
的String是一个空字符串。因此,在将((JSpinner.DefaultEditor)spin2.getEditor()).getTextField().getText()
传递给Integer.parseInt(..)
你可以看看apache commons-io和StringUtils类,它们有很多好方法可以减轻检查空/空字符串的痛苦
答案 3 :(得分:0)
这被证明是后方的巨大痛苦。我想立即为文本字段背景上色。最终制作了一个可以覆盖我要使用的编辑器的编辑器,然后将其相应地设置为Spinners编辑器。到目前为止似乎为我工作。
添加一个带有以下内容的Java类(删除代码块周围的引号,我在使用堆栈溢出的编辑器时遇到了麻烦):
`public class CustomNumberEditor extends JSpinner.NumberEditor {
public CustomNumberEditor( JSpinner spinner ) {
super( spinner );
((DefaultFormatter ) ((JFormattedTextField) getComponent( 0 )).getFormatter()).setCommitsOnValidEdit( true );
}
@Override public void propertyChange(PropertyChangeEvent e) {
super.propertyChange( e );
if( e.getPropertyName().equals( "value" ) )
doStuff( (int) e.getNewValue() );
}
private void doStuff( int value )
{
//do stuff
}
}`
然后在添加微调器时,执行以下操作:
_quantitySpinner.setEditor(new CustomNumberEditor(_quantitySpinner));