JSpinner値が変更されたときにすぐに更新する方法。
ChangeListener listener = new ChangeListener() {
public void stateChanged(ChangeEvent e) {
jLabel.setText(e.getSource());
}
};
spinner1.addChangeListener(listener);
上記のコードはラベルテキストを自動的に変更しません。更新するにはどこでももう一度クリックする必要があります。
答えは、スピナーのエディターの子であるJFormattedTextFieldで使用されるフォーマッターを構成することです。
formatter.setCommitsOnValidEdit(true);
残念なことに、それを手に入れることは、序文と同じくらい長くて汚いです:
final JSpinner spinner = new JSpinner();
JComponent comp = spinner.getEditor();
JFormattedTextField field = (JFormattedTextField) comp.getComponent(0);
DefaultFormatter formatter = (DefaultFormatter) field.getFormatter();
formatter.setCommitsOnValidEdit(true);
spinner.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
LOG.info("value changed: " + spinner.getValue());
}
});
少し(ただし、それほどではない)よりクリーンな方法は、NumberEditorをサブクラス化し、構成を許可するメソッドを公開することです。
ここでの問題は、キーボードから入力してJSpinner
値を手動で編集すると、stateChanged
によってフォーカスが失われるか、Enterキーが押されるまでJSpinner
イベントが発生しないことです。押されました。
値をアップロードする場合は、入力されたキーごとにKeyListener
でsetValue
を実行するJSpinner
が必要です。
JSpinner
とSpinnerNumberModel
の例をここに残します:
JSpinner spinner= new JSpinner();
spinner.setModel(new SpinnerNumberModel(0, 0, Integer.MAX_VALUE, 1));
spinner.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
jLabel.setText(spinner.getValue());
}
});
final JTextField jtf = ((JSpinner.DefaultEditor) spinner.getEditor()).getTextField();
jtf.addKeyListener(new KeyAdapter() {
@Override
public void keyReleased(KeyEvent e) {
String text = jtf.getText().replace(",", "");
int oldCaretPos = jtf.getCaretPosition();
try {
Integer newValue = Integer.valueOf(text);
spinner.setValue(newValue);
jtf.setCaretPosition(oldCaretPos);
} catch(NumberFormatException ex) {
//Not a number in text field -> do nothing
}
}
});
それは遅い答えかもしれませんが、あなたは私のアプローチを使うかもしれません。
As spuas上記のように、問題はstateChanged
イベントがフォーカスが失われたとき、またはEnterキーが押されたときにのみ発生することです。
KeyListenersを使用することもお勧めできません。
代わりにDocumentListener
を使用することをお勧めします。私はspuasの例を少し修正し、それが私が得たものです:
JSpinner spinner= new JSpinner();
spinner.setModel(new SpinnerNumberModel(0, 0, Integer.MAX_VALUE, 1));
final JTextField jtf = ((JSpinner.DefaultEditor) spinner.getEditor()).getTextField();
jtf.getDocument().addDocumentListener(new DocumentListener() {
private volatile int value = 0;
@Override
public void removeUpdate(DocumentEvent e) {
showChangedValue(e);
}
@Override
public void insertUpdate(DocumentEvent e) {
showChangedValue(e);
}
@Override
public void changedUpdate(DocumentEvent e) {
showChangedValue(e);
}
private void showChangedValue(DocumentEvent e){
try {
String text = e.getDocument().getText(0, e.getDocument().getLength());
if (text==null || text.isEmpty()) return;
int val = Integer.parseInt(text).getValue();
if (value!=val){
System.out.println(String.format("changed value: %d",val));
value = val;
}
} catch (BadLocationException | NumberFormatException e1) {
//handle if you want
}
}
});
最後の答えは、少し柔軟に変更できるように、少し並べ替えることができます。 JSpinnerの代わりに、この新しいMyJSpinnerを使用するだけです。最大の変更点は、JSpinnerの基礎となるモデル(int、double、byteなど)でこの新しいバージョンを使用できることです。
public class MyJSpinner extends JSpinner{
boolean setvalueinprogress=false;
public MyJSpinner()
{
super();
final JTextField jtf = ((JSpinner.DefaultEditor) getEditor()).getTextField();
jtf.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void removeUpdate(DocumentEvent e) {
showChangedValue(e);
}
@Override
public void insertUpdate(DocumentEvent e) {
showChangedValue(e);
}
@Override
public void changedUpdate(DocumentEvent e) {
showChangedValue(e);
}
private void showChangedValue(DocumentEvent e){
try {
if (!setvalueinprogress)
MyJSpinner.this.commitEdit();
} catch (NumberFormatException | ParseException ex) {
//handle if you want
Exceptions.printStackTrace(ex);
}
}
});
}
@Override
public void setValue(Object value) {
setvalueinprogress=true;
super.setValue(value);
setvalueinprogress=false;
}
}
私は新しいので、いくつかの規則に違反している可能性があり、遅れる可能性があります。しかし、いくつかの答えが少しわかりにくいので、NetBeansで遊んでみましたIDEコードが生成されます。