ich versuche das MVC und das Observer/Observable Pattern zu verstehen und habe deshalb eine simple Demoapplikation geschrieben:
Model:
Code:
public class Model extends Observable{
private int geschwindigkeit;
public void setGeschwindigkeit(int geschw){
geschwindigkeit = geschw;
setChanged();
notifyObservers(geschwindigkeit);
}
}
View:
Code:
public class View extends JFrame implements Observer{
JTextField text;
public View(){
text = new JTextField();
add(text);
pack();
setSize(200,50);
setVisible(true);
}
public void update(Observable o, Object argv){
text.setText(String.valueOf(argv));
}
}
Controller:
Code:
public class Controller {
Model model;
public Controller( Model model){
this.model = model;
new Timer().schedule( new MyTimerTask(model), 0, 1000 ); // setze geschw. jede sek.
}
class MyTimerTask extends TimerTask{
Model m;
public MyTimerTask(Model model){
this.m = model;
}
public void run(){
int random = (int)(Math.random() * 160) + 20;
model.setGeschwindigkeit(random);
}
}
}
Hauptklasse:
Code:
public class Main {
public static void main(String[] args) {
View view = new View();
Model model = new Model();
Controller controller = new Controller(model);
model.addObserver(view); // view beobachtet model
}
}
Ist das so in Ordnung ? Was würdet ihr verbessern?
public class GeschwindigkeitChangeEvent extends EventObject{
private int geschwindigkeit;
public GeschwindigkeitChangeEvent(Object source, int geschwindigkeit){
super(source);
this.geschwindigkeit = geschwindigkeit;
}
public int getGeschwindigkeit(){
return geschwindigkeit;
}
}
GeschwindigkeitListener:
Code:
public interface GeschwindigkeitListener extends EventListener{
void geschwindigkeitChanged(GeschwindigkeitChangeEvent e);
}
View:
Code:
public class View extends JFrame implements GeschwindigkeitListener{
JTextField text;
public View(){
text = new JTextField();
add(text);
pack();
setSize(200,50);
setVisible(true);
}
public void geschwindigkeitChanged(GeschwindigkeitChangeEvent e){
text.setText(String.valueOf(e.getGeschwindigkeit()));
}
}
Model:
Code:
public class Model {
private int geschwindigkeit;
private EventListenerList listeners = new EventListenerList();
public void setGeschwindigkeit(int geschw){
this.geschwindigkeit = geschw;
notifyGeschwindigkeitChange(new GeschwindigkeitChangeEvent(this,geschwindigkeit));
}
public void addGeschwindigkeitListener( GeschwindigkeitListener listener ) {
listeners.add( GeschwindigkeitListener.class, listener );
}
public void removeGeschwindigkeitListener( GeschwindigkeitListener listener ){
listeners.remove( GeschwindigkeitListener.class, listener );
}
protected synchronized void notifyGeschwindigkeitChange( GeschwindigkeitChangeEvent event ) {
for ( GeschwindigkeitListener l : listeners.getListeners( GeschwindigkeitListener.class )){
l.geschwindigkeitChanged( event );
}
}
}
Controller:
Code:
public class Controller {
Model model;
public Controller( Model model){
this.model = model;
new Timer().schedule( new MyTimerTask(model), 0, 1000 ); // setze geschw. jede sek.
}
class MyTimerTask extends TimerTask{
Model m;
public MyTimerTask(Model model){
this.m = model;
}
public void run(){
int random = (int)(Math.random() * 160) + 20;
model.setGeschwindigkeit(random);
}
}
}
Main:
Code:
public class Main {
public static void main(String[] args) {
View view = new View();
Model model = new Model();
Controller controller = new Controller(model);
model.addGeschwindigkeitListener(view);
}
}
Ist das so auch richtig? Finde es halt etwas komisch, auf das Model einen Listener zu setzen, denn normalerweise wird in Swing der Listener ja auf GUI Komponenten wie JButton gesetzt um Eingaben des Anwenders zu erkennen.
Bei den komplexeren Swing-Komponenten gibt es in der Regel auch zwei Listener; eines bei der Komponenten für die Gui-Events und eines für die Daten (Model)-Events. Etwa bei der JList: Mit addListSelectionListener(ListSelectionListener listener) bekommt man Selektionen mit, die aber nix mit dem Model zu tun haben. Das ListModel, also die JList-Daten, können auch Ereignisse senden: addListDataListener(ListDataListener l); damit meldet der Listener, ob Elemente in die Liste kommen oder verschwinden. Die JList ist ein wichtiger Horcher am ListModel.