Swing MVC in Projekt umsetzen

Denny1989

Aktives Mitglied
Hallo Community.
Ich habe nun mehrere Wochen lang gesucht gelesen, gesucht, gelesen, und ich raff es irgendwie nciht. Ich weiß absolut nicht wie ich beginnen soll. Hier mal ne Beschreibung für mein Problem.

Ich habe eine View produziert die Daten anzeigen soll die aus einer SQL Datenbank gelesen werden müssen.
Es gibt 3 JLists die einmal ne Lagerhistorie, einmal ne Rechnungshistorie und einmal RSS news aus nem feed anzeigen sollen. Weiterhin gibt es einen Panel mit nem JFreechart der ebenfalls ein Model braucht und nen Jtree der auch nen Model benötigt. Ich würde in der GUI gern über änderungen benachrichtigt werden. (Observer) Die meisten beispiele zu MVC gehen davon aus das eine Modell klasse existiert und da ein paar INteger werte geändert werden und per observer mitgeteilt werden... das ist nicht sehr hilfreich leider. Weiterhin frage ich mich ob ich die kompette GUI update wenn sich ein wert in einem Model geändert hat oder ob ich die Observer irgendwie aufteile!?

Ich müsste doch nun mehrere Models nachahlten die die Daten der komponente enthalten richtig? Schmeiße ich die alle in eine Modelklasse??
Mein (e) Models müssten Observable sein und meine View Observer ....

Leider habe ich keine Idee wie ich beginnen könte / mein Programm plane... Es soll ein Teil eines Warenwirtschaftssystems für ein uni projekt werden.

Ich würde mich freuen wenn mir irgendjemand ein Paar tips zum start geben könnte wie ich die Klassen aufteile... sollte es mehrere Models geben!? wenn ja wie verwalte ich die ?
Vor allem interessiert mich halt wie ich in diesem etwas komplexeren Beispiel meinen Code organisiere.
 

ARadauer

Top Contributor
Generell würd ich das fachlich strukturieren...
Ich habe eine View produziert die Daten anzeigen soll die aus einer SQL Datenbank gelesen werden müssen.
Was sind das für Daten? Eine Liste mit Artikeln?

Es gibt 3 JLists die einmal ne Lagerhistorie...
für diese 3 Views würde ich auf jeden Fall 3 Modell machen

Die meisten beispiele zu MVC gehen davon aus das eine Modell klasse existiert und da ein paar INteger werte geändert werden und per observer mitgeteilt werden... das ist nicht sehr hilfreich leider
Wieso nicht... mach dir einfach ein LagerModel das eine Liste mit Artikeln hält und bei Änderungen informierst du die Observer... ist das eine View kann sie sich aktualisieren...

Weiterhin frage ich mich ob ich die kompette GUI update wenn sich ein wert in einem Model geändert hat oder ob ich die Observer irgendwie aufteile!?
kommt drauf an... bei einem jtable model kannst du genau sagen welche zeile sich gändert hat...
aber generell mach ich das schon, dass ich alle felder neu setze...
stellt das modell die daten für ein Formular mit 20 Feldern dar, ist es kein Problem wenn sich diese 20 Felder die Werte neu setzen auch wenn sich nur einer geändert hat...


Ich müsste doch nun mehrere Models nachahlten die die Daten der komponente enthalten richtig? Schmeiße ich die alle in eine Modelklasse??
dei frage ist was du unter komponente verstehst... also eine view mit 20 Feldern des Artikels?? Ja klar ein Model.



Ich würde mich freuen wenn mir irgendjemand ein Paar tips zum start geben könnte wie ich die Klassen aufteile... sollte es mehrere Models geben!? wenn ja wie verwalte ich die ?
mhn Artikel?
Artikel (Fachobjekt), ArtikelPanel (View), ArtikelModel (Model), ArtikelController (Controller), ArtikelDAO (Datenzugriff)....
 

Marco13

Top Contributor
Da kann man sehr (sehr sehr) weit ausholen. Bei dem, was du beschrieben hast, ist nicht klar, mit welchen Daten der JFreeChart und der JTree gefüttert werden sollen.

Vermutlich könnte man das ganze mit EMF&Co mit ein paar klicks "hinmalen" und dann compilieren. Aber man kann davon ausgehen, dass es (mindestens) einmal "per Hand" gemacht werden soll(te).

Der pragmatisch-oberflächliche Ansatz auf Basis dessen, was du beschrieben hast, könnte GROB und sinngemäß so aussehen, dass es sowohl für Lagerhistorie als auch Rechnungshistorie ein Modell gibt (als Interface beschrieben). Zusätzlich jeweils ein RechnungListener- bzw. LagerListener-Interface. Instanzen dieser Listener können zum Lager- bzw. Rechnungsmodell hinzugefügt werden. Wenn sich am Modell etwas ändert, werden die Listener entsprechend benachrichtigt. Falls notwendig oder sinnvoll kann es auch noch LagerEvents und RechnungsEvents geben.

Zwei Punkte sind in bezug auf deine Frage wichtig:

Erstens sollten nicht nur die java.util.Observable/Observer-Klassen verwendet werden. Die sind in den aller(!)wenigsten Fällen wirklich praktisch einsetzbar. Meistens sind eigene, spezielle Modell- und Listener-Interfaces besser. Vermutlich beziehst du dich auf diese Mini-Beispiele, wo das Modell aus einem Integer besteht, und alles mit Observer/Observable gelöst ist. Damit wird die IMHO eigentlich schwierigste Aufgabe beim MVC umgangen: Sich klarzumachen, WAS in das Modell soll, und WER WANN und WIE über die Änderungen benachrichtigt wird.

Zweitens (und das ist vielleicht etwas subjektiv - es gibt Leute, die das anders sehen) : Die Swing-Modellklassen (wie TreeModel oder das JFreeChart-Modell) sollten NICHT Teil des eigenen Modells sein. Damit legt man sich u.U. auf eine konkrete Implementierung der View fest.

Die Frage, ob "das komplette GUI" bei einer Änderung aktualisiert wird, hängt auch mit dem ersten Punkt zusammen: Wenn es nur "Observable" gibt, bleibt einem kaum etwas anderes übrig. Wenn man aber eigene Modell- und Listener-Interfaces erstellt, kann man sich die "Granularität" der Benachrichtigungen aussuchen. Es KÖNNTE dann bei dir z.B. sowas geben wie
Java:
interface RechnungListener
{
    void irgendwasHatSichGeändert();
}

interface RechnungsModell 
{
    void add/remove(RechnungsListener l);

    // Diese Änderungen bewirken ALLE, dass auf allen 
    // RechnungsListenern "irgendwasHatSichGeändert"
    // aufgerufen wird
    void setzeName(String name);
    void setzeBetrag(int betrag);
    void setzeDatum(Date datum);
...
}
Das wäre von der Granularität her genauso wie mit Observer/Observable: Sobald die View (die ein RechnungsListener ist) die Nachricht bekommt "irgendwasHatSichGeändert", muss ALLES aktualisiert werden.

Alternativ dazu kannst du aber auch sowas machen wie
Java:
interface RechnungListener
{
    void nameHatSichGeändert(RechnungsEvent e);
    void betragHatSichGeändert(RechnungsEvent e);
    void datumHatSichGeändert(RechnungsEvent e);
}

class RechnungsEvent
{
    enum Type { NAMENSÄNDERUNG, DATUMSÄNDERUNG ... }

    String alterName;
    String neuerName;
   ...
}


interface RechnungsModell 
{
    void add/remove(RechnungsListener l);

