Portal > Foren > Java > Allgemeine Java-Programmierung > Logisches Problem beim einsatz von Ereignissen
Antwort
 
Themen-Optionen Thema durchsuchen
Alt 22.05.2006, 11:00 Nach oben    #1
Erfahrener Benutzer
 
Benutzerbild von Prophet
 
Registriert seit: 10.05.2006
Ort: Jevenstedt
Beiträge: 131
Standard Logisches Problem beim einsatz von Ereignissen

Mion,

ich spiele ja im moment noch ein wenig mit Java rum. Nun wollte ich ein kleines Programm erstellen was als reaktion auf ein Ereignis etwas im Fenster verändert.

Nun habe ich aber ein logisches Problem. Wie realsiere ich es, das die ActionListener implementierende Klasse auch problemlos auf die eigenschaften meiner Fensterklasse zugreifen kann um diese zu verändern?

Soll ich ein Member reinschreiben welches eine Reference auf die Hauptklasse bereitstellt? Dann müsste aber wieder die ganzen Gets und Sets definieren was ich ja eigetnlich gar nicht brauche.

Ich habe mir auch schon überlegt das sich das Objekt selbst zuhört aber dann ergibt sich das Problem das ich nur ein einziges Ereignis erstellen kann nicht mehrere.

Alos wie löse ich das Problem am geschicktesten/besten/einfachsten?

Gruß, Prophet
__________________
Prophet ist offline  
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 22.05.2006, 13:47 Nach oben    #2
Ben
Benjamin Klaile
 
Benutzerbild von Ben
 
Registriert seit: 02.12.2004
Ort: Remagen
Beiträge: 4.512
Standard

Sagen wir du klickst in dem Frame auf einen Button. Dann hängst du an diesen den ActionListener und implementierst diesen als anonyme innere Klasse.

Vielleicht mal hier schauen:
http://forum.developers-guide.net/showthread.php?t=3035

Grüße, Ben.

[PS]
Je nachdem, wie sich der Thread entwickelt verschiebe ich den auch noch ins Applets, AWT, Swing und SWT-Forum.
Ben ist offline  
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 22.05.2006, 14:39 Nach oben    #3
Erfahrener Benutzer
 
Benutzerbild von Prophet
 
Registriert seit: 10.05.2006
Ort: Jevenstedt
Beiträge: 131
Standard

Ah, danke das werde ich machen!

EDIT: Wenn ich das Ereignis irgendwann mal ändern (also removen) will geht das doch nur wenn ich die Annonyme Klasse in form eine Variablen speichere oder? Bei direkter übergabe wie in dem von die genannten thread besteht diese möglichkeit nicht mehr oder?

EDIT2: Ich habe gerade oben in dem geposteten Artikel noch etwas gelesen und dort ist die lösung meines Problems über die this-Reference beschrieben.
__________________

Geändert von Prophet (22.05.2006 um 14:51 Uhr)
Prophet ist offline  
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 22.05.2006, 16:45 Nach oben    #4
Erfahrener Benutzer
 
Benutzerbild von karahead
 
Registriert seit: 23.11.2005
Ort: Stadtallendorf
Beiträge: 139
Standard

Ich weiß zwar nicht ob ich dich richtig verstanden habe aber du willst, dass eine Klasse eine andere Klasse informiert, wenn es was neues gibt, nicht oder?

Dafür ist das Observer-Pattern bestens geeignet.
Google mal danach und guck dir in der API die Klassen Observer und Observable an.

---Edit
Swing mit seinen ganzen Listenern ist nach dem Observer/MVC Pattern aufgebaut.

Gruß KaraHead
__________________
Die Menschen wünschen sich Unsterblichkeit, aber wissen nichts anzufangen an einem verregneten Sonntag Nachmittag.
karahead ist offline  
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 22.05.2006, 23:25 Nach oben    #6
Erfahrener Benutzer
 
Benutzerbild von Prophet
 
Registriert seit: 10.05.2006
Ort: Jevenstedt
Beiträge: 131
Standard

Ich muss gestehen das ich das mit den Observern nicht verstehe... Das problem was ich habe bleibt doch das selbe oder? Es ist ja ganz schön wenn die seich fein säuberlich getrennt nachrichten schicken. In dem Model kann ich doch genausowenig die Komponenten der GUI von der Daten Klasse aus kontrollieren. Oder habe ich das Missverstanden?

Diese Moder/Control/View-Model kenne ich bereits aus der Macintosh API die arbeitet in Objective-C nach dem gleichen prinzip. Aber sowohl da als auch hier verstehe ich nicht wie das ganze zusammen funktionieren und interagieren soll...

Könnt ihr mir das noch mal erklären?

