Я адаптирую код отсюда:
Прослушиватель изменения значения для JTextField
РЕДАКТИРОВАТЬ 2
Следующий код дает мне бесконечный цикл диалогов, когда я нажимаю стрелку вверх:
STRING: STRING: 10 VALS: 10 STRING: STRING: 10 VALS: 10 STRING: STRING: 10 VALS: 10 .....
Предупреждение, вам нужно будет использовать диспетчер задач, чтобы убить его.
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
Это меняет фон на красный, когда недействительно, НО значения возвращаются к предыдущим (если недействительны), когда поле теряет фокус. Я хочу иметь возможность установить JOptionPane в этот момент, говоря, что значение STILL недействительно, вместо того, чтобы вернуться к предыдущему:
((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);
}
}
}
});
//////////////////////////////////////////////////////////////////////////////////////////////////
ИСХОДНЫЙ ВОПРОС
Но если я использую счетчик, чтобы ввести значение ниже нижней границы. Я получаю "(" в текстовом поле и эту ошибку:
Пользовательские DocumentListeners и formattedTextField плохо сочетаются друг с другом, лучше не смешивать. Вместо этого используйте PropertyChangeListener в текстовом поле, которое прослушивает изменения своего свойства editValid: всякий раз, когда оно изменяется на false, вы можете уведомлять пользователей
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);
}
}
});