    // Diese Änderungen bewirken, dass GANZ spezifische
    // RechnungsEvents an die passenden Methoden aus
    // dem RechnungsListener weitergereicht werden.
    void setzeName(String name);
    void setzeBetrag(int betrag);
    void setzeDatum(Date datum);
...
}
Damit hättest du z.B. die Möglichkeit, in der View in der Methode "nameHatSichGeändert" zum Beispiel NUR ein TextField mit dem neuen Namen zu füllen, und der Rest der View bleibt wie sie ist.

Nochmal: Die Frage, WER WIE WANN benachrichtigt werden soll, ist zusammen mit der Definition des eigentlichen Modell-Interfaces u.U. das schwierigste.

Es gibt auch einen Thread mit Tutorials zum MVC: http://www.java-forum.org/allgemeines/91829-mvc.html#post595758

EDIT: Nachtrag in bezug auf ARadauer's post:
stellt das modell die daten für ein Formular mit 20 Feldern dar, ist es kein Problem wenn sich diese 20 Felder die Werte neu setzen auch wenn sich nur einer geändert hat...
Das ist bei den meisten Anwendugnen tatsächlich so, insbesondere wenn es nicht zeitkritisch ist. Aber je nachdem, wo solche Dinge wie ein JFreeChart-Modell dort reinkommen, und wie aufwändig es ggf. ist, dieses Modell zu aktualisieren (am besten mit einer im EDT ausgeführten SQL-Anfrage :autsch: ;) ... aber im Ernst: speziell wenn alternativ dazu vielleicht nur der Text in einem TextField geändert werden müßte), sollte man sich überlegen, ob man die Benachrichtigungen nicht vielleicht spezifischer macht, um unnötige Aufwände und Verzögerungen zu vermeiden.
 
Zuletzt bearbeitet:

Denny1989

Aktives Mitglied
Danke schonmal für die Antwort. hier mal meine View damit du ne vorstellung davon bekomst.
viewoz.png



auf der rechten seite das sind halt JLists. Die JLists müssten eben die Listen von Datenobjekten halten die ne spezielle ToString methode haben sollten. (Lagerhistorie besteht zb. aus Datum, Mengenänderungen und so).

Würde man für die jeweiligen KOmponenten jeweils ne eigene View mit COntroller machen?

Komponentne sind für mich Jlist, Jtree, DiagramPanel vom Jfreechart...

meine blockade besteht vor alem darin wie ich in meinem controller in dem ich meine (eine) view erstelle die mehreren Modells organisiere, oder fasse ich die ganzen ListModels vorher in einem MainWIndowModel klasse zusammen und lasse nur die das Observer implementieren?

Vor allem fehlt mir der anhaltspunkt wenn ich es so mache wie marco beschrieben hat wie ich dann wenn mein controller instanziiert wird vorgehen. ertelle ich von jedem Modell eine instanz und übergebe meine DBverbindung und lasse das modell sich selbst füllen? danach mache ich in entwa sowas hier. view.getJList.setModel(myRechnungsModel) und wiederhole das für alle meine Modells?
Dann gibt es für jedes MOdell einen Listener den jeweils die View implementieren muss um dann die List upzudaten? Oder merkt der auch automatisch dashinzufügen eines elements zum model, dass ich ihm ja übergeben habe?

Kommt das adden der ActionListener in die View klasse oder macht das der Controller a la view.getJButton.addActionListener(exitButtonListener) ?

Leider fehlt mir irgendwie der anhaltspunkt. das MVVM pattern in .Net habe ich nach ner Woche implementieren können, kann das so viel leichter gewesen sein ? :-D
 
Zuletzt bearbeitet:

Marco13

Top Contributor
Kleiner Einschub dazu
Die JLists müssten eben die Listen von Datenobjekten halten die ne spezielle ToString methode haben sollten. (Lagerhistorie besteht zb. aus Datum, Mengenänderungen und so).
Nicht notwendigerweise. Wenn es sowas gibt wie
Code:
interface LagerhistorienEintrag { getDatum(), getMengenänderung() ... }
dann mann man (unabhäng von der Implementierung der ToString-Methode) einen eigenen ListCellRenderer bauen, der die Einträge (d.h. Strings) passend auf basis der gewünschten Informationen zusammenbaut.
 
G

Gast2

Gast
1. Würde ich kein MVC mehr verwenden sondern MVp
Model View Presenter ? Wikipedia
2. Würde ich für das Eventhandling anonyme Listener verwenden welche deine Controller darstellen.

Deine domain models solltest vor der erstellung deiner gui modellieren...
 

Denny1989

Aktives Mitglied
was ist hier mit domain models gemeint?
Ja das MVP gefiel mir vom ansatz auch irgendwie besser jedoch dachte ich es wäre noch schwieriger und ich fange erstmal mit MVC an?
Wie gesagt ich habe viel gelesen dazu aber noch nix wirklich interessantes.. vor allem wenns darum ging ne komplexe gui zu erstellen.

PS ich habe in meinem vorigen eintrag gerade noch was hinzugefügt. Dachte ncih dass so schnell noch jemand schreibt.

PPS:
mein Model müsste sich an folgendem Datenbankschema orientieren

Artikel: ArtNr, Name, Beschreibung, BruttoPreis, HerstNr, Kategorie, Einkaufspreis
Hersteller: HerstNr, Name, Ort, PLZ, Strasse
Lager: ArtNr, Menge, Lagerplatz, Mindestbestand, Meldebestand, Höchstbestand
Lagerhistorie: ArtNr, Menge, Datum, Bemerkung
Rechnung: RechnungsNr, ArtNr, Kaufmenge, Gesamtpreis


in den JLists von Rechnung und lagerhistorie sind jeweils nur die Strings die in dem Screenshot zu sehen sind anzuzeigen, aber es wäre natürlich sinnvoll dennoch die einmal geholten daten nachzuhalten falls man irgendwann man die daten verändern möche (was auch geplant ist).
 
Zuletzt bearbeitet:

Denny1989

Aktives Mitglied
Leider hilft mir das immernoch nciht so recht.

Kann mir vllt jemand eine kurze klassen struktur geben wenn angenommen in der View nur 2 Jlists mit VERSCHIEDENEN model klassen wären, die per observer ihre Änderungen mitteilen sollen. also wie sieht dann die view aus? hält sie sich das model irgendwo? erstellt der controller die view und die MOdels? sollte ich eine Klasse MainModel machen die beide Models kapselt?

und vor allem wie geh ich bei der initialisierung vor?
 

Denny1989

Aktives Mitglied
es hat aber ebenfalls wieder nur EIN Model. UNd das besteht wieder nur aus einersimplen String variable. Davon kann ich mir immernoch nciht ableiten wo ich meine 3 Listmodels und TreeModel hinstecke? Ob ich daraus eine MainWIndow Model klasse mache!? UNd wie ich den Controller zwischen Model und View sinnvoll hänge.
Außerdem erkenne ich nicht was da der Controller ist? ist das der Service?



Beim erstelneines LagerHistroyModels erbe ich da von DefaultListModel? Um das direkt als Mdel von einer JList festlegen zu können? UNd würde ich dann in diese Klasse meine Funktionen z.B. getDataFromDatabase(), removeHistoryElement(), add.. etc reinhängen?
 
Zuletzt bearbeitet:
G

Gast2

Gast
es hat aber ebenfalls wieder nur EIN Model. UNd das besteht wieder nur aus einersimplen String variable. Davon kann ich mir immernoch nciht ableiten wo ich meine 3 Listmodels und TreeModel hinstecke? Ob ich daraus eine MainWIndow Model klasse mache!? UNd wie ich den Controller zwischen Model und View sinnvoll hänge.
Außerdem erkenne ich nicht was da der Controller ist? ist das der Service?
Kein Mensch weiß wie deine Models aussehen dass solltest schon du selber wissen die deine Fachklassen aussehen. Aus deinem DB Schema machst du jetzt deine Models. Wahrscheinlich hast du eine Lager klasse welche mehrere Artikel haben kann also.

