# MVC Verständnisfrage (mehrere Views)



## Tiaclagear (23. Mai 2008)

Hallo,

habe mich etwas in MVC eingearbeitet, jedoch finde ich kein richtiges Beispiel, in welchem 2 oder mehr Views über ein Hauptmenü aufgerufen/gesteuert werden. Den View selber habe ich soweit glaube ich verstanden. Das Modell holt Daten (über DAO) aus einer Tabelle und der Controller reicht diese dann an den View weiter. 

Wie aber baue ich aber so etwas in ein Menü ein. 
Ich habe 2 Schaltflächen:

1. Schaltfläche ruft Dialog 1 für Tabelle 1 auf.
2. Schaltfläche ruft Dialog 2 für Tabelle 2 auf.

Rufe ich da nur den Controller auf und übergebe diesem den View oder wäre es besser, gleich noch das Model mit zu übergeben (dem Controller)?


Noch eine andere Frage. Wie löst man das, wenn man einen View hat aber dieser unterschiedlich aufgebaut werden soll.
Beispiel: Man hat 2 Kunden für einen View. 

Kunde 1 will nur die ersten 3 Felder der Tabelle A sehen und editieren. 
Kunde 2 will alle Felder der Tabelle A sehen und editieren.

Macht man für Kunde 2 einen extra View oder wird so etwas mit Abfragen in den View eingebaut?

Vielen dank schonmal.

MfG Tiaclagear


----------



## HLX (24. Mai 2008)

Tiaclagear hat gesagt.:
			
		

> Hallo,
> 
> habe mich etwas in MVC eingearbeitet, jedoch finde ich kein richtiges Beispiel, in welchem 2 oder mehr Views über ein Hauptmenü aufgerufen/gesteuert werden.


Der AnwendungsController erzeugt die Controller der jeweiligen Views, welche wiederum ihren View erzeugen. 



			
				Tiaclagear hat gesagt.:
			
		

> Den View selber habe ich soweit glaube ich verstanden. Das Modell holt Daten (über DAO) aus einer Tabelle und der Controller reicht diese dann an den View weiter.


 :toll: 



			
				Tiaclagear hat gesagt.:
			
		

> Wie aber baue ich aber so etwas in ein Menü ein.
> Ich habe 2 Schaltflächen:
> 
> 1. Schaltfläche ruft Dialog 1 für Tabelle 1 auf.
> ...


Das Modell solltest du im Controller erzeugen oder von anderen Controllern an den jeweiligen Untercontroller übergeben lassen. 



			
				Tiaclagear hat gesagt.:
			
		

> Noch eine andere Frage. Wie löst man das, wenn man einen View hat aber dieser unterschiedlich aufgebaut werden soll.
> Beispiel: Man hat 2 Kunden für einen View.
> 
> Kunde 1 will nur die ersten 3 Felder der Tabelle A sehen und editieren.
> ...


Nein, in Swing z.B. verwendet man dafür TableModels. Dabei ist zu beachten, dass es sich hier (obwohl Model im Namen steht) um eine GUI-Komponente handelt. Jede Änderung im Darstellungsmuster wird im TableModel dargestellt. Bei einem neuen Kunden weist du der Tabelle einfach sein TableModel zu oder du veränderst die Daten im TableModel anhand von Datenbankeinträgen.


----------



## Tiaclagear (26. Mai 2008)

Moin,

ah ok glaube habs verstanden.
Vielen Dank für deine Hilfe.

MfG Tiaclagear


----------



## Tiaclagear (26. Mai 2008)

Ich habe dies mal nun so umgesetzt:

Hauptcontroller (Menu)


```
public class Hauptcontroller implements ActionListener {

	private Hauptpanel panel;
	private ControllerTabelle1 con1;
	private ControllerTabelle2 con2;

	public Hauptcontroller() {

		panel = new Hauptpanel();

		panel.jButton.addActionListener(this);
		panel.jButton1.addActionListener(this);

	}

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

	public void actionPerformed(ActionEvent e) {

		if (e.getSource() == panel.jButton) {

			if (con1 == null) {
				con1 = new ControllerTabelle1();
			}

			panel.jPanel1.removeAll();
			panel.jPanel1.add(con1.dialog);
			panel.jPanel1.validate();
			con1.dialog.tabModel.fireTableDataChanged();
		}

		if (e.getSource() == panel.jButton1) {

			if (con2 == null) {
				con2 = new ControllerTabelle2();
			}

			panel.jPanel1.removeAll();
			panel.jPanel1.add(con2.dialog);
			panel.jPanel1.validate();
			con2.dialog.tabModel.fireTableDataChanged();
		}

	}
}
```

Das Menu