Gruß, Prophet
__________________
Prophet ist offline  
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 23.05.2006, 08:33 Nach oben    #7
Projektleiter
 
Registriert seit: 30.11.2005
Ort: Bottrop
Beiträge: 1.129
Standard

Daten ändern sich -> schicken Nachricht an Observer/Listener -> View, dass sich selbst als Listener bei den Daten registriert hat, ändert Anzeige entsprechend.

Warum ändern die Daten sich? Ganz einfach:
View registriert User-Aktion -> leitet Aktion an Controller weiter -> Controller modifiziert Daten.

Heißt also: View ließt Daten, Controller schreibt Daten, Daten benachrichtigen Observer von Änderungen (d.h. in diesem Falle das View).

Um die ursprüngliche Frage zu beantworten:
Zitat:
Soll ich ein Member reinschreiben welches eine Reference auf die Hauptklasse bereitstellt?
Ja. (Außer du arbeitest mit inneren Klassen oder anonymen Klassen.)

Zitat:
Dann müsste aber wieder die ganzen Gets und Sets definieren was ich ja eigetnlich gar nicht brauche.
Wenn du sie definieren musst, dann brauchst du sie. Beim generieren hilft dir die IDE deines Vertrauens.
pago ist offline  
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 24.05.2006, 16:01 Nach oben    #8
Erfahrener Benutzer
 
Benutzerbild von Prophet
 
Registriert seit: 10.05.2006
Ort: Jevenstedt
Beiträge: 131
Standard

Ich habe mich mal mit dem Thema beschäftigt.

Ich habe als anhang eine Grafik begefügt die Zeigt wie ich das MVC Prinzip verstanden habe. Dabei habe ich den Controller weggelassen weil ich mich nach diesem Kapitel des buches "Java ist auch eine Insel" richte. Ist es so richtig? Ich habe versucht mich an das MVP Prinzip zu halten.

swing-mv-pattern.png
__________________
Prophet ist offline  
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 24.05.2006, 17:32 Nach oben    #9
Projektleiter
 
Registriert seit: 30.11.2005
Ort: Bottrop
Beiträge: 1.129
Standard

Und da sag noch einer ich sei nicht künstlerisch begabt...
Angehängte Grafiken
Dateityp: png mv_simple.png (8,6 KB, 7x aufgerufen)
pago ist offline  
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 24.05.2006, 17:51 Nach oben    #10
Erfahrener Benutzer
 
Benutzerbild von Prophet
 
Registriert seit: 10.05.2006
Ort: Jevenstedt
Beiträge: 131
Standard

Also besitzt die GUI eine Instanz der Daten / des Modells und ändert diese Entsprechend. Und die Daten alamieren die EventListener damit diese die GUI verändern?
Aber lauschen die EventListener nicht den GUI Komponenten? Müsste ich diese dann ich beiden Richtungen definieren? Die von Java bereitgestellten damit sich die Daten bei GUI eingaben ändern und die Selbsterstellten damit sich die GUI ändert wenn es die Daten / das Modell will?
Verstehe ich das so richtig?
__________________
Prophet ist offline  
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 24.05.2006, 18:23 Nach oben    #11
Projektleiter
 
Registriert seit: 30.11.2005
Ort: Bottrop
Beiträge: 1.129
Standard

Hab nen Teil deines Posts nicht verstanden, deshalb nochmal in Worten:

Die GUI besitzt eine Instanz des Models und modifiziert diese, richtig. Die EventListener benachrichtigt, wenn das Model sich verändert. Die GUI registriert sich selbst oder einen Helfer als EventListener des Models und wird über Änderungen des Models benachrichtigt, woraufhin sie die angezeigten Daten ändert.

Den GUI-Komponenten lauscht niemand. Du darfst hier nicht das Swing-interne MVC mit deinem eigenen verwechseln. Aus der Programm-Perspektive gehört nämlich z.B. ein TableModel schon zum View!

d.h. hier ist eine Unterscheidung zwischen Swing-MVC und App-MVC zu treffen. Die Swing-Komponenten (inkl. ihrer Model und EventListener) sind View, nicht Model.
pago ist offline  
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 24.05.2006, 18:27 Nach oben    #12
Erfahrener Benutzer
 
Benutzerbild von Prophet
 
Registriert seit: 10.05.2006
Ort: Jevenstedt
Beiträge: 131
Standard

Ok ich glaube ich habe es verstanden... Wenn ich ein fertiges Programm habe poste ich es nochmal hier dann weiß ich wenigstens das ich es richtig habe...

Vielen dank schonmal!
__________________
Prophet ist offline  
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 31.05.2006, 08:48 Nach oben    #13
Erfahrener Benutzer
 
