MVC Hilfe

wako

Grünschnabel
hallo Javajaner,

ich hab mal ne frage zu MVC. Hab zwar schon einiges gelesen (auch hier im forum) über Model-View-Controlls aber noch nie das richtige beispiel dafür gefunden. mein problem is einfach die umsetztung. ich frage mich immer wo was wie rein gehört.
Beispiel:

hab einfach ne gui mit 2 button und nem textarea (swing natürlich)....pk, für so ein kleines beispiel is glaub mvc übertrieben aber wie müsste zum beispiel eine view klasse (hier glaub nur die elemente anordnen?), eine model klasse (werden die elemente hier bei den listenern regestriert?) und ein controller klasse aussehen....und wer weis über wehn bescheid? hab echt keinen plan. vielleicht könnte mir ja jemand helfen. ach ja, kann es auch mehrere models und controller geben? wenn ja für was am besten immer einzelne komponenten machen?

thx leutz

wako
 
habs mal so gemacht. bitte sagt mir ob ich es richtig verstanden hab :-)

Meine View. Machts nix anderes als z.b. buttons anordnen und halt die GUI aufbaun
und sie hat zu jedem GUI-Element eine set und get Methode
Code:
public class PanelSystemPropertiesView extends JPanel{
...
public PanelSystemPropertiesView() {
		new PanelSystemPropertiesModel(this);
		this.initGUI();
	}
}

Mein Model kennt die View und registriert sich und die view beim controller
Code:
public class PanelSystemPropertiesModel{
	
	private PanelSystemPropertiesView panelView = null;
	private JFileChooser jfcLogging				= new JFileChooser();
	
	public PanelSystemPropertiesModel(PanelSystemPropertiesView panelView) {
		new PanelSystemPropertiesController(this,panelView);
		this.panelView = panelView;
		
		this.initFileChoser();
	}

	private void initFileChoser() {
		this.jfcLogging.setDialogTitle("Kunden-Verzeichnis wählen");
        this.jfcLogging.setDialogType(JFileChooser.OPEN_DIALOG);
        this.jfcLogging.setMultiSelectionEnabled(false);
        this.jfcLogging.setFileSelectionMode(JFileChooser.FILES_ONLY);
	}
	
	public void showFileChoser(JButton button) {
	    int action = this.jfcLogging.showOpenDialog(this.panelView); 
            if(action == JFileChooser.APPROVE_OPTION ) {
        	String strPath = this.jfcLogging.getSelectedFile().getAbsolutePath();
        	
        	if(button.equals(this.panelView.getJbutAIXVMPack())) {
        		this.panelView.getJtxtfAIXVMPack().setText(strPath);
        	} else if (button.equals(this.panelView.getJbutHPUXVMPack())) {
        		this.panelView.getJtxtfHPUXVMPack().setText(strPath);
        	} else if (button.equals(this.panelView.getJbutLINUXVMPack())) {
        		this.panelView.getJtxtfLINUXVMPack().setText(strPath);
        	} else if (button.equals(this.panelView.getJbutSINIXVMPack())) {
        		this.panelView.getJtxtfSINIXVMPack().setText(strPath);
        	} else if (button.equals(this.panelView.getJbutSOLARISVMPack())) {
        		this.panelView.getJtxtfSOLARISVMPack().setText(strPath);
        	} else if (button.equals(this.panelView.getJbutWINVMPack())) {
        		this.panelView.getJtxtfWINVMPack().setText(strPath);
        	}
        }
    }
}

Mein controller registriert die gui -elemente bei einem listener und ruft bei auftredenten
ereignissen methode(n) beim Model auf --> Model updated gui
Code:
public class PanelSystemPropertiesController{
	private PanelSystemPropertiesModel panelModel 	= null;
	private PanelSystemPropertiesView  panelView	= null;
	
	private JButton jbutAIXVMPack			= null;
	private JButton jbutHPUXVMPack			= null;
	private JButton jbutLINUXVMPack			= null;
	private JButton jbutSOLARISVMPack		= null;
	private JButton jbutSINIXVMPack			= null;
	private JButton jbutWINVMPack			= null;
	
	private Object src	= null;
	
	public PanelSystemPropertiesController(PanelSystemPropertiesModel panelModel, PanelSystemPropertiesView panelView) {
		this.panelModel = panelModel;
		this.panelView	= panelView;
		
		this.jbutAIXVMPack = 	 this.panelView.getJbutAIXVMPack();
		this.jbutHPUXVMPack =  	 this.panelView.getJbutHPUXVMPack();
		this.jbutLINUXVMPack = 	 this.panelView.getJbutLINUXVMPack();
		this.jbutSINIXVMPack = 	 this.panelView.getJbutSINIXVMPack();
		this.jbutSOLARISVMPack = this.panelView.getJbutSOLARISVMPack();
		this.jbutWINVMPack =	 this.panelView.getJbutWINVMPack();
		
		this.addToActionListener();
	}
	
