Swing Controller im MVC-Pattern

J

Java2000

Gast
Ich habe eine Frage betreffend MVC. Ich bin mit dem Pattern vertraut, trotzdem fällt mir keine komfortable Lösung für ein sehr simples Problem ein. Stark vereinfacht: Ein JFrame enthält eine JTextArea und einen JButton. Bei Klick auf den JButton, soll der Inhalt der JTextArea in den Standartoutput System.out gedruckt werden. Ich würde gerne wissen, wie die MVC-Lösung dafür aussieht.

Dafür brauche ich wohl ein Model, worin der Text aus der textArea gespeichert wird. Soweit ich sehe, ist die einzige Lösung dazu, der textArea einen DocumentListener anzuhängen, der bei jedem Tastendruck den Text ins Model speichert (=sehr ineffizient).

Dann brauche ich noch eine View mit der JTextArea und dem JButton. Ganz einfach wäre es hier, wenn ich dem JButton einen ActionListener anhängen würde, der den Inhalt der JTextArea ausdruchen würde. Aber das wäre ja kein MVC (oder?). Stattdessen muss ich wohl Methoden anbieten, damit der Controller sich registrieren kann.

Zuletzt muss der Controller das Model und die View verbinden. Wie soll ich das jetzt machen? Wie schaffe ich es, dass die JTextArea ihren Inhalt ins Model mit setText() ins model speichert?

Ich habe das Skelet dafür vorbereitet. Wie verbinde ich im Controller das Model und die View richtigerweise miteinander?
Java:
import java.awt.BorderLayout;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.event.DocumentListener;

public class MVCQuestion {

	public static void main(String[] args) {
		Model model = new Model();
		View view = new View(model);
		new Controller(model,view);
	}
}

class Model {

	private String text;
	
	public Model() {
		text = "Schreibe hier einen Text";
	}

	public String getText() {
		return text;
	}
	
	public void setText(String text) {
		this.text = text;
	}
}

class View extends JFrame {

	private Model model;
	private JTextArea textArea;
	private JButton button;
	
	public View(Model model) {
		this.model = model;
		this.textArea = new JTextArea(model.getText());
		this.button = new JButton("Print");
		add(textArea,BorderLayout.CENTER);
		add(button,BorderLayout.SOUTH);
		
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setSize(400,300);
		setLocationRelativeTo(null);
		setVisible(true);
	}
	
	public void addTextListener(DocumentListener listener) {
		textArea.getDocument().addDocumentListener(listener);
	}
	
	public void addPrintListener(ActionListener listener) {
		button.addActionListener(listener);
	}
}

class Controller {

	public Controller(Model model, View view) {
		// was jetzt?
	}
}

Ich weiss, dass MVC ist kein perfekter Pattern, sondern mehr eine Richtlinie. Allerdings scheint es mir so, als wäre MVC in unzähligen Situationen eine schlechte Lösung und es existiert irgendwie kein Alternativ-Pattern dazu.

Vielen Dank im voraus für alle Hilfe
Gruss
Martin
 
Zuletzt bearbeitet von einem Moderator:

Michael...

Top Contributor
Wenn es nur darum geht, per Button den Inhalt einer TextArea (in der selben GUI) auf der Konsole auszugeben ist MVC wohl ein bisschen übertrieben. Wenn der Text nicht über ein "Model" sonstigen Objekten zur Verfügung gestellt werden muss, ist das ja eine reine GUI interne Geschichte.

Dafür brauche ich wohl ein Model, worin der Text aus der textArea gespeichert wird. Soweit ich sehe, ist die einzige Lösung dazu, der textArea einen DocumentListener anzuhängen, der bei jedem Tastendruck den Text ins Model speichert (=sehr ineffizient).
Wenn der Inhalt der TextArea tatsächlich in einem Model landen soll, dann wäre da ein FocusListener an der TextArea die bessere Wahl.
 
J

Java2000

Gast
Das GUI, das ich erstellen möchte, hat natürlich noch weitere Elemente. Deswegen wollte ich auch das heilige MVC-Pattern anwenden, damit nichts schief gehen kann. Kann doch nicht sein, dass ich bereits bei der einfachen Verknüfpung von TextArea und Button scheitere.
In Wirklichkeit sind die JTextArea und der JButton nicht einmal in der gleichen Klasse, sondern verschiedenen Klassen, die von JPanel erben.
 