Java:
public class Lager extends DomainModel
{

List<Artikel> artikel;

Usw.

Weiß nich was du mit simpler String Variable meinst. Wenn du in einer JList oder JTree etwas anderes darstellen lassen willst braucsht du einen Renderer...

Du verwechselt deine GUI Models mit deinen Domain Models...
Die Controller sind deine anonymen LISTENER!!!
MVC ist ein Architekturmuster für die GUI entwicklung mehr nicht...

UNd wie ich den Controller zwischen Model und View sinnvoll hänge.
Als anonymen Listener...

So könnte es aussehen wenn die View ihre Daten darstellt:
View <-> GUI-Controller<-> Model <-> Controller <-> Service <-> DAO <-> Datenbank

Kannst es aber auch einfach machen und die ganze Logik in deinen Controller packen
View <-> GUIController<->Model <-> Service <-> Datenbank

Die View kann jetzt mehrere Komponenten beinhalten , JButton,JList usw.
Macht der User jetzt eine Interaktion (drückt den Button). Hat die Komponente einen Listener (z.b. ActionListener), welcher den GUI-Controller darstellt, der ist dafür zuständig die Daten zu besorgen und das Model zu füllen.

Wenn du nun eine Interaktion auslöst
 
Zuletzt bearbeitet von einem Moderator:

Denny1989

Aktives Mitglied
ok mal ein Beispiel.

Lagerhistorie: HistorienId, ArtNr, Menge, Datum, Bemerkung

Das ist der Db entwurf. Eine Lagerhistorie würde dann aus einer Liste mit elementen dieses typen mit gleicher HistorienId bestehen.
Mein (domain) Model wäre das dann richtig? Wie würde das nun Konzeptionel in ein GUI MOdel welche ja einfach nur ne abgespeckteVersion davon ist übertragen werden?

Was meinst du denn mit anonyme Listener? wenn ich meine Listener in die View Klasse schreibe welche dann das Model ansprechen hab ich ja nix gekonnt in sachen trennung von view und Logik oder?
 
G

Gast2

Gast
Darum gibt es GUIController die vom Toolkit abhängig sind und normale Controller(welche Service aufrufen)
 

ARadauer

Top Contributor
UNd wie ich den Controller zwischen Model und View sinnvoll hänge.
controller instanziert model und view und regestriert die view als listener am model.
model informiert bei änderung über oberserver/interface (also kennt die gui klasse nicht) die gui...

ob du jetzt an ein modell mehrere view listener hängst (excel diagramm darstellung und excel tabellenblatt darstellung)
oder eine view auf mehrere modell hört ist ja egal...
 

ARadauer

Top Contributor
wer war das vorhin: gui modell ist nicht fachmodell?
ja stimmt schon, aber bei kleinen swing anwendungen die direkt auf die DB gehen ist es meiner Meinung nach kein Fehler das simpel zu halten und das zu haben.
Also ein KundenModell hält einen Liste mit Kunden und einen aktuell ausgewählten Kunden. Es informiert Tabellen- und Detail Ansicht über Änderungen und implementiert hierfür das AbstractTable Modell... hab ich schon öfter so implementiert....
 
G

Gast2

Gast
wer war das vorhin: gui modell ist nicht fachmodell?
ja stimmt schon, aber bei kleinen swing anwendungen die direkt auf die DB gehen ist es meiner Meinung nach kein Fehler das simpel zu halten und das zu haben.
Also ein KundenModell hält einen Liste mit Kunden und einen aktuell ausgewählten Kunden. Es informiert Tabellen- und Detail Ansicht über Änderungen und implementiert hierfür das AbstractTable Modell... hab ich schon öfter so implementiert....

Für eine JTree oder für eine JTable wirst du aber ein DomainModel haben und ein SwingTree bzw. TableModel...
 
G

Gast2

Gast
darüber kann man streiten ;-)

Mach einen Gegenvorschlag...
Wie gesagt für mich gibt (Logik) Controller, welche Service o.ä. aufrufen die nichts mit MVC zu tun haben.

Und es gibt GUI Controller die für MVC genutzt werden und welche Toolkit abhängig sind. Die würde ich als anonyme Listener machen.
 
G

Gast2

Gast
Hier mal ein Beispiel (vereinfacht!!!)

Models:
Java:
//Für die Notifications
public class DomainModel {

	protected PropertyChangeSupport changeSupport;
	
	public DomainModel(){
		changeSupport = new PropertyChangeSupport(this);
	}

	public PropertyChangeSupport getChangeSupport() {
		return changeSupport;
	}
	
}

Java:
public class Lager extends DomainModel{

	
	private String lagername;
	private List<Artikel> artikels = new ArrayList<Artikel>();
	
	public List<Artikel> getArtikels() {
		return artikels;
	}

	public boolean addArtikels(List<Artikel> artikel){
		boolean success = artikels.addAll(artikel);
		if(success){
			changeSupport.firePropertyChange("addArtikels", null, artikel);
		}
		return success;
	}

	public void setLagername(String lagername) {
		changeSupport.firePropertyChange("lagername", this.lagername = lagername, lagername);
	}

	public String getLagername() {
		return lagername;
	}
}

Java:
public class Artikel extends DomainModel{

	private String name;
	private Integer id;
	
	public void setName(String name) {
		changeSupport.firePropertyChange("name", this.name = name, name);
	}
	public String getName() {
		return name;
	}
	public void setId(Integer id) {
		changeSupport.firePropertyChange("id", this.id = id, id);
	}
	public Integer getId() {
		return id;
	}
	
}

Views:

Java:
public class View extends JPanel implements PropertyChangeListener{

	private Lager lager;
	private JList jList;
	
	public View(Lager lager){
		this.lager = lager;
		lager.getChangeSupport().addPropertyChangeListener(this);
		jList = new JList();
		jList.setCellRenderer(new MyListRenderer());
		add(new JScrollPane(jList));
	}

	@Override
	public void propertyChange(PropertyChangeEvent evt) {
		if(evt.getPropertyName().equals("addArtikels")){
			jList.setListData(lager.getArtikels().toArray());
		}
		
	}
	
	private class MyListRenderer extends DefaultListCellRenderer{
		
		@Override
		public Component getListCellRendererComponent(JList list, Object value,
				int index, boolean isSelected, boolean cellHasFocus) {
			JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected,
					cellHasFocus);
			Artikel a = (Artikel) value;
			label.setText("Id: " + a.getId() + "      Name: " + a.getName());
			return label;
		}
	}
	
}

Java:
public class View2 extends JPanel{
	
	
	private Lager lager;

	public View2(Lager lager){
		this.lager = lager;
		JButton button = new JButton("Create Artikel");
		// DAS HIER IST EIN Controller in MVC
		button.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				//Entweder du machst hier einen neuen (Logik) Controller der einen oder mehrere Service aufruft.
				
				//oder machst hier deine sachen
				CreateService initService = new CreateService();
				initService.createArtikelData(View2.this.lager);
			}
		});
			add(button);
	}

}

Service und Main
Java:
public class CreateService {

	public void createArtikelData(Lager lager){
		List<Artikel> list = new ArrayList<Artikel>();
		for(int i = 0; i < 5; i++){
			Artikel artikel = new Artikel();
			artikel.setId(i);
			artikel.setName("Artikel" + i);
			list.add(artikel);
		}
		lager.addArtikels(list);
	}
	
}

Java:
public class Main {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Lager lager = new Lager();
		lager.setLagername("Lager 1");
		