	private void addToActionListener() {
		this.jbutAIXVMPack.addActionListener(
				new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						panelModel.showFileChoser(jbutAIXVMPack); } } );
		
		this.jbutHPUXVMPack.addActionListener(
				new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						panelModel.showFileChoser(jbutHPUXVMPack); } } );
		
		this.jbutLINUXVMPack.addActionListener(
				new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						panelModel.showFileChoser(jbutLINUXVMPack); } } );
		
		this.jbutSINIXVMPack.addActionListener(
				new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						panelModel.showFileChoser(jbutSINIXVMPack); } } );
		
		this.jbutSOLARISVMPack.addActionListener(
				new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						panelModel.showFileChoser(jbutSOLARISVMPack); } } );
		
		this.jbutWINVMPack.addActionListener(
				new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						panelModel.showFileChoser(jbutWINVMPack); } } );
		
	}
}


und is das richtig so :-) ( bestimmt nich....) Wenn ja, dann isses schon ziehmlich aufwendig...und macht bestimmt bei größeren ANwendungen die GUI langsam oder?
 
Hi, zunächst mal danke für deine Antwort und den Source Code. Ich möchte nun mal wiedergeben, wie ich das ganze verstanden hab :) Bitte korrigiert mich wenn ich falsch liege.

Die View kennt sowohl den Controller als auch das Model.
Sie registriert sich beim Model als Listener. Wenn sich im Model also was ändert, kann dieses Ereignisse feuern. Darauf ruft die View die get-Methoden des Models auf und aktualisiert die View. Wenn durch Benutzerinteraktion auf der View etwas verändert wird, ruft die View die Methoden des Controller auf.

Das Model kennt weder den Controller noch die View. Es führt eine Liste mit Listener (z.B. View), die bei Änderungen der Daten informiert werden sollen.

Der Controller kennt in diesem Fall das Model und erzeugt die View. Die Controller-Methoden werden ja von der View aufgerufen. Demnach ändert der Controller die Daten im Model.

Nun habe ich noch Fragen:
In dem Code greift der Controller nicht nur auf das Model und ändert die Daten, sondern greift auch auf die View zu um z.B. Items zu dis/enablen. Wäre es hier nicht besser beim Grundkonzept zu bleiben, dass das Model bei Änderung die View informiert?

Und warum greift die View nicht direkt auf die set-Methoden des Models zu, wenn sie ihm schon bekannt sind? Warum macht sie den Umweg über den Controller?

Gruss
M_Kay
 
Hallo,

also ich kenne das so, dass der Controller die View und das Model kennt. Der Controller ändert das Model und zeigt änderungen des Models in der View an. Das Model kennt nicht den Controller und nicht die View und die View kennt auch nicht das Model oder den Controller.

MFG

zEriX
 
Auch wenn die Entstehung des Beitrages von 2004 ist :rolleyes:

würde mich doch mal interessieren wie ihr das mvc anwendet.

Einen Link zur fh-muenchen habe ich zwar nicht gefunden aber in folgendem Artikel einen Verweis darauf:

http://www.medien.ifi.lmu.de/filead.../essays/BurcuBaltaci/modelviewcontroller.html

Ich denke mal, dass es sich hier um eine Zusammenfassung dessen handelt was mal im toten Link über MVC gesagt wurde.

Ich selber habe das MVC über Head First Design Patterns kennen gelernt. Dort wird das Pattern genauso erklärt wie M_Kay es beschrieben hat.

Im Prinzip setze ich das in meiner Programmierung auch so um. Was mich jetzt aber mal interessieren würde wäre wie ihr das handhabt und z.B. die View aktualisiert.
Ich selber arbeite hier mit Observern und registriere die View beim Model. Das Model benachrichtigt die View wenn sich etwas ändert und die View holt sich dann die Daten.

Jetzt habe ich selber schon überlegt, warum ich das mit Observern mache. Wozu gibt es denn PropertyChangeListener. Wäre das nicht auch eine Alternative oder die
bessere Vorgehensweise in Java?

@zerix
Deine Vorgehensweise finde ich auch gut oder sogar noch besser, da nur der Controller über alles Bescheid weiß.
Wie informiert das Model denn den Controller über Änderungen ?

Viel mehr beschäftigt mich aber die Frage:
Warum setzt der Controller die Daten im Model ?

Die Daten holt sich bei mir das model immer selber (Serverrequest z.B.) und informiert dann die Observer.
Sicher nicht die beste Lösung aber (wohl) möglich.

Zumindest laut :
http://de.wikipedia.org/wiki/Model_View_Controller

Scheint mir jetzt aber nach kürzerer Betrachtung nicht die eleganteste Lösung zu sein dem Model das zu überlassen :mad:
Der Weg, das nur der Controller über die View bzw das Model Bescheid weiß bringt eine losere Kopplung.
Kann es sein, dass sich deine Controller die Daten über andere Klassen holen ?
Scheint eigentlich auch plausibel. Möchte es nur bestätigt wissen.

Was machst du wenn es mehrere Views gibt. Nach Deinem Prinzip müßte der Controller ja alle möglichen Views registrieren können, damit diese über Änderungen informiert werden ?

Gruß Jens
 
@jb007:
In einem Test habe ich das so programmiert:
Der Controller ist gleichzeitig ein ViewEvent- und ModelEvent-Listener. Er erzeugt das Model und die View.
Das Model feuert bei Änderungen ein ModelEvent und die View (zb GUI) feuert ViewEvents bei Änderungen.
Auf diese Weise kennt das Model und die View "nichts" :)
Nur der Controller kennt beide und stellt den Vermittler zwischen den Klassen dar.

Das war so meine Überlegung, die ich in einem winzigen Programmbeispiel umgesetzt habe. Es hatte auch alles funktioniert :)
 
Zurück