我正在从这里改编代码:
值更改侦听器到JTextField
编辑2
当我按下向上微调箭头时,以下代码给我一个无限循环的对话框:
STRING:STRING:10个变量:10 STRING:STRING:10个变量:10 STRING:STRING:10个变量: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:对于输入字符串:java.lang.Integer.parseInt(Integer.java:java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)处的异常: 504),网址为com.NResearch.ValueAtRisk.Sigma $ 7.warn(Sigma.java:626),网址为com.NResearch.ValueAtRisk.Sigma $ 7.removeUpdate(Sigma.java),网址为com.NResearch.ValueAtRisk.Sigma $ 7.warn(Sigma.java:626) :619)在javax.swing.text.AbstractDocument.fireRemoveUpdate(AbstractDocument.java:260)在javax.swing.text.AbstractDocument.handleRemove(AbstractDocument.java:623)在javax.swing.text.AbstractDocument.remove(AbstractDocument。 javax.swing.text.AbstractDocument.replace(AbstractDocument.java:667)的javax.swing.text.JTextComponent.setText(JTextComponent.java:1718)的javax.swing.text.AbstractDocument.replace(AbstractDocument.java:667)。javax.swing.text.DefaultFormatter.install(DefaultFormatter.java:124)处的JFormattedTextField $ AbstractFormatter.install(JFormattedTextField.java:949)at javax.swing处的javax.swing.text.InternationalFormatter.install(InternationalFormatter.java:285) javax.swing的.JFormattedTextField.setFormatter(JFormattedTextField.java:465)在java.awt.Component.processEvent(JFormattedTextField.setValue(JFormattedTextField.java:789)在javax.swing.JFormattedTextField.processFocusEvent(JFormattedTextField.java:636)组件java.awt.Container.processEvent(Container.java:2229)上的Component.java:6261)java.awt.Container.dispatchEventImpl(Container.java:2287)上java.awt.Component.dispatchEventImpl(Component.java:4861)的)在java.awt.KeyboardFocusManager处的java.awt.Component.dispatchEvent(Component.java:4687)。java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:938)上的redispatchEvent(KeyboardFocusManager.java:1895)java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:570)上的java.awt.Component.dispatchEventImpl :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 java.security.ProtectionDomain的.AccessController.doPrivileged(本机方法)$ java.security的.doIntersectionPrivilege(ProtectionDomain.java:76)。java.awt.EventQueue $ 4.run(EventQueue.java:708)处的ProtectionDomain $ 1.doIntersectionPrivilege(ProtectionDomain.java:87)在java.security.AccessController处的java.awt.EventQueue $ 4.run(EventQueue.java:706)中。 java.security.ProtectionDomain上的doPrivileged(本机方法)$ 1.doIntersectionPrivilege(ProtectionDomain.java:76)在java.awt.EventQueue.dispatchEvent(EventQueue.java:705)在java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242) )的java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)的java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)的java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)的Java .EventDispatchThread.pumpEvents(EventDispatchThread.java:138),位于java.awt.EventDispatchThread。运行(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); } } });
自定义DocumentListeners和formattedTextField不能很好地配合使用,最好不要混用。而是在侦听其editValid属性更改的文本字段上使用PropertyChangeListener:每当更改为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的看法-这样的侵入性通知会惹恼我,也可能会惹恼您的用户。