0

私は2日間解決策を見つけようとしましたが、まだ何をすべきかわかりません.

状況は次のとおりです。Calendar型の変数が無限ループを介して時間の経過とともにインクリメントする実行可能なクラスがあります(ソース 1に単純化されたモデルがあります)。次に、新しいスレッドを開始する GUI があります ( source 2 )。

変数「時間」が変更されたときに、GUI でいくつかの計算を行い、いくつかのラベルを変更したいと考えています。

私が理解しているように、PropertyChangeListener を作成する必要がありますが、これは私が問題を抱えている場所です。その方法が本当にわかりません。私は次のことを行いました: TimeLoop クラスをSource 3に更新しました。ソース 4にリストされているリスナーを作成しました(これも単純化されています)。そして、ここで質問があります:リスナーをどのように、どこで初期化する必要がありますか? または、どこが間違っていますか?回答ありがとうございます。

PS私が持っていた唯一のアイデアは(ソース5)であり、もちろんうまくいきません。


ソース 1 (実行可能なクラスの例):

public class TimeLoop implements Runnable {

        private Calendar time = Calendar.getInstance();

        @Override
        public void run() {
            try {
                time.set(1997, 11, 27, 00, 00, 00);
                while (true) {

                    time.add(time.HOUR, 1);
                    Thread.sleep(1000);
                }

            } catch (InterruptedException ex) {
                System.out.println("Interrupted error");
            }
        }
    }

ソース 2 (私の GUI クラスからのソース):

public static void main(String args[]) {

        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new GUI().setVisible(true);
            }
        });

        Thread trTime = new Thread(new TimeLoop());
        trTime.setName("TimeLoop");
        trTime.start(); 

    }

ソース 3 (編集されたランナブル クラス):

public class TimeLoop implements Runnable {

    private Calendar time = Calendar.getInstance();
    private PropertyChangeSupport support = new PropertyChangeSupport(this);

    public void updateTime() {
        Calendar oldValue = time;
        time.add(time.HOUR, 1);
        Calendar newValue = time;
        support.firePropertyChange("time", oldValue, newValue);
    }

    public void addListener(PropertyChangeListener listener) {
        support.addPropertyChangeListener(listener);
    }

    @Override
    public void run() {
        try {
            while (true) {
                time.set(1997, 11, 27, 00, 00, 00);
                updateTime();
                Thread.sleep(1000);
            }
        } catch (InterruptedException ex) {
            System.out.println("Interrupted error");
        }
    }
}

ソース 4 (リスナー):

public class TimeListener implements PropertyChangeListener {

            @Override
            public void propertyChange(PropertyChangeEvent pce) {
                System.out.println(pce.getPropertyName() + " has new value);
            }
        }

ソース 5 (間違ったコード):

public static void main(String args[]) {           
        Thread trTime = new Thread(new TimeLoop());
        trTime.setName("TimeLoop");
        trTime.start(); 

        TimeLoop tLoop = new TimeLoop();
        TimeListener tTistener = new TimeListener();
        tLoop.addListener(tTistener);
    }
4

3 に答える 3

0

あなたはほとんどそこにいます。適切な順序に従うだけです。

  1. TimeLoop および TimeListener オブジェクトのインスタンスを作成します。
  2. TimeListener を TimeLoop に追加します。
  3. 独自のスレッドで実行されている TimeLoop を開始します。
TimeLoop tLoop = new TimeLoop();
TimeListener tListener = new TimeListener();
tLoop.addPropertyChangeListener(tListener);
Thread trTime = new Thread(tLoop);
trTime.setName("TimeLoop");
trTime.start();

#5 のコードの問題は、スレッド (new TimeLoop()) で実行しているオブジェクトが、PropertyChangeListener (tLoop) を追加した TimeLoop のインスタンスと同じではないことです。したがって、スレッド内で実行されているインスタンスはイベントを発生しません。

于 2013-09-10T22:23:18.727 に答える
0

Observer Pattern でこの問題を解決しました。コードは次のとおりです。

ソース 1 (実行可能なクラス):

public class TimeLoop extends Observable implements Runnable{

    private Calendar time = Calendar.getInstance();

    @Override
    public void run() {
        try {
            time.set(1997, 11, 27, 00, 00, 00);
                while (true) {
                    time.add(time.HOUR, 1);
                    setChanged();
                    notifyObservers(time);
                    Thread.sleep(1000);
                }
            }
        } catch (InterruptedException ex) {
            System.out.println("Interrupted error");
        }
    }

}

ソース 2 (ハンドラー):

public class Handler implements Observer{

    private Calendar resp;

    @Override
    public void update(Observable o, Object o1) {
        if (o1 instanceof Calendar) {
            resp = (Calendar) o1;
            System.out.println("Received response: " + resp);
        }
    }
}

ソース 3 (GUI):

public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new GUI().setVisible(true);
            }
        });

        final TimeLoop tLoop = new TimeLoop();
        final Handler responseHandler = new Handler();      
        tLoop.addObserver(responseHandler);

        Thread trTime = new Thread(tLoop);
        trTime.setName("TimeLoop");
        trTime.start();

    }
于 2013-09-11T12:48:46.243 に答える
0

オブザーバーパターンを使用するMVCは非常に便利だと思います。

于 2013-09-10T22:36:18.207 に答える