Wie teste ich ob sich der wert einer variable ändert (listener)?

1 Antwort

1) Wieso ist das Feld statisch? Um von überall einfachen Zugriff darauf zu haben? Wenn ja, ist das ein Antipattern, welches konkret gegen das Konzept der OOP läuft und Fehler sowie Inflexibilitäten begünstigt.

Jedes Feld, welches den Zustand eines Objektes definiert, sollte objektgebunden sein. Seinen Wert kann man teilen, indem man es über Parameter/Rückgabewerte transportiert.

2) An Color-Objekte selbst kann kein Listener gehängt werden. Du kannst aber eine Klasse erstellen, deren Instanzen bezüglich Zustandsänderungen beobachtbar sind.

Die Zustandsänderungen selbst werden über Setter vorgenommen. Diese triggern wiederum ein Event, auf welches dem Objekt angehängte Listener reagieren können. In diesem Zug kommt das PropertyChangeListener-Interface ins Spiel. Eine einfache Beispiel-Implementation kannst du dir hier anschauen.

CloudBeta 
Fragesteller
 08.02.2022, 15:15

Also erstmal danke für deine große hilfe öfers aber ich hab das gefühl ich verstehe vieles noch garnicht :( ich habe es jetzt nicht mehr statisch aber trotzdem weis ich nicht wie ich den code von der website anwenden soll :/ Und um eine funktion aufzurufen aus einer anderen klasse muss ich ja entweder new Klassenname.update(); machen oder irgendetwas statisch machen oder?

0
CloudBeta 
Fragesteller
 08.02.2022, 15:18
@CloudBeta

Uund wenn ich das mit dem new mache schmiert es ab weil das irgendwie schon halt in einer anderen klasse aufgerufen wird also in der klasse vom anfangsfenster

0
regex9  08.02.2022, 18:02
@CloudBeta
(...) aber ich hab das gefühl ich verstehe vieles noch garnicht (...)

OOP-Grundkenntnisse sind für GUI-Programmierung Voraussetzung. Möglicherweise hast du da noch Lücken.

(...) trotzdem weis ich nicht wie ich den code von der website anwenden soll (...)

Die Idee dahinter ist Folgende: Es gibt ein Objekt, dessen Zustand beobachtet werden soll (= das Observable; im Beispiel ist es die Agency, wobei das PropertyChangeSupport-Objekt die Verwaltung aller Beobachter übernimmt). Diesem werden ein oder mehrere Beobachter (= Observer) angehängt (im Beispiel der Channel). Bei einer Zustandsänderung wird vom Observable die firePropertyChange-Methode aufgerufen und wesentliche Informationen über die Änderung mitgeliefert (Was hat sich geändert? Was ist der neue Wert?). Im Hintergrund läuft die PropertyChangeSupport-Klasse alle registrierten Beobachter ab und ruft dessen propertyChange-Methode auf.

Ein anderes einfaches Beispiel dazu:

import java.awt.*;
import java.beans.*;
import javax.swing.*;

public class Main {
  public static void main(String[] args) {
    SwingUtilities.invokeLater(() -> {
      var model = new Model();
      var window1 = new Window1(model);
      var window2 = new Window2(model);
    });
  }
}

class Model {
  private Color color;
  
  private PropertyChangeSupport support;

  public Model() {
    support = new PropertyChangeSupport(this);
  }

  public void addPropertyChangeListener(PropertyChangeListener listener) {
    support.addPropertyChangeListener(listener);
  }

  public void setColor(Color color) {
    if (this.color != color) {
      support.firePropertyChange("color", this.color, color);
      this.color = color;
    }
  }
}

class Window1 {
  public Window1(Model model) {
    var frame = new JFrame("Window 1");
    var button = new JButton("Change color");
    button.addActionListener(event -> {
      model.setColor(Color.RED);
    });
    frame.add(button);
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    frame.pack();
    frame.setVisible(true);
  }
}

class Window2 implements PropertyChangeListener {
  private JButton button;

  public Window2(Model model) {
    model.addPropertyChangeListener(Window2.this);

    var frame = new JFrame("Window 2");
    button = new JButton("Some button");
    frame.add(button);
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    frame.pack();
    frame.setVisible(true);
  }

  @Override
  public void propertyChange(PropertyChangeEvent evt) {
    button.setBackground((Color) evt.getNewValue());
  }
}

Der Button des ersten Fensters sorgt bei Klick dafür, dass sich die Farbe des Buttons vom zweiten Fenster ändert.

Und um eine funktion aufzurufen (...)

Wenn es sich um eine statische Methode handelt, benötigst du nur den Klassennamen und die Methode muss (und das gilt ebenso für objektgebundene Methoden) für den aufrufenden Kontext sichtbar sein.

SomeClass.someMethod();

Eine statische Methode macht aber nur Sinn, wenn sie den Zustand der einzelnen Objekte dieser Klasse nicht verändert. Eine Methode drive von einer Klasse Car wäre beispielsweise nie statisch, denn sie ändert ja in logischer Hinsicht den Zustand eines einzelnen Car-Objekts (nämlich dessen Position).

Wenn du eine objektgebundene Methode aufrufen möchtest, benötigst du eine Referenz, die auf das Objekt zeigt.

Car car = new Car();
car.drive();

Das Schlüsselwort this bezieht sich innerhalb dieser Methode dann auf dieses eine Objekt. Hier:

public void drive() {
  this.x += 50;
}

würde also die Position des Autos verändert werden, auf das die Variable car zeigt.

Uund wenn ich (...)

Um diesen Kommentar zu verstehen, fehlen mir Informationen / der Kontext.

0