Observer Pattern

chuvak

Erfahrenes Mitglied
Ich bin dabei, das Observer-Pattern zu verstehen.
Dabei habe ich mir 3 Klassen angelegt:

View: Beinhaltet einen JSlider und ein Textfeld, wo dessen momentaner Wert angezeigt werden soll.
Model: Soll auf Veränderungen des JSliders reagieren und den momentanen Wert speichern (Beobachter).
Main: Instanziiert die beiden Klassen.

Leider reagiert mein Beobachter nicht auf Veränderungen. Kann mir bitte jemand helfen?

Main:
Java:
package javaapplication1;

import javax.swing.*;

public class Main extends JFrame {

    private Model m1 = new Model();
    private View v1 = new View(m1);

    public Main() {
        this.setVisible(true);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setSize(500, 400);

        m1.addObserver(v1);
        this.add(v1);
    }

    public static void main(String[] args) {
        Main m = new Main();
    }
}

View:
Java:
package javaapplication1;

import javax.swing.*;
import java.util.*;

public class View extends JPanel implements Observer {

    private JSlider slider = new JSlider(0, 5, 1);
    private JTextField tf1 = new JTextField(10);
    private Model m1;

    public View(Model m1) {
        this.m1 = m1;
        m1.addObserver(this);
        slider.setPaintTicks(true);
        slider.setMinorTickSpacing(1);
        this.add(slider);
        this.add(tf1);
    }

    public void update(Observable obs, Object obj) {
        tf1.setText(m1.getWert() + "");
    }
}

Model:
Java:
package javaapplication1;

import java.util.*;

public class Model extends Observable {

    private int wert;

    public int getWert() {
        return wert;
    }

    public void setWert(int wert) {
        this.wert = wert;
        setChanged();
        notifyObservers("wert");
    }
}
 
Du musst wohl noch irgendwo überhaupt auf eine Änderung deines Sliders reagieren. Das passiert über einen ChangeListener ... also auf deinem Slider einen ChangeListener registrieren, dann bekommst du jedesmal ein Event der Slider bewegt wird und wenn du das Event bekommst, lässt du dir den aktuellen Wert des Sliders ausgeben speicherst den über setWert(..:) in deinem Model und es sollte funktionieren.

Gruß
Der Wolf
 
Geht da nicht der Sinn, des Observer Patterns verloren?
In den ganzen Beispielen dazu stand nichts vom ChangeListener... :confused:
 
Vorweg: Mein Beitrag ist mit Vorsicht zu genießen. Bei der Klausur letzte Woche habe ich die Aufgaben zu Design Patterns erst gar nicht angefangen.

Das was du vor hast macht so denke ich keinen Sinn. Der JSlider selbst implementiert ja bereits ein Observer Pattern und du kannst dich mittels Listener als Observer registrieren. Das selbst zu machen geht nicht (also, die Oberserver zu benachrichtigen), da du keinen Zugriff auf die darunter liegenden, nativen Ereignisse hast. Du kannst zwar, wie Der Wolf bereits gesagt hat, einen Listener dranhängen und dann die Events nach außen weitergeben, aber wozu?
 
Mir gehts hier nur um das Prinzip.
Ich wollte nur, dass das Model irgendein Steuerelement (z.B. JSlider) beobachtet, dessen Werte speichert und bei Bedarf ausgibt.
Deshalb erschien mir das Observer Pattern am sinnvollsten.
 
Vorweg: Mein Beitrag ist mit Vorsicht zu genießen. Bei der Klausur letzte Woche habe ich die Aufgaben zu Design Patterns erst gar nicht angefangen.

Das was du vor hast macht so denke ich keinen Sinn. Der JSlider selbst implementiert ja bereits ein Observer Pattern und du kannst dich mittels Listener als Observer registrieren. Das selbst zu machen geht nicht (also, die Oberserver zu benachrichtigen), da du keinen Zugriff auf die darunter liegenden, nativen Ereignisse hast. Du kannst zwar, wie Der Wolf bereits gesagt hat, einen Listener dranhängen und dann die Events nach außen weitergeben, aber wozu?
Da wir nicht wissen, wie sein Programm aussehen soll, können wir darüber auch nicht urteilen. Aber so unnütz finde ich das nicht, denn das View kann sich jederzeit ändern und dann ist es egal, was da für Komponenten drin sind, eventuell sogar eigene. Dann macht so eine Schnittstelle durchaus Sinn.

b2t:
Öhm... Bei dir sind Observer und Observable vertauscht. Das erkennt man aber schon an den Namen. Observer ist der Beobachter und Observable das zu beobachtende Objekt. Da du dein View vom Model beobachten lassen willst, müsstest du das View zu einem Observable machen und das Model dann zu einem Observer und diesen dann im View registrieren.

An sich ist das, was du gemacht hast, der übliche Fall, nämlich das reagieren auf Änderungen im Model, sprich Datenlage hat sich geändert und darauf muss dann entsprechend reagiert werden, z.B. alle Views aktualisieren, insofern ist dein Programm auch richtig. Du willst das in diesem Fall aber genau umgekehrt machen, daher müsstest du die Observer-Geschichte einfach umdrehn. Wenn du willst, dass bei einem Ereignis, in dem Fall das Bewegen des Sliders, etwas in das Textfeld geschrieben wird, dann müsstest du dieses eben an den Observer übergeben, also dann an das Model.
 
Hallo,

um wieder auf dein Problem zurückzukehren das der Code nicht funktioniert.

Soweit ich das beim durchsehen des Codes erkennen kann, rufst du nirgends den Setter "setWert()" auf, ergo wird auch das setChanged nicht ausgeführt und du erhältst keine Änderung.

Grüße

Phil
 

Neue Beiträge

Zurück