3

次のようなモデルとしてJSpinnerコンポーネントを作成しました。SpinnerNumberModel

JSpinner spinbox = new JSpinner(new SpinnerNumberModel(2, 1, 7, 1));

変更を検出するためのリスナーを追加しました。

spinbox.addChangeListener(new ChangeListener() {
    @Override
    public void stateChanged(ChangeEvent arg0) {
        synchronized (this) {
            System.out.println("New value: " +
              ((Integer)_spiNumOfAIs.getValue()).intValue());
        }
    }
});

しかし、私が見るのはこれだけです:

新しい値: 0

新しい値: 0

スピンボックスの値を間違って読み取っていませんか?

ブロックについて疑問がある場合synchronized: 私は Swing を初めて使用し、作成したスレッドと同じスレッドでアクション リスナーが実行されるかどうかわからないJDialogため、すべてのアクション リスナーに対してスレッド セーフ対策を講じました安全に。_spiNumOfAIsメンバー変数です。

編集:この小さなコードスニペットからでも、私はそれを見ていなかったことが明らかです...リファクタリング中に、 aJSpinner spinboxと a の両方を使用していることを忘れていJSpinner _spiNumOfAisました。前者は GUI に表示されるスピナーです。

4

1 に答える 1

4

すべての Swing 操作は EDT で実行する必要があり、その結果、UI との対話は常に EDT で行われます。つまりChangeListener、EDT で呼び出されるため、同期する必要はありません。EventQueue.isDispatchThreadを返すリスナーで を使用すると、これを簡単に確認できますtrue。これはSwing 同時実行性レッスンで説明されており、そこから引用します。

すべてのイベント処理コードが実行されるイベント ディスパッチ スレッド。Swing フレームワークとやり取りするほとんどのコードも、このスレッドで実行する必要があります。

間違った値で問題にさらに答えるには、問題を再現できるようにコードを追加する必要があります。たとえば、これはスピナーの非常に基本的な作業例です

import javax.swing.JFrame;
import javax.swing.JSpinner;
import javax.swing.SpinnerModel;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.EventQueue;

public class JSpinnerDemo {

  public static JFrame createFrame(){
    JFrame frame = new JFrame(  );
    frame.add( createSpinner() );
    frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    frame.pack();

    return frame;
  }

  public static JSpinner createSpinner(){
    JSpinner spinner = new JSpinner( new SpinnerNumberModel( 2,1,7,1 ) );
    spinner.addChangeListener( new ChangeListener() {
      @Override
      public void stateChanged( ChangeEvent e ) {
        JSpinner spinner = ( JSpinner ) e.getSource();
        SpinnerModel spinnerModel = spinner.getModel();
        System.out.println(spinnerModel.getValue());
      }
    } );
    return spinner;
  }
  public static void main( String[] args ) {
    EventQueue.invokeLater( new Runnable() {
      @Override
      public void run() {
        createFrame().setVisible( true );
      }
    } );
  }
}

これを自由に変更して、問題を説明してください。javadocで説明されているように、エディターとモデル値が同期しなくなる可能性があるため、JSpinnerクラスの javadocを確認することもお勧めします。別の良い出発点は、スピナーに関する Swing チュートリアルです。

于 2012-04-28T09:21:07.633 に答える