		final JFrame frame = new JFrame();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(300,300);
		
		frame.add(new View(lager), BorderLayout.CENTER);
		frame.add(new View2(lager), BorderLayout.SOUTH);
		
		SwingUtilities.invokeLater(new Runnable() {
			
			@Override
			public void run() {
				frame.setVisible(true);
			}
		});

	}

}

Wie gesagt ich würde noch eine (Logik) Controller einführen (hat nix mit MVC zu tun) oder nenn wie du es magst, falls du mehrere Service aufrufen musst kannst du das schön kapseln.
 
Zuletzt bearbeitet von einem Moderator:

ARadauer

Top Contributor
Mach einen Gegenvorschlag...
Wie gesagt für mich gibt (Logik) Controller, welche Service o.ä. aufrufen die nichts mit MVC zu tun haben.

Und es gibt GUI Controller die für MVC genutzt werden und welche Toolkit abhängig sind. Die würde ich als anonyme Listener machen.

Wobei "streiten" der falsche Begriff ist... ist gibt in diesem Bereich einfach mehrere Ansätze die richtig sind. MVC ist ja kein Gesetzt... es ist einfach ein Muster von Mustern das Hilft GUI und Daten besser zu trennen...

Es kommt drauf an was man als Controller versteht... Controller als das C in MVC ist ja der GUI-Controller der keine Fachlogik enthalten soll
1. VIEW - stößt Aktion in Controller an, Controller lädt Daten, Controller setzt Daten in das Model
2. VIEW - stößt Aktion in Controller an, Controller veranlasst Modell die Daten zu laden
3. VIEW - stößt Aktion in Controller an, Controller lädt Daten die das Modell sind

(Ob die Fachlogik jetzt im Controller oder Modell ist oder nochmal in Services die vom Modell oder Controller benutzt werden, sei dahingestellt..)
Hab alle 3 Varianten schon gesehen und finde keine davon falsch...
 
G

Gast2

Gast
Wobei "streiten" der falsche Begriff ist... ist gibt in diesem Bereich einfach mehrere Ansätze die richtig sind. MVC ist ja kein Gesetzt... es ist einfach ein Muster von Mustern das Hilft GUI und Daten besser zu trennen...

Es kommt drauf an was man als Controller versteht... Controller als das C in MVC ist ja der GUI-Controller der keine Fachlogik enthalten soll
1. VIEW - stößt Aktion in Controller an, Controller lädt Daten, Controller setzt Daten in das Model
2. VIEW - stößt Aktion in Controller an, Controller veranlasst Modell die Daten zu laden
3. VIEW - stößt Aktion in Controller an, Controller lädt Daten die das Modell sind

(Ob die Fachlogik jetzt im Controller oder Modell ist oder nochmal in Services die vom Modell oder Controller benutzt werden, sei dahingestellt..)
Hab alle 3 Varianten schon gesehen und finde keine davon falsch...

Variante 2 würde ich nie benutzen...
 

Denny1989

Aktives Mitglied
genau das ist zb ein Problem bei mir. WIe manage ich das bzw wie verbinde ich diese Beiden ? die müssen ja irgendwie synchron laufen oder?

nochmal vereinfacht probieren..

view:
1 Jlist (Rechnungen)
1 tree (Artikel mit KAtegorien)
und zur erkläung einen button

Model:
holt sich seine daten aus einer DB
-hält:
ListModel
TreeModel

Controller:
-erstellt view und model
-registriert die view beim model als observer

Fragen:
Wo hänge ich erstmal den ActionListener vom button an? amch ich das über den COntroller oder im Code von der View direkt
new ActionListener() {actionPerfomed()...}? Oder macht man dafür jeweils ne eigene neue KLasse auf?

Implementiert eine EINE Modelklasse ein Observable / was äquivalentes und informiert die View welche EINEN Observer implementiert... Oder implementiere ich mir jeweils ein eigenes ListModel / TreeModel welches jeweils Observable implementieren und auch verschiedene ObserverInterfaces voraussetzen um die Update methode "einzuschränken"?

Kann ich in den Tree / Listmodels direkt weitere informationen zu den dargestellten halten?

Wie update ich einen Tree? wenn ich mein TreeModel auf das Model des GUI Trees gesetzt habe kann ich ja nciht einfach nur die referenz neu setzen das bringt ja nix oder?

EDIT: IHR WART WIEDER SCHNELLER ALS ICH.


Edit2:
bezeichnest du das jetzt als Controller alias anonymer Listener?



Java:
 button.addActionListener(new ActionListener() {
            
            @Override
            public void actionPerformed(ActionEvent e) {
                //Entweder du machst hier einen neuen (Logik) Controller der einen oder mehrere Service aufruft.
                
                //oder machst hier deine sachen
                CreateService initService = new CreateService();
                initService.createArtikelData(View2.this.lager);
            }
        });

Und is das ne saubere Methode wenn ich in diesen anonymen Listenern immer nur Methoden auf einem (logik?) COntroller aufrufe?

als beispiel:

mein Controller:
erstellt view und model
-stößt model an sich "selbst" aus der DB zu ziehen
-beinhaltet methode addArtikel( Artikel article) {model.getArtikelModel().addArtikel(aritcle); }

view
initialisiert sich.
erstellt die Button / actionListener die keine größeren Aufwände haben als Textfeld.getText() ud ruft direkt controller.addArtikel(new Artikel(name)) auf?
-implementiert propertyChange Listener (verkettet man da wirklich unzählige If abfragen um rauszufinden was sich aktualisiert hat?)

model
implementiert den PropertyChangeSupport
 
Zuletzt bearbeitet:
G

Gast2

Gast
Edit2:
bezeichnest du das jetzt als Controller alias anonymer Listener?



Java:
 button.addActionListener(new ActionListener() {
            
            @Override
            public void actionPerformed(ActionEvent e) {
                //Entweder du machst hier einen neuen (Logik) Controller der einen oder mehrere Service aufruft.
                
                //oder machst hier deine sachen
                CreateService initService = new CreateService();
                initService.createArtikelData(View2.this.lager);
            }
        });

Und is das ne saubere Methode wenn ich in diesen anonymen Listenern immer nur Methoden auf einem (logik?) COntroller aufrufe?

Jop ...

Kannst auch den ActionListener in einen GUI Controller machen was dir aber keinen Mehrwert bringt...
 

Denny1989

Aktives Mitglied
habeim letzten post zum schluss noch was ergänzt. kannste noch kurz was zum logik controller schireben und wie ich ein TreeModel für einen JTree in dein Beispiel integrieren würde? wenns nciht zu viel arbeit macht... Danke schonmal.

wenn ich statt dem oben geschriebenen auslesen von Textfeldern oder so in der View es ausm Controlr heraus machen würde...

view.getJTextfield().getTex() würde ich meinen Controller an die View Binden was nicht erwünscht ist richtig?
 
Zuletzt bearbeitet:

ARadauer

Top Contributor
Wie lädst du denn die Daten? Mach mal ein Beispiel, vielleicht versteh ich dich auch falsch.

natürlich lädt das Model die Daten nicht selber, es benutzt schon einen Service bzw bei kleinen Anwendungen direkt ein DAO

Poker Turnier verwalltung ;-)
Java:
public class TourneyModel {
      
   ArrayList<ModelChangeListener> listener = new ArrayList<ModelChangeListener>();
    
   private ITourneyDao dao;   
   private List<Tourney> tourneyList = new ArrayList<Tourney>();
   
   public TourneyModel(ITourneyDao dao){
      this.dao = dao;
   }
   
