0

我已经尝试了两天找到解决方案,但仍然不知道该怎么办。

情况如下:我有一个可运行的类,其中 Calendar 类型的变量通过无限循环随时间增加一些(源 1中有一个简化模型)。接下来我有一个 GUI,我在其中开始新线程(源 2)。

当变量“时间”发生变化时,我想进行一些数学运算并更改我的 GUI 上的一些标签。

据我了解,我应该创建 PropertyChangeListener ,这是一个我有问题的地方:我真的不明白该怎么做。我做了以下事情:将我的 TimeLoop 类更新为Source 3。我创建了Source 4上列出的侦听器(也简化了)。问题来了:我应该如何以及在哪里初始化监听器?或者我哪里错了?感谢您的回答。

PS我唯一的想法是(Source 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 实例不同。因此,在 Thread 中运行的实例不会触发任何事件。

于 2013-09-10T22:23:18.727 回答
0

我认为使用观察者模式的MVC非常有用。

于 2013-09-10T22:36:18.207 回答
0

我用观察者模式解决了这个问题。这是代码:

源 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(图形用户界面):

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 回答