40

jSpinner 値が変更されたときにすぐに更新する方法。

ChangeListener listener = new ChangeListener() {
  public void stateChanged(ChangeEvent e) {
    jLabel.setText(e.getSource());
  }
};

spinner1.addChangeListener(listener);

上記のコードは、ラベル テキストを自動的に変更しません。更新するには、任意の場所をもう一度クリックする必要がありました。

4

6 に答える 6

48

答えは、スピナーのエディターの子である 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 をサブクラス化し、構成を許可するメソッドを公開することです。

于 2011-09-28T17:37:24.387 に答える
9

表示するコードは正しいように見えます。参考までに、実際の例を次に示します。

補遺:JSpinnerにフォーカスがある間、左右の矢印キーでキャレットを移動します。上矢印は増加し、下矢印はカレットを含むフィールドを減少させます。変更は、スピナーとラベルの両方で(事実上)同時に行われます。

のにアクセスするJFormattedTextFieldにはJSpinner.DateEditor、親のgetTextField()メソッドを使用します。次に、適切なカレットリスナーまたはテキスト入力リスナーを使用して、必要に応じてラベルを更新することができます。

補遺:ここでsetCommitsOnValidEdit提案されているように、使用するように更新します。

import java.awt.EventQueue;
import java.awt.GridLayout;
import java.util.Calendar;
import java.util.Date;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JSpinner.DateEditor;
import javax.swing.SpinnerDateModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.text.DefaultFormatter;

/**
 * @see https://stackoverflow.com/questions/2010819
 * @see https://stackoverflow.com/questions/3949518
 */
public class JSpinnerTest extends JPanel {

    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame f = new JFrame("JSpinnerTest");
                f.add(new JSpinnerTest());
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.pack();
                f.setVisible(true);
            }
        });
    }

    public JSpinnerTest() {
        super(new GridLayout(0, 1));
        final JLabel label = new JLabel();
        final JSpinner spinner = new JSpinner();
        Calendar calendar = Calendar.getInstance();
        Date initDate = calendar.getTime();
        calendar.add(Calendar.YEAR, -5);
        Date earliestDate = calendar.getTime();
        calendar.add(Calendar.YEAR, 10);
        Date latestDate = calendar.getTime();
        spinner.setModel(new SpinnerDateModel(
            initDate, earliestDate, latestDate, Calendar.MONTH));
        DateEditor editor = new JSpinner.DateEditor(spinner, "MMM yyyy");
        spinner.setEditor(editor);
        JFormattedTextField jtf = editor.getTextField();
        DefaultFormatter formatter = (DefaultFormatter) jtf.getFormatter();
        formatter.setCommitsOnValidEdit(true);
        spinner.addChangeListener(new ChangeListener() {

            @Override
            public void stateChanged(ChangeEvent e) {
                JSpinner s = (JSpinner) e.getSource();
                label.setText(s.getValue().toString());
            }
        });
        label.setText(initDate.toString());
        this.add(spinner);
        this.add(label);
    }
}
于 2010-10-16T15:34:52.873 に答える
3

JSpinnerここでの問題は、キーボードから入力して手動で値を編集するとstateChanged、フォーカスが失われるJSpinnerまで、または Enter キーが押されるまで、イベントが発生しないことです。

値をアップロードする場合は、入力されたキーごとに aをKeyListener実行する a が必要です。setValueJSpinner

JSpinnerここに aと aの例を残します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
        }
    }
});
于 2011-06-08T09:18:43.980 に答える
-1

私は新しいので、いくつかのルールに違反している可能性があり、遅れる可能性があります。しかし、いくつかの回答が少しわかりにくいので、NetBeans IDE をいじってみたところ、jform に配置された jspinner GUI コンポーネントを右クリックし、events-> change に移動すると、コードが生成されることがわかりました。

于 2016-08-01T14:06:52.113 に答える