   public void readAll(){
      tourneyList = dao.readAllTourneys();   
      informListener();      
   }
...
so ungefähr. also Ich kenne Leute die sagen, das Model ist die Liste. Ich habe gerne ein eigenes Objekt die das Model repräsentiert.
Man könnte jetzt im Controller das DAO benutzen und dem Model die Liste setzen... was ich nach Head First On Design Patterns als falsch empfinde, da der Controller nur für GUI Logic usw zuständig ist. Also bei mir lädt sich das Modell mit Services oder Daos die Daten selber...
Einfache Fachlogik würde auch auch in dieser Klasse machen, bzw ein Service der von dieser Klasse benutzt wird...

Ich mach das meistens so (wobei eigentlich nur privat, beruflich bin ich im web unterwegs)
... ich weiß das es Leute gibt denen das nicht gefällt aber ich muss sagen ich fahre sehr gut damit...

Im Allgemeinen: Man sollte bei diesen Themen nicht zu dogmatisch sein, komm ich in ein Team wo es anders gemacht wird.. ist es für mich auch ok....

solange keine queries im panel ausgeführt werden ;-)
 
G

Gast2

Gast
natürlich lädt das Model die Daten nicht selber, es benutzt schon einen Service bzw bei kleinen Anwendungen direkt ein DAO

Poker Turnier verwalltung ;-)
Java:
public class TourneyModel {
      
   ArrayList<ModelChangeListener> listener = new ArrayList<ModelChangeListener>();
    
   private ITourneyDao dao;   
   private List<Tourney> tourneyList = new ArrayList<Tourney>();
   
   public TourneyModel(ITourneyDao dao){
      this.dao = dao;
   }
   
   public void readAll(){
      tourneyList = dao.readAllTourneys();   
      informListener();      
   }
...
so ungefähr. also Ich kenne Leute die sagen, das Model ist die Liste. Ich habe gerne ein eigenes Objekt die das Model repräsentiert.
Man könnte jetzt im Controller das DAO benutzen und dem Model die Liste setzen... was ich nach Head First On Design Patterns als falsch empfinde, da der Controller nur für GUI Logic usw zuständig ist. Also bei mir lädt sich das Modell mit Services oder Daos die Daten selber...
Einfache Fachlogik würde auch auch in dieser Klasse machen, bzw ein Service der von dieser Klasse benutzt wird...

Ich mach das meistens so (wobei eigentlich nur privat, beruflich bin ich im web unterwegs)
... ich weiß das es Leute gibt denen das nicht gefällt aber ich muss sagen ich fahre sehr gut damit...

Im Allgemeinen: Man sollte bei diesen Themen nicht zu dogmatisch sein, komm ich in ein Team wo es anders gemacht wird.. ist es für mich auch ok....

solange keine queries im panel ausgeführt werden ;-)

Wie gesagt würde ich nicht so machen.
1. Grund du kannst das Model nicht ohne deine DAO's wiederverwenden ich finde das Model sollte ziemlich plain und stateless bleiben und keine Logik enthalten oder Service aufrufen
2. Wird es so schwer das Model mit Codegeneratoren generieren zu lassen, was einem sehr sehr viel Arbeit abnehmen kann.
3. Bei Client Server finde ich es ziemlich unpraktisch wenn das Model einen entfernten Aufruf macht und die Exception handelt usw.

Wie gesagt View hat anonyme Listener (GuiController) greift auf Logik(Controller) oder direkt Service zu (je nachdem wieviel schichtig alles werden sollte). Es gibt also eine Client LogikSchicht welches dann den Service aufruft und Model synchronisiert.

Gibt ja schon einiges dass man sich generien lassen kann wenn man einen Client/Server macht. Spätestens wenn du DTO's oder ähnliches hast wird dein Konzept unschön.
Darum lieber Converter in der Logikschicht welche Daten und Model synchronisert, gibt schon Projekte auch zum generieren lassen.
 
G

Gast2

Gast
habeim letzten post zum schluss noch was ergänzt. kannste noch kurz was zum logik controller schireben und wie ich ein TreeModel für einen JTree in dein Beispiel integrieren würde?

Schau in der API wie man ein TreeModel macht und benutze deine DomainModels darin.



view.getJTextfield().getTex() würde ich meinen Controller an die View Binden was nicht erwünscht ist richtig?

Wie gesagt würde ich nicht machen zuviel overhead
 

Denny1989

Aktives Mitglied
kurze frage noch. in dem domain model welches du oben beispielhaft erstellt hast ist nur der propertyChanged teil drin. was würde denn jetzt real da drin? irgendwie versteh ich den zusammen hang zwischen der lager klasse und dem domain model nicht ... das ist doch nur um das property changed bereitzustellen oder? Oder hält das noch irgendwas anderes?
 

ARadauer

Top Contributor
@SirWayne: ja klingt schlüssig... ich werd mir das nochmal durch den Kopf gehen lassen...
Wie gesagt man sollte in dem Bereich nicht zu dogmatisch handeln und sich ruhig auf andere und vielleicht bessere Ansätze einlassen...
 

Denny1989

Aktives Mitglied
Guten Morgen. Wollte nochmal eine Frage loswerden.