```
public class Hauptpanel extends JFrame {

	private javax.swing.JPanel jContentPane = null;

	private javax.swing.JPanel jPanel = null;
	public javax.swing.JPanel jPanel1 = null;
	public javax.swing.JButton jButton = null;
	public javax.swing.JButton jButton1 = null;

	/**
	 * This is the default constructor
	 */

	public Hauptpanel() {
		super();
		initialize();
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {

		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		this.setSize(712, 626);

		jButton = new javax.swing.JButton();
		jButton.setText("Dialog 1");

		jButton1 = new javax.swing.JButton();
		jButton1.setText("Dialog 2");

		jPanel1 = new JPanel();
		jPanel1.setBounds(109, 5, 589, 580);
		jPanel1.setBackground(new java.awt.Color(20, 153, 255));

		jPanel = new javax.swing.JPanel();
		jPanel.add(jButton, null);
		jPanel.add(jButton1, null);
		jPanel.setBounds(0, 0, 102, 592);
		jPanel.setBackground(new java.awt.Color(0, 153, 255));

		jContentPane = new javax.swing.JPanel();
		jContentPane.setLayout(null);
		jContentPane.add(jPanel1, null);
		jContentPane.add(jPanel, null);

		this.setContentPane(jContentPane);

		setVisible(true);

	}

}
```

Der Controller für die Dialoge (sind inhaltlich identisch)


```
public class ControllerTabelle1 implements ControllerInterface {

	private DAOTabelle1 daoBN;
	public Dialog1 dialog;

	public ControllerTabelle1() {

		dialog = new Dialog1();

		daoBN = new DAOTabelle1();

		this.dialog.button1.addActionListener(this);

	}

	public void actionPerformed(ActionEvent e) {
		try {
			Vector ergebnis = daoBN.selectAllRolle();

			for (int i = dialog.tabModel.getRowCount(); i > 0; i--)
				dialog.tabModel.removeRow(i - 1);

			for (int i = 0; i < ergebnis.size(); i++) {

				Tabelle1 rolle = (Tabelle1) ergebnis.get(i);

				this.dialog.tabModel.addRow(
					new String[] {
						rolle.getRoleID(),
						rolle.getRoleBez(),
						rolle.getErstelldatum().toString(),
						rolle.getAeTimestamp().toString(),
						rolle.getUser(),
						String.valueOf(rolle.getAeVersNr())});
			}

		} catch (SQLException e1) {
			e1.printStackTrace();
		} catch (Exception e1) {
			e1.printStackTrace();
		}

	}
}
```

Und der Dialog selber


```
public class Dialog1 extends JPanel {

	public JPanel hauptpanel;
	public JTable table;
	public JButton button1;
	public DefaultTableModel tabModel;

	public Dialog1() {

		init();

	}

	private void init() {

		hauptpanel = new JPanel();
		hauptpanel.setSize(500, 500);

		setLayout(new FlowLayout());

		table = new JTable();
		JScrollPane pane = new JScrollPane(table);

		button1 = new JButton("Anzeigen");

		add(pane);
		add(button1);

		tabModel =
			new DefaultTableModel(
				new String[] {
					"Rolle",
					"Bez",
					"Erstelldatum",
					"AE_Timestamp",
					"User",
					"VersNr" },
				0);

		table.setModel(tabModel);
	}
}
```

Ist dies so richtig umgesetzt oder könnte man noch etwas verbessern ?

MfG Tiaclagear


----------



## HLX (26. Mai 2008)

So wie ich das Beispiel verstehe, ändert sich bei der Auswahl eines Menüpunktes lediglich der Tabelleninhalt bzw. die Tabellenstruktur.

Dafür bräuchtest du lediglich einen einzigen Controller, der bei der Auswahl eines Menüpunktes die Daten lädt, diese in eine TableModel-Instanz packst und dann der JTable das TableModel über die Methode setModel zuweist. Schließlich hast du nur einen einzigen View, bei dem sich nur der Inhalt ändert.

Zwei Klassen mit identischem Code machen übrigens keinen Sinn. Solltest du aus irgendeinem Grund einen TabellenController benötigen, erstelle nur eine Klasse und mach diese parametrisierbar.


----------



## Tiaclagear (26. Mai 2008)

Dies war auch nur ein Beispiel um mich mit MVC vertraut zu machen.

Der eigentliche Aufbau der Dialoge soll mehr als nur eine Tabelle haben:

Oben - Textfelder für "Neu Anlegen" bzw "Ändern" eines Datensatzes
Mitte - eine Tabelle bzw. auch wieder Textfelder für die Anzeige der Datensätze
Unten - jeweilige Schaltflächen

Das ich mit dem TabellenController die JTables hinbekomme ist mir jetzt klar. Aber wie mache ich dies aber z.B.: für JTextfields oder JCheckBox ?

MfG Tiaclagear


----------



## HLX (26. Mai 2008)

Erstelle zunächst je View einen Controller (View = z.B. JFrame, JInternalFrame oder JDialog). Solltest du unterschiedliche Views durch Panels darstellen (z.B. durch Auswechseln des "Hauptpanels" im Frame, erstelle einen Controller je "HauptPanel". Die Controller behandeln alle Elemente ihres Views.

Controller müssen nicht zwingend von einem Listener abgeleitet sein, sie können auch mehrere Listener definieren.


----------

