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

时间:2016-03-11 19:16:38

标签: java swing observer-pattern observers

我已经创建了一系列类来尝试找出Observer模式并且遇到了一些麻烦。 观察者/观察者关系中的两个类是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。 Swing Timer-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。观察者相关的方法 - 主题

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();
        }
    });
}
}

1 个答案:

答案 0 :(得分:1)

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

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

myTimer.registerObserver(this);

到您的ClockPanel构造函数。