Java:
 @Override
    public void propertyChange(PropertyChangeEvent evt) {
        if(evt.getPropertyName().equals("addArtikels")){
            jList.setListData(lager.getArtikels().toArray());
        }

Wenn ich im model nun 20 Variablen habe. Baue ich dann in der View so eine Verkettung von If abfragen nach den PropertyName String auf um die zu Updaten? Oder würde ich dann irgendwie mit Observable Pattern und für jede Variable / Variablen gruppe einen extra Observer einrichten?
 
Zuletzt bearbeitet:
G

Gast2

Gast
@SirWayne: ja klingt schlüssig... ich werd mir das nochmal durch den Kopf gehen lassen...
Wie gesagt man sollte in dem Bereich nicht zu dogmatisch handeln und sich ruhig auf andere und vielleicht bessere Ansätze einlassen...

Ja kommt auch auf die größe des Projektes an. Aber ich würde es lieber granularer schichtiger von anfang an aufbauen braucht meistens auch nicht mehr Zeit und späterer (unerwartete) Erweiterungen können besser eingebaut werden wie wenn alles umgebaut werden muss.

Z.b. am anfang eine standalone Anwendung und auf einmal soll doch ein richtiger Server eingebaut werden und dann die ganzen Models nochmal umbbauen kannn nervig werden^^...
 
G

Gast2

Gast
Guten Morgen. Wollte nochmal eine Frage loswerden.

Java:
 @Override
    public void propertyChange(PropertyChangeEvent evt) {
        if(evt.getPropertyName().equals("addArtikels")){
            jList.setListData(lager.getArtikels().toArray());
        }

Wenn ich im model nun 20 Variablen habe. Baue ich dann in der View so eine Verkettung von If abfragen nach den PropertyName String auf um die zu Updaten? Oder würde ich dann irgendwie mit Observable Pattern und für jede Variable / Variablen gruppe einen extra Observer einrichten?

Das ist das Observer Pattern!!! View regisitiert sich auf dem Model. Model ändert sich und schmeißt ein PropertyChangeEvent. View reagiert darauf. Das mit dem PropertyChangeSupport war nur ein Beispiel du kannst auch eigene Listener schreiben.

Im Model kann es auch Methoden geben die mehrer Modeländerunegn durchführen und danach ein final Event werfen worauf die View reagiert.


Hier mal ein Beispiel für eigene Listener: Du selbst wissen wie es dir besser gefällt...
model
Java:
public class Lager{

	private List<Artikel> artikels = new ArrayList<Artikel>();
	private Set<ArtikelListener> artikelListeners = new HashSet<ArtikelListener>();
	
	public boolean addArtikeListener(ArtikelListener artikelListener){
		return artikelListeners.add(artikelListener);
	}
	
	public boolean removeArtikeListener(ArtikelListener artikelListener){
		return artikelListeners.remove(artikelListener);
	}
	
	public boolean addArtikels(List<Artikel> artikel){
		boolean success = artikels.addAll(artikel);
		if(success){
			fireAddArtikel(artikel);
		}
		return success;
	}
	
	private void fireAddArtikel(List<Artikel> artikel){
		for(ArtikelListener artikelListener: artikelListeners){
			artikelListener.actionAddArtikel(artikel);
		}
	}

Listener
Java:
public interface ArtikelListener extends EventListener{

	void actionAddArtikel(List<Artikel> artikel);
	
	void removeAddArtikel(List<Artikel> artikel);
	
	// und so weiter
	
}

View

Java:
public class View extends JPanel implements ArtikelListener{

	private Lager lager;
	private JList jList;
	
	public View(Lager lager){
		this.lager = lager;
		lager.addArtikeListener(this);
		jList = new JList();
		jList.setCellRenderer(new MyListRenderer());
		add(new JScrollPane(jList));
	}

	
	private class MyListRenderer extends DefaultListCellRenderer{
		
		@Override
		public Component getListCellRendererComponent(JList list, Object value,
				int index, boolean isSelected, boolean cellHasFocus) {
			JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected,
					cellHasFocus);
			Artikel a = (Artikel) value;
			label.setText("Id: " + a.getId() + "      Name: " + a.getName());
			return label;
		}
	}

	@Override
	public void actionAddArtikel(List<Artikel> artikel) {
		jList.setListData(lager.getArtikels().toArray());
		
	}

	@Override
	public void removeAddArtikel(List<Artikel> artikel) {
		// TODO Auto-generated method stub
		
	}

Du kannst es auch noch ein ArtikelEvent einführen und so weiter.

Ich persönlich benutze den ProprtyChangeSupport nicht mehr weil mir die implmentierung nicht gefällt und ein paar Nachteile hat.
Ich mache immer einen eigenen Support der intern ein Set<PropertyChangeListener> hält.
 

Marco13

Top Contributor
Wenn ich im model nun 20 Variablen habe. Baue ich dann in der View so eine Verkettung von If abfragen nach den PropertyName String auf um die zu Updaten? Oder würde ich dann irgendwie mit Observable Pattern und für jede Variable / Variablen gruppe einen extra Observer einrichten?

Ich finde diese PropertyChangeListener ja auch irgendwie suspekt ( http://www.java-forum.org/allgemein...rwendet-man-propertychangedevents-eigene.html )... würde die nicht (oder nur SEHR bedingt) in eigenen Modellen verwenden....
 
G

Gast2

Gast
Ich finde diese PropertyChangeListener ja auch irgendwie suspekt ( http://www.java-forum.org/allgemein...rwendet-man-propertychangedevents-eigene.html )... würde die nicht (oder nur SEHR bedingt) in eigenen Modellen verwenden....

Nee finde den ProprtyChangeListener an sich nicht schlecht... Ich würde ungern JEDES mal eigene Listener machen. Aber der PropertyChangeSupport ist total daneben, den würde ich nie verwenden.

Bei EMF wird einem das alles mit generiert aber die haben auch nur einen Adapter(Listener) welche auf Änderungen auf den Content des Model hört und da muss man dann auch mit if vergleichen.
 

Denny1989

Aktives Mitglied
Ok habe mal angefangen meine (domain) Models erstellt. Habe ich das richtig verstanden dass die domain model ausschließlich die Daten enthalten welche die Datenbasis (Datenbank/ xml datei ) hält?

Java:
public class Artikel {

	private String artNr;
	private String name;
	private String beschreibung;
	private String kategorie;
	private double bruttoPreis;
	private double einkaufsPreis;
	private Integer lagerplatzVerbrauch;
	private Hersteller hersteller;
	
	public Artikel() {
		
	}...getter und setter bla bla..

und natürlich noch Hersteller und sowas. Diese haben keine Observer o.ä..
Nun gibt es einen Service der das Model mit daten aus der DB füllt... je nach dem was ich halt inital brauche...

Dann gibt es ein GUI Model, nennt sich bei mir DisponentModel, dies implementiert / enthält PropertyChangeSupport oder was ähnliches und ausschließlich die die ListModels, TreeModels (und evtl ne referenz auf das DomainModel?).

Mein Controller (logik) enthält nun nur noch Funktionen a la addArtikel(Artikel article) die von der View in einem anonymen Listener aufgerufen wird, und leitet die an den ModelService weiter, der dann das GuiModel das DomainModel bearbeitet und evtl halt gleich in Datenbank die änderungen schreibt. Der Modelservice bedient also die Models immer Synchron.

Meine View enthält jetzt den PropertyChangeListener (der einfachheit halber erstmal) und reiht in der update methode nun diese unendlich langen if statements aneinander (das ist eine Frage die ich wirklich gern direkt beantwortet hätte :) ) ...

Wenn die Referenz meine GUIModels.TreeModel aber direkt dem Jtree übergeben wurde was mache ich dann um die daten zu aktualisieren? einfach neu setzen damit er neu "zeichnet"?

Ich hoffe ich zeige genügend eigeninitiative :) will es wirklich gern verstehen. Und bin dankbar für eure hilfe.
 
G

Gast2

Gast
Ok habe mal angefangen meine (domain) Models erstellt. Habe ich das richtig verstanden dass die domain model ausschließlich die Daten enthalten welche die Datenbasis (Datenbank/ xml datei ) hält?

Java:
public class Artikel {

	private String artNr;
	private String name;
	private String beschreibung;
	private String kategorie;
	private double bruttoPreis;
	private double einkaufsPreis;
	private Integer lagerplatzVerbrauch;
	private Hersteller hersteller;
	
	public Artikel() {
		
	}...getter und setter bla bla..

und natürlich noch Hersteller und sowas. Diese haben keine Observer o.ä..
Nun gibt es einen Service der das Model mit daten aus der DB füllt... je nach dem was ich halt inital brauche...

Sieht schon mal gut aus...
Aber die DomainModels müssen Events feuern (notifys) und Observer (Beobachter) aufnehmen können.

Dann gibt es ein GUI Model, nennt sich bei mir DisponentModel, dies implementiert / enthält PropertyChangeSupport oder was ähnliches und ausschließlich die die ListModels, TreeModels (und evtl ne referenz auf das DomainModel?).

Der PropertyChangeSupport gehört in deine DomainModels!!!
Warum machst du ein extra GUIModel? Brauchst du doch gar nicht. Deine List- und TreeModels usw. sind doch schon GUIModels und haben auch schon Methoden und Listener die auf Änderungen reagieren.

Mein Controller (logik) enthält nun nur noch Funktionen a la addArtikel(Artikel article) die von der View in einem anonymen Listener aufgerufen wird, und leitet die an den ModelService weiter, der dann das GuiModel das DomainModel bearbeitet und evtl halt gleich in Datenbank die änderungen schreibt. Der Modelservice bedient also die Models immer Synchron.

Meine View enthält jetzt den PropertyChangeListener (der einfachheit halber erstmal) und reiht in der update methode nun diese unendlich langen if statements aneinander (das ist eine Frage die ich wirklich gern direkt beantwortet hätte :) ) ...

Wenn die Referenz meine GUIModels.TreeModel aber direkt dem Jtree übergeben wurde was mache ich dann um die daten zu aktualisieren? einfach neu setzen damit er neu "zeichnet"?

Ich hoffe ich zeige genügend eigeninitiative :) will es wirklich gern verstehen. Und bin dankbar für eure hilfe.

Der Service holt die Daten aus der Datenbank, speichert sie usw.
Der Controller füllt das Model. Aber für den Anfang für das bessere Verständniss würde ich den Controller weg lassen und in deinen anonymen Klassen den Service aufrufen so wie ich es oben gemacht hab. Der Service füllt das Model und speichert lädt usw. Daten aus der DB und enthält sonstige Logik.

Der Service kennt KEINE GUIModels. Sonst hast du ja keine Trennung!!!
 

Marco13

Top Contributor
Ein "Detail": Es ist oft vorteilhaft (in bezug auf Flexibilität und Strukturierung) die Modelle als Interfaces zu beschreiben. Das lapidare "...getter und setter bla bla.." wirft z.B. schon die Frage auf: GIBT es setter? Soll man die Artikelnummer eines Artikels noch ändern können, nachdem er einmal erstellt wurde? Das kann sein, wenn das quasi ein 1:1-Interface für irgendwelchen Datenbankinhalt sein soll. Aber man sollte sich die Frage stellen. Es kann aber auch sein, dass für ALLE (!) Fields nur getter existieren sollten (das Objekt also nach außen hin "immutable" (unveränderbar) ist).

Um die mögliche Frage vorwegzunehmen: Das ganze "Listener-Zeug" bezieht sich, soweit ich das bisher interpretiert habe, ja nicht auf die Eigenschaften eines einzelnen Artikels an sich, sondern auf den Bestand an Artikeln - also auf das Lager, wie SirWayne es ja unten auch angedeutet hatte.
 

Denny1989

Aktives Mitglied
ok. fangen wir nochmal "hinten"
also DomainModel stellt PropertyChangedSupport zur verfügung und die getter und setter (ja daten sollen auch geändert werden dürfen). Ändert sich darin was werden beobachter benachrichtigt.

Irgendwo muss ich doch jetzt meine TreeModels und Listmodels zusammenfassen oder wie bekommt das die Daten vom Domain model? Also die Verknüpfung Tree / DOmain Model fehlt mir glaub ich irgendwie. Es gibt ja dann noch so eine Klasse Model die irgendwie die Liste der Rechnungen, Liste der Artikel etc halten sollte... also eben das gesamte Wissensmodell der Applikation.

Es könne sich sowohl Artikel details ändern als auch Artikel löschen / hinzufügen. Muss ich also auch inder Artikel klasse den Property... zur verfügung stellen und nicht nur in der Rechnungsklasse oder ähnliches die die Artikel hält richtig?

Mein Controller der dann auch so Aktionen wie erstelle nen Dialog (view2) ausführen sollte, sollte nun eben nen ModelService aufrufen der Änderungen an die Models geben sollte und ggf. in die DB schreiben sollte. Der wird über ein Interface initialisiereModel(), addArtikel() oder sowas beschrieben.

Meine Aktionen löse ich per anonyme Listener wie von dir vorgeschlagen im View direkt auf, deckt sich eig auch bei genauerem nachdenken mit meinen .Net erfahrungen.

PS: Mit dem Factory Muster bin cih zumindest in der Theorie vertraut.
 
G

Gast2

Gast
Du siehst doch dass ich eine JList habe? Dort siehst du doch auch die Verküpfung...
Ich hol mir aus dem DomainModel einfach die Elemente und setze die in die JList, wenn sich das Model ändert...

Ein TreeModel musst du halt eins machen und Methoden zu Verfügung stellen... Sobald jemand ein lager dazu kommt kannst du in der View das TreeModel updaten...
How to Use Trees (The Java™ Tutorials > Creating a GUI With JFC/Swing > Using Swing Components)

Irgendwo muss ich doch jetzt meine TreeModels und Listmodels zusammenfassen oder wie bekommt das die Daten vom Domain model? Also die Verknüpfung Tree / DOmain Model fehlt mir glaub ich irgendwie. Es gibt ja dann noch so eine Klasse Model die irgendwie die Liste der Rechnungen, Liste der Artikel etc halten sollte... also eben das gesamte Wissensmodell der Applikation.

Warum willst du etwas zusammen fassen?
Dein Wissensmodell ist dein DomainModell dein herzstück der anwendung...


Mein Controller der dann auch so Aktionen wie erstelle nen Dialog (view2) ausführen sollte, sollte nun eben nen ModelService aufrufen der Änderungen an die Models geben sollte und ggf. in die DB schreiben sollte. Der wird über ein Interface initialisiereModel(), addArtikel() oder sowas beschrieben.

Warum soll der Controller sowas machen, wie nen Dialog erstellen???? Der (Logik)Controller sollte von der GUI Klassen befreit sein...


Fang einfach mal an zu programmiern und poste hier den Code zu deinen Fragen. Dann sieht man mal wie weit du bsit
 
Zuletzt bearbeitet von einem Moderator:

Marco13

Top Contributor
Irgendwo muss ich doch jetzt meine TreeModels und Listmodels zusammenfassen oder wie bekommt das die Daten vom Domain model? Also die Verknüpfung Tree / DOmain Model fehlt mir glaub ich irgendwie.

SirWayne hatte oben schon angedeutet:
Schau in der API wie man ein TreeModel macht und benutze deine DomainModels darin.
Das läßt sehr viel Interpretationsspielraum. Für den einfacheren (übersichtlicheren) Fall eines ListModels könnte das bedeuten, dass man ein eigenes ListModel implementiert, das direkt auf dem DomainModel arbeitet. Sinngemäß am Beispiel eines Lagers, das nur eine Artikelliste ist:
Java:
// Vorgegebenes Domain-Modell
interface LagerModell 
{
    int getAnzahlArtikel();
    Artikel getArtikel(int index);
    void add/removeLagerListener(...);
}

// Swing-ListModel fürs GUI
class ArtikelListModel implements ListModel
{
    private LagerModell lagerModel = ... // wird im Konstruktor übergeben

    // Die Methoden von ListModell werden direkt auf LagerModel umgebogen: 
    Object getElementAt(int index) { return lagerModell.getArtikel(index); }
    int getSize() { return lagerModell.getAnzahlArtikel(); }
    
    void add/RemoveListDataListener(ListDataListener l) { ... }
}

Die IMHO vermutlich deutlich einfachere Alternative wäre, im GUI einfach ein DefaultListModel zu verwenden. Wenn das LagerModell sich ändert, wird einfach das DefaultListModell mit dem aktuellen Lagerinhalt aktualisiert:
Java:
class GUI implements LagerListener
{
    private LagerModell lagerModel = ...

    private DefaultListModel lagerListModel = ...
    private JList lagerList = new JList(lagerListModel);

    public void lagerInhaltHasSichGeändert()
    {
        // Leere das lagerListModel
        // Füge alle Artikel aus dem LagerModell in das LagerListModell ein
    }
}



Es könne sich sowohl Artikel details ändern als auch Artikel löschen / hinzufügen. Muss ich also auch inder Artikel klasse den Property... zur verfügung stellen ...
Ja, dann schon.
 

Denny1989

Aktives Mitglied
Hallo. habe jetzt einiges umgesetzt und wollte mal fragen wie ich nun weiter vorgehen kann / sollte.
Habe jetzt models (Artikel, Rechnung, Rechnungsposition, ...) die quasi ein abbild der Datenbank darstellen und PropertyCHange Support anbieten. Weiterhin gibt es ein Model service der mir mein gesamtes Model (DisponentenModel) aus der Datenbank holt und die Objekte / Model erstellt. Quasi einfach nur eine HIlfsklasse.

Es gibt eine Controller der Referenzen auf den Model service das Model und die View hält. Er instanziiert Den Model service und übergibt ihm die Datenbank verbindung. Schubst die Methode erstelle initialesModel(db) an und setzt das Model. Danach wird die View erstelt diese Bekommt das MOdel übergeben und baut sich selbst auf und setzt die Models in die Listen. Die View hat einen PropertyCHangeListener und regelt die Updates (der zwei Listen bisher) mit If Abfragen auf die PropertyName member der Events. Die ListRenderer habe ich in eigene Klassen gemacht und an diese das Model übergeben (ist ja auch nur aufruf GUI --> Model...nicht andersrum, sollte ja i.O. sein?)

Nun wollte ich mich daran machen und mein JFreechart befüllen. Das wollte ich gern initial machen und die referenz auf das Model des Charts halten und dann nur Änderungen einfüge weil sich das Chart wohl automatisch updatet (laut Doku). Jetzt stellt sich mir die Frage wie ich das mache. Ich denke in das DisponentModel darfs das ChartModel / Chart ja eig nciht rein weil das ja GUI Model ist (auf einer anderen GUI gibts das evtl ja nicht). Ich weiß jetzt leider nicht wie ich das einbinden könnte. Damit es vernünftig ist. Die CHarts liegen in einem TabbedPane...es sollen also mehrere Charts / Chartmodels gehalten werden.

Wo / auf welche weise erstelle ich diese ChartModel und wo halte ich das?
 

Marco13

Top Contributor
Das hängt IMHO davon ab, wie die "Übersetzung" aussieht: Von den Daten, wie sie im Businessmodell liegen, in die Daten, wie sie im ChartModel liegen. Die beiden hier angedeuteten Optionen gibt es dort natürlich auch.
 

Denny1989

Aktives Mitglied
wäre es legitim ein ChartModel zu erstellen welches von dem von JFreechart erbt... diese nach dem Model zu instanziieren und es beim model als PropertxCHangeListener anzumelden (Und dem GUI MOdel eine referenz auf das BusinessMOdel zu übergeben)?

Um so dann immer wenn sich was relevantes ändert mein model zu aktualisieren?

dann würde das model ja immernoch frei von GUI Daten sein oder? die daten liegen im mom in den Listen des Typs Rechnung vor (ArrayList oder sowas).

edit: das wäre option 1 deines beitrages richtig?
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
MiMa JUnit5 im JavaFX Projekt AWT, Swing, JavaFX & SWT 2
B Java Projekt mit JavaFX und jfoenix ausführbar machen AWT, Swing, JavaFX & SWT 46
H JavaFX wie JavaFX Projekt aufsetzen? AWT, Swing, JavaFX & SWT 10
G JavaFX Code in neues Projekt übernehmen AWT, Swing, JavaFX & SWT 0
N JavaFX Javafx intelij Projekt zu ausführbaren jar Datei Machen AWT, Swing, JavaFX & SWT 1
Z GUI Forms - Mehrere Fenster in einem Projekt AWT, Swing, JavaFX & SWT 18
L FX-Projekt: fast leere Fensterausgabe ohne Fehlermeldung AWT, Swing, JavaFX & SWT 6
N JavaFX Projekt nachträglich zu JavaFX Application machen? AWT, Swing, JavaFX & SWT 1
ruutaiokwu SWT "Google Window Builder" tut keine jar's ins Projekt rein bei SWT-Projekt AWT, Swing, JavaFX & SWT 22
VPChief Eclipse: Projekt mit src ordner exportieren. AWT, Swing, JavaFX & SWT 76
Zrebna JavaFX-Projekt mit Bildern funktioniert nicht - um Hilfe wird gebeten AWT, Swing, JavaFX & SWT 14
ZH1896ZH MineSweeper Projekt: Testen nicht möglich AWT, Swing, JavaFX & SWT 6
N Ausführbare Datei aus JavaFX Projekt erstellen AWT, Swing, JavaFX & SWT 22
MiMa Java Projekt nach JavaFX convertieren AWT, Swing, JavaFX & SWT 4
M Java Gui Projekt, Würfelspiel AWT, Swing, JavaFX & SWT 2
Sam96 JavaFX mit Sqlite Projekt mit jar zu groß AWT, Swing, JavaFX & SWT 10
A Wie baue ich das Bus-System in ein Java Projekt ein? AWT, Swing, JavaFX & SWT 5
B Pong Projekt mit LWJGL Klassen exportieren AWT, Swing, JavaFX & SWT 14
C Hilfe beim programmieren mit studiumgebundenes Projekt AWT, Swing, JavaFX & SWT 1
J Frage zu Java Projekt [2D Game] AWT, Swing, JavaFX & SWT 3
Tom299 JavaFX Projekt-Struktur AWT, Swing, JavaFX & SWT 2
S Projekt: Meisterschaft - Abspeichern bereits gemachter Schritte AWT, Swing, JavaFX & SWT 2
M JavaFX MSI oder EXE aus JavaFX Projekt erstellen? AWT, Swing, JavaFX & SWT 2
Birke Swing Neue Swing LayoutManager: TOnion Projekt AWT, Swing, JavaFX & SWT 10
R JavaFX Mein SceneBuilder Projekt AWT, Swing, JavaFX & SWT 3
D Ambitioniertes Projekt - Brauche Stichworte AWT, Swing, JavaFX & SWT 4
M GUI-Projekt realisieren AWT, Swing, JavaFX & SWT 9
J Swing Window-Builder-Projekt richtig übertragen AWT, Swing, JavaFX & SWT 2
J Das erste Projekt und ein Haufen von Fragen. Der SudokuReader. AWT, Swing, JavaFX & SWT 4
D Java Projekt als Jar AWT, Swing, JavaFX & SWT 3
J jme neues projekt öffnen AWT, Swing, JavaFX & SWT 4
J Projekt Olympische Spiele AWT, Swing, JavaFX & SWT 12
F Netbeans Gui in BlueJ Projekt AWT, Swing, JavaFX & SWT 9
X Resourcen in Projekt einbinden AWT, Swing, JavaFX & SWT 7
R jFreeChart in eine NetBeans Projekt integrieren AWT, Swing, JavaFX & SWT 24
D Swing Projekt Herangehensweise Swing AWT, Swing, JavaFX & SWT 6
N Swing Projekt - jar ausführen AWT, Swing, JavaFX & SWT 11
C Problem mit Swing Application Framework - Projekt beim AWT, Swing, JavaFX & SWT 2
W netbeans projekt in Eclipse importieren -gui teil geht nicht AWT, Swing, JavaFX & SWT 5
C Mein erstes kleines Swing-Projekt - Probleme AWT, Swing, JavaFX & SWT 8
M Einstellung des Projekt-Verzeichnis in NetBeans AWT, Swing, JavaFX & SWT 4
T Projekt - ChatClient - JEditorPane - Smilies, Vektor AWT, Swing, JavaFX & SWT 2
D Events, Listener, GUI . Größeres Projekt AWT, Swing, JavaFX & SWT 4
M java projekt als exe kompilieren. AWT, Swing, JavaFX & SWT 2
M mvvm umsetzen ohne fxml AWT, Swing, JavaFX & SWT 0
M Menü ohne Menübar umsetzen[SWT] AWT, Swing, JavaFX & SWT 8
M Design in Java umsetzen AWT, Swing, JavaFX & SWT 3
cosmic Dartboard in JFrame umsetzen AWT, Swing, JavaFX & SWT 5
F JToggleButton in AWT umsetzen (Button soll stecken bleiben) AWT, Swing, JavaFX & SWT 4
F TableCellRenderer wie umsetzen? AWT, Swing, JavaFX & SWT 2
W Wie Layout mit welchen Swing Managern umsetzen? AWT, Swing, JavaFX & SWT 24
F Fenster im Fenster wie mit SWING umsetzen? AWT, Swing, JavaFX & SWT 2

Ähnliche Java Themen

Neue Themen


Oben