Michael...

Top Contributor
Ohne die konkreten Absichten zu kennen, lässt sich da jetzt schwer was dazu sagen.
Generell gilt, alles was für das Model relevant ist (also u.U. auch anderen Programmteilen zur Verfügung gestellt werden soll) muss ins Model rein. Das ist die grosse Kunst beim MVC.

Nur weil Button und TextArea nicht in der selben Klasse deklariert sind (was in der Realität ziemlich oft vorkommt), macht es noch keinen Sinn da ein MVC aufzusetzen. Dem Button ist es ja egal was in der TextArea steht, er muss ja einfach nur seine Listener darüber informieren, dass er gedrückt wurde.
 
J

Java2000

Gast
Genau, der JButton hat keine Ahnung von der JTextArea. Deswegen muss der Text aus der JTextArea ins Model. Nur wie soll der Controller das anstellen?
Diese Komponenten sind nur ein kleiner Teil meiner Applikation. Aber wenn ich diese nicht in ein MVC-Pattern einbauen kann, kann ich die komplette Applikation nicht in MVC umsetzen. Schlussendlich würde mir nichts anderes übrig bleiben, als Controller und View zu verschmelzen und die Listener innerhalb der View zu erstellen. Dann würds nicht lange dauern und der erste fragt nach: "Und warum hast du's nicht in MVC gemacht?" ;)
 

Michael...

Top Contributor
Genau, der JButton hat keine Ahnung von der JTextArea. Deswegen muss der Text aus der JTextArea ins Model.
Ich meinte eigentlich dem Button sollte es egal sein, was in der TextAera drinsteht. Dem Button sollte es sogar egal sein, dass eine TextArea exisitiert. Die einzige Funktion eines Buttons ist es zu erkennen, wenn er gedrückt wird und dies weiter zu melden.

Mir scheint Du versucht's zwanghaft alles per MVC umsetzen zu wollen ;-)
Ein separates Model macht Sinn, wenn Information zentral verfügbar sein soll oder wenn die darstellende Komponente austauschbar sein sollte.

In dem von Dir beschriebenen Fall scheint mir der Aufwand ein Model zwischen Button und TextArea zu stecken wenig sinnvoll und nicht notwendig.

Hier mal ein auf die Schnelle gebasteltes Bsp. um zu verdeutlichen was ich meine. Button und TextArea sind in unterschiedlichen Klassen implementiert und wissen nichts voneinander und trotzdem kann man ohne MVC per Buttonclick den Text verarbeiten:
Java:
import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

public class Controller implements ActionListener {

	public static void main(String[] args) {
		new Controller();
	}

	private GUInterface gui;

	public Controller() {
		gui = new DemoGUI();
		gui.addButtonListener(this);
		gui.setBounds(0, 0, 200, 200);
		gui.setVisible(true);
	}
	
	interface GUInterface {
		public void addButtonListener(ActionListener listener);
		public String getSomeText();
		public void setVisible(boolean b);
		public void setBounds(int x, int y, int width, int height);
	}

	public void actionPerformed(ActionEvent evt) {
		System.out.println();
		System.out.println(gui.getSomeText());
	}

	class DemoGUI extends JFrame implements GUInterface {
		private TextAreaPanel textPanel;
		private ButtonPanel buttonPanel;

		public DemoGUI() {
			buttonPanel = new ButtonPanel();
			textPanel = new TextAreaPanel();
			this.getContentPane().add(textPanel, BorderLayout.CENTER);
			this.getContentPane().add(buttonPanel, BorderLayout.SOUTH);
			this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		}

		public void addButtonListener(ActionListener listener) {
			this.buttonPanel.addActionListener(listener);
		}

		public String getSomeText() {
			return this.textPanel.getTextContent();
		}
	}

	class TextAreaPanel extends JPanel {
		private JTextArea textArea;

		public TextAreaPanel() {
			this.setLayout(new BorderLayout());
			this.add(new JScrollPane(textArea = new JTextArea()), BorderLayout.CENTER);
		}

		public String getTextContent() {
			return "Mein Inhalt:\n" + this.textArea.getText();
		}
	}

