观察者模式从 JPanel 中的计时器打印值

Observer pattern to print value from timer in JPanel

我创建了一系列 类 来尝试找出观察者模式,但遇到了一些麻烦。 observer/observed关系中的两个类分别是ClockPanel,TheTimer。 TheTimer 是一个(摆动)计时器,它以秒为单位跟踪时间。 ClockPanel 是一个 GUI(swing),它有一个启动计时器的按钮和一个我想显示时间的 JLabel。

我的观察者模式的目标:获取在 TheTimer 中创建的值并将其打印在我的 GUI 上。

目前的问题:计时器正在更新时间,但我似乎不明白如何在我的 GUI 中更新值。

我在 C# 讨论中发现了一个与此类似的问题,但这个问题更加微妙,而且超出了我的理解范围。

以下是构成程序的五个 类: 1. GUI-ClockPanel

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class ClockPanel implements Observer {
JFrame frame;
JPanel panel;
JButton sbutton;
JLabel label;

@Override
public void update(int counter) {
    String clockval = String.valueOf(counter);
    label.setText(clockval);
}

public ClockPanel() {
    frame = new JFrame();
    frame.setSize(100, 100);
    panel = new JPanel();
    label = new JLabel();

    TheTimer myTimer = new TheTimer();

    sbutton = new JButton("start");
    sbutton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            myTimer.StartTimer();
        }
    });

    frame.setLayout(new FlowLayout());
    frame.add(panel);
    frame.add(sbutton);
    frame.add(label);
    frame.setVisible(true);

}
}

2。摇摆计时器-TheTimer

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.JPanel;
import javax.swing.Timer;

public class TheTimer extends JPanel implements Subject {

private ActionListener action;
private Timer Time;
private int delay = 1000;
private ArrayList<Observer> observers = new ArrayList<Observer>();
private int counter = 0;

public TheTimer() {

    action = new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            System.out.println(counter);
            counter++;
            setCounter(counter);
        }
    };
}

public void StartTimer() {
    Time = new Timer(delay, action);
    Time.setInitialDelay(0);
    Time.start();
}

public int getCounter() {
    return counter;
}

public void setCounter(int counter) {
    this.counter = counter;
    notifyObservers();
}

@Override
public void registerObserver(Observer observer) {
    observers.add(observer);
}

@Override
public void removeObserver(Observer observer) {
    observers.remove(observer);
}

@Override
public void notifyObservers() {
    for (Observer ob : observers) {
        System.out.println("Notifying ClockPanel on change in counter value");
        ob.update(this.counter);
    }
}
}

3。观察者-观察者

public interface Observer {
public void update(int counter);
}

4。 Observer相关方法-Subject

public interface Subject {
public void registerObserver(Observer observer);

public void removeObserver(Observer observer);

public void notifyObservers();
}

5。 Main-TestMain

import javax.swing.SwingUtilities;

public class TestMain {

public static void main(String args[]) {

    ClockPanel panel = new ClockPanel();
    TheTimer timer = new TheTimer();
    timer.registerObserver(panel);

    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            new ClockPanel();
        }
    });
}
}

您有两个 TheTimer 对象:一个在 ClockPanel 中,另一个在 TestMain#main() 中。

您需要从(比如)main() 中删除计时器并添加:

myTimer.registerObserver(this);

你的 ClockPanel 构造函数。