Benutzerbild von Prophet
 
Registriert seit: 10.05.2006
Ort: Jevenstedt
Beiträge: 131
Standard

Also da ich nicht schnalle wie ich das "vereinfachte" MVC Pattern benutzte. Habe ich mich mal an das normale herangewagt. Und ich muss sagen ich finde es verständlicher. Hier ein Beispiel nur um sicherzugehen das ich das alles richtig verstanden habe:
Code:
class TestView
{
  private JButton button;

  public JButton getButton()
  {
    return this.button;
  }
}

class TestModel implements Observable
{
  private boolean buttonPressed;

  public boolean getButtonPressed()
  {
    return this.buttonPressed;
  }

  public void setButtonPressed(boolean btnPressed)
  {
    this.buttonPressed = btnPressed;
  }
}

class TestControl
{
  private TestView mainView;
  private TestModel mainModel;

  public static void main(String[] args)
  {
    mainBla = new TestControl();
  }

  public TestControl
  {
    this.mainView = new TestView();
    this.mainModel = new TestModel();

    this.mainView.getButton().addActionListener(new ActionHandlerButtonPressed());

    this.mainModel.addObserver(new ObserverButtonPressed());
  }

  protected class ActionHandlerButtonPressed implements ActionListener
  {
    public void actionPerformed(ActionEvent actionEvent)
    {
      this.mainModel.setButtonPressed(true);
    }
  }

  protected class ObserverButtonPressed implements Observer
  {
    public void update(Observable o, Objekt arg)
    {
      this.mainView.getButton(); // Tu Was
    }
  }
}
Ich hoffe ich habe das MVC-Pattern dort oben richtig dargestellt.

Mir stellen sich jetzt noch zwei fragen:
1. Was erhalte ich in Observer.update an parametern die mir weiterhelfen?

2. Wenn ich jetzt zum beispiel dinge im datei system mache wohin gehören diese? In das Vie nicht das ist klar. Aber ich weiß nicht ob sowas in Control oder Model gehört.
__________________
Prophet ist offline  
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 31.05.2006, 18:12 Nach oben    #14
Projektleiter
 
Registriert seit: 30.11.2005
Ort: Bottrop
Beiträge: 1.129
Standard

Ähm... was soll das darstellen? *sfz*

Pass auf, nochmal das ganze: Du musst zwischen Komponenten und Programmen unterscheiden. Was du da machst macht vielleicht dann Sinn, wenn du eine Komponente entwickelst, aber mit der Programmlogik hat das nichts zu tun.

Was genau verstehst du an meiner Erklärung nicht (mal abgesehen von "alles")? Und von welchem "vereinfachten MVC-Pattern" sprichst du? Was ich dir hier erklärt habe ist nicht vereinfacht. So funktioniert das - und nicht anders.
pago ist offline  
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 31.05.2006, 18:54 Nach oben    #15
Erfahrener Benutzer
 
Benutzerbild von Prophet
 
Registriert seit: 10.05.2006
Ort: Jevenstedt
Beiträge: 131
Standard