	class ButtonPanel extends JPanel {
		private JButton button = new JButton("Drück mich");
		
		public ButtonPanel() {
			this.add(button);
		}
		
		public void addActionListener(ActionListener listener) {
			button.addActionListener(listener);
		}
	}
}
 

javimka

Top Contributor
Vielen Dank Michael für deine Demo. Tatsächlich versuche ich mein Beispiel zwangshaft mit MVC zu lösen, weil es ja noch andere Komponenten gibt, die ich der Einfachheit halber weggelassen habe, die das MVC rechtfertigen (JTextFields, JComboBoxen etc). Aber wenn ich die TextArea-JButton Verbindung nicht ins MVC Pattern einbauen kann, entspricht ja am Schluss das ganze Programm nicht dem MVC.

Aber nun habe ich ja deine Lösung, die ich bei mir umsetzen kann. Für mich ist es einfach seltsam, wenn ich 10 Buttons in einer GUI habe, 10 mal eine Methode addListenerToButtonX anbieten zu müssen. Insebesondere wenn sie nicht direkt im GUI sondern in einer anderen Panel-Klasse liegen, muss ich diese Methoden auch noch an die andere Panel-Klasse delegieren, wie du es in Zeile 60 mit dem Button machst.

Ich werde mir wohl auch in Zukunft ab und zu erlauben, einen Listener direkt in der GUI zu erstellen, wenn es so einfach ist. Ist dann halt ein Hybrid zwischen MVC und MV oder so ^^
 

Marco13

Top Contributor
Wieder der backlink :D

Ich finde es vollkommen legitim, einen kleinen Controller (d.h. Listener) direkt ins GUI zu packen. Zu versuchen, dort krampfhaft einen Controller reinzubringen kann (wie hinter einer Kette von Links, die mit dem obigen anfängt, zu lesen ist) schon ziemlich krampfig sein.

Auf deinen ersten Codeschnipsel bezogen ist mir aber nicht klar, welche Rolle das Modell dort spielen sollte. Wenn man auf einen Buttonklick hin den Inhalt einer JTextArea ausgeben will, gibt's da erstmal kein Modell, außer natürlich dem Modell, das hinter der TextArea steckt - nämlich das Document. Aber mit dem muss man ja erstmal nichts zu tun haben.
 

Michael...

Top Contributor
Aber wenn ich die TextArea-JButton Verbindung nicht ins MVC Pattern einbauen kann, entspricht ja am Schluss das ganze Programm nicht dem MVC.
MVC ist ja nur ein Pattern, das man innerhalb seines Programms anwenden kann. Das heisst ja nicht, dass man es auf das gesamte Programm anwenden oder auf jede einzelne Komponente runterbrechen muss.
Mir ging es ja nur darum, aufzuzeigen, dass es wegen eines Buttons und einer TextArea keinen Sinn macht ein Model aufzusetzen - es vielleicht sogar falsch wäre, nur um künstlich eine Verbindung zwischen Button und TextArea zu erzwingen.
u.U kann es ja Sinn machen den Text der Area in einem Model zu halten. Das hängt aber vom konkreten Anwendungsfall ab.

Deswegen: genau Überlegen welche Daten in einem Model zusammengefasst und verwaltet werden sollen.

Für mich ist es einfach seltsam, wenn ich 10 Buttons in einer GUI habe, 10 mal eine Methode addListenerToButtonX anbieten zu müssen.
Man kann auch einen Listener für mehrere Komponenten verwenden. Dieser muss dann die einzelnen Events unterscheiden können.
Ich werde mir wohl auch in Zukunft ab und zu erlauben, einen Listener direkt in der GUI zu erstellen, wenn es so einfach ist.
Bei "GUI internen" Aktionen macht das ja auch Sinn.
 
G

Gast2

Gast
Ich persönlich arbeite fast nur mit anonymen Listener...

im anhang hab ich mal ein kleines mvc bsp gemacht...
 

Anhänge

  • mvc.jar
    15,8 KB · Aufrufe: 16
Zuletzt bearbeitet von einem Moderator:
Ähnliche Java Themen
  Titel Forum Antworten Datum
