2

ComboBox で選択したインデックスに基づいて、タイム ゾーンやその他のものを変更するクラス用の簡単なスイング プログラムを作成しました。メソッド run() が次のようになっている場合、正常に動作します。

public void run() {
        while(true){
            Calendar c = Calendar.getInstance();
            int h = c.get(Calendar.HOUR);
            int m = c.get(Calendar.MINUTE);
            int s = c.get(Calendar.SECOND);
            l.setText(""+h+":"+m+":"+(s<10?"0"+s:s));
            try {
                t.sleep(1000);
            } catch (InterruptedException ex) {}
        }
    }

しかし、それを再定義して時間変更を機能させようとすると、次の行で null ポインター例外が発生します。

p.cb.addItemListener(new ItemListener() {

メソッド run() は次のようになりますが、機能しません。何か案は?

public void run() {
    while(true){

        p.cb.addItemListener(new ItemListener() {

            @Override
            public void itemStateChanged(ItemEvent e) {
                Calendar c = Calendar.getInstance();
                int h = c.get(Calendar.HOUR);
                int m = c.get(Calendar.MINUTE);
                int s = c.get(Calendar.SECOND);
                int index = p.cb.getSelectedIndex();

                if(index == 0){
                    l.setText(""+h+":"+m+":"+(s<10?"0"+s:s));
                }
                else if(index == 1){
                    l.setText(""+(h-6)+":"+m+":"+(s<10?"0"+s:s));
                }
                else if(index == 2){
                    l.setText(""+(h-1)+":"+m+":"+(s<10?"0"+s:s));
                }
                else if(index == 3){
                    l.setText(""+(h-6)+":"+m+":"+(s<10?"0"+s:s));
                }
                else if(index == 4){
                    l.setText(""+(h+8)+":"+m+":"+(s<10?"0"+s:s));
                }
            }

        });

        try {
            t.sleep(1000);
        } catch (InterruptedException ex) {}
    }
}

混乱している方のために説明すると、p は JFrame クラスのインスタンスであり、cb は JFrame クラスの ComboBox への参照です。

4

3 に答える 3

4

またはに値があるため、 ANullPointerExceptionがスローされています。pcbnull

于 2013-03-05T16:02:29.740 に答える
1

あなたのスレッドは今では意味がありません。毎秒コンボボックスに ItemListener を追加していますが、各 ItemListener は同じことをしています。また、スレッドは EDT から GUI 要素を変更しています。EDT に ItemListener を追加する必要があります。

あなたがしようとしているのは、毎秒またはコンボボックスが変更されたときにラベルを更新することだと思います。

これはスレッドなしで行う必要がありますが、Swing Timer と ItemListener の組み合わせを使用してください。

// called on the EDT
void setup() {
     // create gui elements
     p.cb.addItemListener(new ItemListener() {
        updateTimeLabel();
     }
     new Timer(1000, new ActionListener() {
        public void actionPerformed(ActionEvent evt) {
           updateTimeLable()
        }
     });
 }

 private void updateTimeLabel() {
     Calendar c = Calendar.getInstance();
     int h = c.get(Calendar.HOUR);
     int m = c.get(Calendar.MINUTE);
     int s = c.get(Calendar.SECOND);
     int index = p.cb.getSelectedIndex();

     if(index == 0){
        l.setText(""+h+":"+m+":"+(s<10?"0"+s:s));
     }
     else if(index == 1){
         l.setText(""+(h-6)+":"+m+":"+(s<10?"0"+s:s));
     }
     else if(index == 2){
         l.setText(""+(h-1)+":"+m+":"+(s<10?"0"+s:s));
     }
     else if(index == 3){
          l.setText(""+(h-6)+":"+m+":"+(s<10?"0"+s:s));
     }
     else if(index == 4){
          l.setText(""+(h+8)+":"+m+":"+(s<10?"0"+s:s));
     }
 }

null ポインター例外が発生する理由については、まだ初期化されていない別の変数へのアクセス、メモリの可視性の問題、スレッドの競合状態、または EDT からの GUI 要素の変更が原因である可能性があります。スレッドを削除すると、最初の条件以外のすべての条件がなくなります。addItemListener メソッドを呼び出す前に p.cb が初期化されていることを確認するのは簡単です。

また、p、cb、l よりもわかりやすい名前を使用する必要があります。

于 2013-03-05T17:35:11.307 に答える
0

混乱している方のために説明すると、p は JFrame クラスのインスタンスであり、cb は JFrame クラスの ComboBox への参照です。

JFrameのインスタンス? なぜこの方法に従っているのですか?変数を呼び出しComboBoxてリスナーを追加するだけです! pのようですNULL

于 2013-03-05T18:36:16.963 に答える