Ich verstehe nicht wie ich das umsetzten soll. Was mich daran noch viel mehr irritiert ist die tatsache das es anderswo (http://de.wikipedia.org/wiki/MVC) anders für mich verständlicher erklärt wird. Aber sich doch deutlich von deinen erkläreungen unterscheidet. Ich habe nun versucht nach dem für mich verständlicherem vorzugehen. Also dem "großen" MCV Pattern welches ja zb oben auch unter wikipedie erklärt wird...
Ich habe nochmal eine Grafik erstellt die mein verständnis dieses Pattern verdeutlichen soll. Und bei dem Quelltext oben wollte ich an einem Praktischen Beispiel testen ob ich es richtig verstanden habe...

mvc-pattern.png

EDIT: Dadurch erreiche ich doch eine klare trennung zwischen Daten, Verarbeitung und Darstellung oder?
__________________

Geändert von Prophet (31.05.2006 um 18:57 Uhr)
Prophet ist offline  
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 31.05.2006, 20:20 Nach oben    #16
Projektleiter
 
Registriert seit: 30.11.2005
Ort: Bottrop
Beiträge: 1.129
Standard

*sfz*
Was du in dem Beispielprogramm oben realisiert hast, hat nichts mit MVC zu tun. Meine Güte...

Noch einmal wiederholen: Du kannst das Komponenten-MVC (z.B. JButton, ButtonModel, ActionListener) nicht auf dein Programm übertragen. Es macht absolut überhaupt gar keinen Sinn, einer View-Komponente eine "getButton"-Methode zu verpassen. Das ist absoluter Schwachfug. Es macht fasst noch weniger Sinn, dass der Controller als Listener beim Model eingetragen ist.

Ich kann's nur nochmal versuchen: Das View registriert sich beim Model und ändert sich, wenn das Model sich ändert. Der Controller wird vom View benachrichtigt, wenn der Benutzer irgendwas im View umstellt, und macht dann, was als Reaktion notwendig ist (Daten speichern, Model ändern, etc.). Dem Controller ist _völlig egal_, ob sich das Model ändert. Das bedeutet für ihn nichts.

Und nochmal: Das hat mit vereinfachtem MVC hier überhaupt nichts zu tun. Und das MVC, was auf Wikipedia erklärt wird, ist auch nicht "größer" oder sonstwas. Du schaffst es nur nicht, dass Prinzip von Komponenten auf Programme umzulegen.

Beispiel:
java Code:
  1. // Controller.java
  2. interface Controller {
  3.     void processUserInput(String input);
  4. }
  5.  
  6. // User.java
  7. import java.beans.*;
  8.  
  9. class User {
  10.     // Attribute
  11.     private String name;
  12.     private int age;
  13.    
  14.     // Utility
  15.     private PropertyChangeSupport support;
  16.    
  17.     public User() {
  18.     }
  19.    
  20.     public User(String name, int age) {
  21.         this.name = name;
  22.         this.age  = age;
  23.     }
  24.    
  25.     public String getName() {
  26.         return name;
  27.     }
  28.    
  29.     public void setName(String name) {
  30.         String old = this.name;
  31.         this.name = name;
  32.         support.firePropertyChange("name", old, name);
  33.     }
  34.    
  35.     // usw.
  36. }
  37.  
  38. // UserInterface.java
  39. interface UserInterface {
  40.     public String readUserName();
  41.     public int readUserAge();
  42. }
  43.  
  44. // ConsoleUserInterface.java
  45. class ConsoleUserInterface implements UserInterface, PropertyChangeListener {
  46.     private User user;
  47.     private Scanner in;
  48.    
  49.     public ConsoleUserInterface(User user) {
  50.         this.user = user;
  51.         in = new Scanner(System.in);
  52.        
  53.         user.addPropertyChangeListener(this);
  54.     }
  55.    
  56.     public void propertyChanged(PropertyChangeEvent e) {
  57.         if("age".equals(e.getPropertyName())) {
  58.             System.out.printf("Age of user changed from %s to %s.%n", e.getOldValue(), e.getNewValue());
  59.         } else if("name".equals(e.getPropertyName())) {
  60.             System.out.printf("Name of user changed from %s to %s.%n", e.getOldValue(), e.getNewValue());
  61.         }
  62.     }
  63.    
  64.     public String readUserName() {
  65.         System.out.println("Please insert user name:");
  66.         return in.nextLine();
  67.     }
  68.    
  69.     public int readUserAge() {
  70.         System.out.println("Please insert user age:");
  71.         return in.nextInt();
  72.     }
  73.    
  74.     public void run() {
  75.         controller = new DefaultController(user, this);
  76.         while(true) {
  77.             System.out.println("What next (setName, setAge, quit)?");
  78.             String cmd = in.nextLine();
  79.             controller.processUserInput(cmd);
  80.         }
  81.     }
  82. }
  83.  
  84. // DefaultController.java
  85. class DefaultController implements Controller {
  86.     private UserInterface ui;
  87.     private User user;
  88.    
  89.     // [Konstruktor]
  90.  
  91.     public void processUserInput(String input) {
  92.         if("setAge".equals(input)) {
  93.             int age = ui.readUserAge();
  94.             if(0 < age && age < 130) {
  95.                 user.setAge(age);
  96.             }
  97.         } else if("setName".equals(input)) {
  98.             String name = ui.readUserName();
  99.             if(name.length() > 0) {
  100.                 user.setName(name);
  101.             }
  102.         } else if("quit".equals(input)) {
  103.             System.out.println("Thanks for using this demo. Going to halt now.");
  104.             System.exit(0);
  105.         }
  106.     }
  107. }
  108.  
  109. // Main.java
  110. public class Main {
  111.     public static void main(String args&#91;&#93;) {
  112.         User user = new User("Dummy User", 19);
  113.         UserInterface ui = new ConsoleUserInterface(user);
  114.         ui.run();
  115.     }
  116. }

Nun klarer?
pago ist offline  
Diesen Beitrag zu to del.icio.us hinzufügen!Diesen Beitrag zu Technorati hinzufügen!Diesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 05.06.2006, 17:44 Nach oben    #17
Erfahrener Benutzer
 
Benutzerbild von Prophet
 
Registriert seit: 10.05.2006
Ort: Jevenst