MiMa Strukturierung und Organisation von umfangreiche Controller AWT, Swing, JavaFX & SWT 1
R Fxml findet controller nicht AWT, Swing, JavaFX & SWT 2
_user_q Objekte vom MainController in anderen Controller verwenden und andersherum (NullPointerException) AWT, Swing, JavaFX & SWT 14
sserio Wie funktioniert ein Controller bei JavaFx? AWT, Swing, JavaFX & SWT 1
A JavaFX Controller Problem AWT, Swing, JavaFX & SWT 1
I JavaFX - Pane wechseln über 2. Controller AWT, Swing, JavaFX & SWT 5
S JavaFX Fehler zwischen View und Controller bei MouseEvent (MVC) AWT, Swing, JavaFX & SWT 13
M4cM4rco0707 JavaFX Custom-Komponente mit Custom-Controller AWT, Swing, JavaFX & SWT 3
W Daten von Controller zu Controller übertragen AWT, Swing, JavaFX & SWT 7
J Saubere Trennung Model, View, Controller Javafx AWT, Swing, JavaFX & SWT 10
M JavaFX JavaFX in mehrere Controller AWT, Swing, JavaFX & SWT 21
OSchriever Auf Stage von FXML-Controller zugreifen AWT, Swing, JavaFX & SWT 12
J JavaFX JavaFX Splitpane - Zugriff auf die Controller der Elemente AWT, Swing, JavaFX & SWT 8
L JavaFX Exception nach includieren einer fxml // nested controller AWT, Swing, JavaFX & SWT 1
G JavaFX SplitPane Anwendung - Controller Probleme AWT, Swing, JavaFX & SWT 5
J Injection - Aber Controller sind null AWT, Swing, JavaFX & SWT 3
J Controller ist null - Warum AWT, Swing, JavaFX & SWT 3
@SupressWarnings() JavaFX Auf den Controller einer ListCell zugreifen AWT, Swing, JavaFX & SWT 4
L Javafx Controller Klasse in Maven AWT, Swing, JavaFX & SWT 7
M NullPointerException / Controller AWT, Swing, JavaFX & SWT 4
ralfb1105 JavaFX Daten zwischen Controller "austauschen" AWT, Swing, JavaFX & SWT 65
ralfb1105 JavaFX Exception Message von Model Class via Controller in View darstellen AWT, Swing, JavaFX & SWT 39
R JavaFX Übergabe von Parametern an Controller AWT, Swing, JavaFX & SWT 7
J Controller wird zu groß, was tun ? AWT, Swing, JavaFX & SWT 5
MiMa GUI Controller für Border Pane als MVC Modell AWT, Swing, JavaFX & SWT 1
K JavaFX in mehrere Controller aufteilen AWT, Swing, JavaFX & SWT 29
K JavaFX in mehrere Controller aufteilen AWT, Swing, JavaFX & SWT 0
F JavaFX ListView füllen in Controller Class AWT, Swing, JavaFX & SWT 12
L JavaFX Zugriff auf HostServices im FXML Controller AWT, Swing, JavaFX & SWT 1
V JavaFX Button Controller Fehler, trotz Erfolg in einem anderem Code? AWT, Swing, JavaFX & SWT 7
L Wie realisiere ich einen Controller AWT, Swing, JavaFX & SWT 1
M Java FX SceneBuilder 2.0, FXML, Controller AWT, Swing, JavaFX & SWT 1
T JavaFX Controller im extra Thread AWT, Swing, JavaFX & SWT 0
I JavaFX Im Controller die ProgressBar mit Task updaten AWT, Swing, JavaFX & SWT 6
A JavaFX Von Klasse auf Controller Inhalt zugreifen AWT, Swing, JavaFX & SWT 9
KrokoDiehl JavaFX Gleiche Controller-Instanz für inludiertes FXML AWT, Swing, JavaFX & SWT 1
A JavaFX Controller Class saveFile AWT, Swing, JavaFX & SWT 2
X JavaFX getScene().getWindow() im JavaFX Controller AWT, Swing, JavaFX & SWT 1
D JavaFX Gesetzte Variable in einem Controller im Controller laden AWT, Swing, JavaFX & SWT 1
L JavaFX Verständnisfrage zu JavaFX FXML und Controller-Klasse AWT, Swing, JavaFX & SWT 1
K Kann nicht auf GUI Elemente zugreifen, mit einer Methode im Controller klappts, mit der anderen nich AWT, Swing, JavaFX & SWT 10
Z JAVAFX Stage über Controller weitergeben um css-file zu laden AWT, Swing, JavaFX & SWT 4
D JavaFX Controller Klasse splitten? AWT, Swing, JavaFX & SWT 16
F JavaFX Zugriff auf Controller Methode von einer normalen Klasse aus AWT, Swing, JavaFX & SWT 4
C JavaFX Controller class AWT, Swing, JavaFX & SWT 2
M Java FX Daten an Controller übergeben AWT, Swing, JavaFX & SWT 3
D JavaFX Zugriff auf Controller erlangen AWT, Swing, JavaFX & SWT 4
W JavaFX Label in Controller-Klasse in einer anderen Controller-Klasse ändern AWT, Swing, JavaFX & SWT 9
B mouseOnEntered ( Controller richtig implementieren) AWT, Swing, JavaFX & SWT 4
S View-Komponenten im Controller bekannt machen AWT, Swing, JavaFX & SWT 7
G Swing MVC / View - Controller AWT, Swing, JavaFX & SWT 7
R Model View Controller Konzept AWT, Swing, JavaFX & SWT 2
F Element anzeigen / erstellen. Maus vs Controller AWT, Swing, JavaFX & SWT 7
J Swing MVC mit Java Swing, insbesondere die Controller-Struktur AWT, Swing, JavaFX & SWT 4
A Controller für RCP AWT, Swing, JavaFX & SWT 2
M Swing Von einem Controller aus View-Elemente ändern AWT, Swing, JavaFX & SWT 11
D Design - View & Controller AWT, Swing, JavaFX & SWT 2
R Checkboxen - Event mit Controller abfangen AWT, Swing, JavaFX & SWT 7
P Verbindung View und Controller AWT, Swing, JavaFX & SWT 3
F MVC --> was ist der Controller? AWT, Swing, JavaFX & SWT 2
F MVC: Update von View und Controller AWT, Swing, JavaFX & SWT 5
S MVC - Neues Frame, neue View, neuer Controller? AWT, Swing, JavaFX & SWT 3
C Model View Controller - Beispielimplementation AWT, Swing, JavaFX & SWT 5
M SWT und Model View Controller? AWT, Swing, JavaFX & SWT 8
B Observer Pattern JLabel ändern AWT, Swing, JavaFX & SWT 7
B JavaFX Pattern (Aufteilung Zuständigkeiten AWT, Swing, JavaFX & SWT 7
M Swing MVC-Pattern - View mit mehreren Models AWT, Swing, JavaFX & SWT 5
C Swing Daten in JTable wiedergeben per TableModel und MVC Pattern AWT, Swing, JavaFX & SWT 16
Cromewell JavaFX MVC-Pattern AWT, Swing, JavaFX & SWT 7
L JavaFX Java FX Anwendung nach MVC mit Observer Pattern AWT, Swing, JavaFX & SWT 15
3 2D-Grafik BasicStroke dash pattern - Linie zu lang!? AWT, Swing, JavaFX & SWT 1
M Welches Pattern bei GUI Anwendungen? AWT, Swing, JavaFX & SWT 2
lumo SWT Image Pattern AWT, Swing, JavaFX & SWT 5
M Swing MVC Pattern verstanden, aber Probleme bei der Umsetzung AWT, Swing, JavaFX & SWT 5
C GUI Entwicklung - welches Pattern? AWT, Swing, JavaFX & SWT 16
G Hilfe! Command Pattern an easy ImageViewer? AWT, Swing, JavaFX & SWT 13
D Wie mehrere Grafiken auf JPanel anzeigen lassen? (Observer pattern?) AWT, Swing, JavaFX & SWT 24
D MVC Pattern in Swing-Applikationen AWT, Swing, JavaFX & SWT 4
hdi Observer-Pattern bei JPanel nicht möglich? AWT, Swing, JavaFX & SWT 7
A MVC-Pattern - Kreuzweise Anwendung? AWT, Swing, JavaFX & SWT 4

Ähnliche Java Themen

Neue Themen


Oben