Saubere Trennung Model, View, Controller Javafx

Jamil

Mitglied
Nachdem mir Joreyk den Tipp gegeben hat die View in einer separaten Klasse zu verwalten, habe ich es versucht umzusetzen und es funktioniert. Allerdings frage ich mich, ob meine Umsetzung stilistisch in Ordnung ist, oder ob man doch noch was ändern muss.

Zunächst eine grafische Darstellung des Programmabschnitts, um die es hier gehen soll:

listStage1.png

Hier der Code der Klasse MyView:
(ich habe die buttons und textfields in ner ArrayList verpackt, um den externen Zugriff zu erleichtern.)

Java:
public class MyView{
private ObservableList<String> listFr = FXCollections.observableArrayList();
     private ListView<String> frenchList;
     private ObservableList<String> listDe = FXCollections.observableArrayList();
     private ListView<String> germanList;
     private ArrayList<TextField> txtFldList;
     private ArrayList<Button> btnList;
      
     private final String NAME_LIST_TXTFLD[] = {"sheed name", "file name", "in french", "in german", "search a word"};
     private final String NAME_LIST_BTN[] = {"export list", "safe", "search", "delete","delete list", "exit"};      
     private Text displayedText;
    
     public MyView() {        
        frenchList  = new ListView<>(listFr);
        germanList = new ListView<>(listDe);
        txtFldList = new ArrayList<>();
        btnList = new ArrayList<>();        
    }
    public Scene setView(){
            
            controler = new Text("Click on the List \nor write the word");
            VBox vBox = new VBox();
            HBox hBoxBtnList = new HBox();
            HBox hBoxTxtFldList = new HBox();
            HBox hBox3 = new HBox(displayedText);
            HBox hBoxListContainer = new HBox(new VBox(new Label("Liste Deutsch:"), germanList), new VBox(new Label("Liste foreign language:"), frenchList));
            
            germanList.getStyleClass().add("listDe");
            frenchList.getStyleClass().add("listFr");
            germanList.setPrefSize(450, 550);
            frenchList.setPrefSize(450, 550);
            
            vBox.getChildren().addAll(hBoxBtnList,hBoxTxtFldList,hBox3,hBoxListContainer);
            
            for(String btnName : NAME_LIST_BTN ) {
                Button btn = new Button(btnName);
                btnList.add(btn);
                hBoxBtnList.getChildren().add(btn);
            }
            
            for(String txtFldName : NAME_LIST_TXTFLD) {
                TextField txtFld = new TextField();
                txtFld.setPromptText(txtFldName);
                txtFld.getStyleClass().add("textfield");
                txtFldList.add(txtFld);
                hBoxTxtFldList.getChildren().add(txtFld);    
            }
            for(int i = 0; i < vBox.getChildren().size(); i++) {
                vBox.getChildren().get(i).getStyleClass().add("hbox" + String.valueOf(i+1));
            }
            
            hBoxBtnList.getChildren().get(0).getStyleClass().add("first-btn");
            displayedText.getStyleClass().add("text1");
            vBox.getStyleClass().add("vbox");
            
            
            // click on the List item in order to delete them
            frenchList.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
            germanList.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);    

            Scene scene = new Scene(vBox, 900, 600);
            scene.getStylesheets().add(getClass().getResource("stylesheet2.css").toExternalForm());
            return scene; 
    }
    public ObservableList<String> getStringListDe() {
        return listDe;
    }
    public ObservableList<String> getStringListFr() {
        return listFr;
    }
    public ListView<String> getListViewFr() {
        return frenchList;
    }
    public ListView<String> getListViewDe() {
        return germanList;
    }
    
    public Button getButton(int index) {    
        return btnList.get(index);
    }
    public String getTxt(int index) {
        return txtFldList.get(index).getText();
    }    
    public TextField getTxtField(int index) {
        return txtFldList.get(index);      
    }
    public void clearTxtfldDeFr() {
          txtFldList.get(3).clear();
          txtFldList.get(2).clear();       
        }
    public Text getControler() {
      return displayedText;
    }
}

Und hier ein kleiner Abschnitt wie ich die View im Anschluss funktionalisiert habe
Java:
public class ListStage { 
  private ExportList exportList;
  private MyView myView;
  private Stage stage;
  public ListStage() {
      myView = new MyView();
      stage = new Stage();
  }
  
  public void start() {
   
    Scene scene = myView.setView();
    myView.getButton(0).setOnMouseClicked(e1 -> exporter());
    myView.getButton(1).setOnMousePressed(e2 -> safe());
    myView.getButton(2).setOnMouseClicked(e3 -> search());
    myView.getButton(3).setOnMouseClicked(e4 -> delete());
    myView.getButton(4).setOnMouseClicked(e5 -> deleteAll());
    myView.getButton(5).setOnMousePressed(e5 -> exit());
    
    // delete items by clicking on the list
    myView.getListViewDe().setOnMouseClicked(e6 -> clickOnTheList(e6));  
    myView.getListViewFr().setOnMouseClicked(e7 -> clickOnTheList(e7));
    
    // switch from french-textfield to german-textfield and safe the new Word by pressing ENTER
    myView.getTxtField(2).setOnKeyPressed(e8 -> switchTxtFieldsFrDe(e8));
    myView.getTxtField(3).setOnKeyPressed(e9 -> switchTxtFieldsDeFr(e9));
     
    stage.setMinWidth(790.0);
    stage.setScene(scene);
    stage.show();
  }

Irgendwie soll man da auch noch einen "Controler" unterbringen. Man müsste folglich das Programm in 3 Abschnitte unterteilen. Könnte man das so verstehen, dass falschangaben vom Controler abgefangen werden? Sollte ich eine Controler class hinzufügen?[/SIZE]
 
Zuletzt bearbeitet von einem Moderator:

Jamil

Mitglied
Hm ok. Ich erstelle mir also eine Klasse Model, welche vom Controller mit Informationen versorgt wird, die dann im Model verarbeitet werden. Sobald das erledigt ist, wird im Anschluss der Input vom Model zurück zum Controller oder direkt zur View geschickt?
 

Jamil

Mitglied
Danke, ich hab dieses Schema aus dem Vorlesungsfolien übernommen.

MVC.png


Der Controller kennt das Model und das Model returned back den Value

Controller:
Java:
public void safe() {  
        
        if (myView.getTxt(2).isEmpty() || myView.getTxt(3).isEmpty()) {
            myView.getControler().setText("a word missing");
            
        }else {
            String displayedText = model.setNewListItem(myView.getStringListDe(),myView.getTxtField(3), myView.getStringListFr(), myView.getTxtField(2));
            myView.getControler().setText(displayedText);
        } 
    }

Model:
Java:
public class Model {

    public String setNewListItem(ObservableList<String> stringListDe, TextField textFieldDe,ObservableList<String> stringListFr, TextField textFieldFr) {
        String newWordDe = String.valueOf(stringListDe.size()) + ". " + textFieldDe.getText();
        String newWordFr = String.valueOf(stringListFr.size()) + ". " + textFieldFr.getText();
        stringListDe.add(newWordDe);
        stringListFr.add(newWordFr);
        
        clearTxtflds(textFieldDe, textFieldFr);
        textFieldFr.requestFocus();
        String displayedText = "Word has been added";
        return displayedText;
    }
    
    private void clearTxtflds(TextField textField1, TextField textField2) {
        textField1.clear();
        textField2.clear();
    }
}
 
Zuletzt bearbeitet von einem Moderator:

mrBrown

Super-Moderator
Mitarbeiter
wichtige Grundregel dabei: das Model weiß nichts über die View, es muss nicht mal wissen, dass überhaupt eine existiert.
In deinem Model kennt das Model aber Text-Felder, das sollte nicht so sein
 

Jamil

Mitglied
Also eine Trennung von der View könnte, wenn ich nicht falsch liege, so aussehen. Jedoch
ist das kein MVC sondern MVVC. Ist das die richtige Herangehensweise?
mvvc.png

hab nochmal die Vorlesungsfolien von mihe7 überflogen und diesen Code Schnipsel gefunden

mvvc2.png
 
Zuletzt bearbeitet:

mrBrown

Super-Moderator
Mitarbeiter
MVVM ist eine Abwandlung von MVC, die Beziehungen vom Model zum Rest sind in beiden Modellen identisch :)


Um mal näher an deinem Problem zu bleiben: das Model (das Konzept, nicht eine konkrete Klasse) ist in deinem Fall ja eine Liste von Wörtern und deren Übersetzungen. Der Liste kann man vermutlich Wörter hinzufügen (und potentiell auch löschen, ich nehm das einfach mal an).

Das ganze könnte man zB in einer Klasse "Wörterbuch" darstellen, intern hält ein Wörterbuch eine Liste von Einträgen, und nach außen bietet es Methoden zum Abfragen aller Wörter und zum Hinzufügen bzw. Löschen von Einträgen an.
Außerdem ist das Model "Beobachtbar", zB mit Observer- oder Listener-Pattern, und wenn Wörter hinzugefügt oder gelöscht werden, werden die Beobachter darüber informiert.


Die View würde dann ein "Wörterbuch" bekommen und dieses beobachten. Zum Anzeigen würde sie die Einträge des Wörterbuchs abfragen, und wenn sie über Änderungen informiert sind, aktualisiert sie die Abfrage.
Der Controller würde sich dagegen bei der View "registrieren" und sich über "Aktionen" innerhalb dieser informieren lassen, zB Klicks auf Buttons.

Wenn in der View jetzt was in Textfelder eingegeben wird, und dann die Eingabe mit einem Klick auf den Button bestätigt wird, löst der Beton-Klick eine Methode im Controller aus. Der Controller würde dann die Textfelder abfragen (sich also die Daten aus der View holen) und mit den Daten die "Hinzufügen-Funktion" des Wörterbuchs aufrufen. Das Wörterbuch aktualisiert sich dann und informiert die Beobachter. Beobachter ist in dem Fall nur die View, diese aktualisiert sich daraufhin.
 

Jamil

Mitglied
Super, vielen Dank euch :) . Ich denke, dass ich das Prinzip von MVC und die Umsetzung nun verstanden habe. Zumindest konnte ich mein Projekt grundlegend verbessern. Ich hab die View komplett auslagern können und auch den Controller schön unterbringen können, was den Code in allen 3 Klassen viel lesbarer gemacht hat. Jetzt brauche ich nur noch ein wenig Übung, damit mir die Trennung der Programmabschnitte ohne großem Zeitaufwand gelingt. Wobei ich mir auch nochmal die Observable und Listener-Konzepte genauer anschauen muss.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
H Swing Saubere Erstellung einer Tabelle AWT, Swing, JavaFX & SWT 3
F JList und saubere Programmierung AWT, Swing, JavaFX & SWT 4
D Swing Trennung der UI- und Persistenz-Schicht AWT, Swing, JavaFX & SWT 1
A Trennung GUI und Funktion AWT, Swing, JavaFX & SWT 5
J prinzipielles verständnis für Oberfläche/Code-trennung AWT, Swing, JavaFX & SWT 5
O Trennung GUI / Funktionalität AWT, Swing, JavaFX & SWT 3
F Zugriff auf Oberfläche bzw Trennung GUI / Logik AWT, Swing, JavaFX & SWT 3
K Trennung von GUI und Logik AWT, Swing, JavaFX & SWT 6
G Korrekte Trennung von GUI, Logik und Event nach MVC AWT, Swing, JavaFX & SWT 5
D Trennung des Event-Handling von der GUI AWT, Swing, JavaFX & SWT 4
D Trennung von Programm und Oberfläche AWT, Swing, JavaFX & SWT 3
O Trennung Gui und Anwendungslogik AWT, Swing, JavaFX & SWT 13
O Trennung Gui und Logik - Strukturierte Client Anwendung AWT, Swing, JavaFX & SWT 4
C Default table model aktualisieren AWT, Swing, JavaFX & SWT 7
A ViewController (IFrame) > Jdialog > Model AWT, Swing, JavaFX & SWT 1
F JComboBox und Model AWT, Swing, JavaFX & SWT 10
S UI Model Binding AWT, Swing, JavaFX & SWT 7
F jTree und das Model aus einer eigenen Klasse AWT, Swing, JavaFX & SWT 1
ralfb1105 JavaFX Exception Message von Model Class via Controller in View darstellen AWT, Swing, JavaFX & SWT 39
ralfb1105 JavaFX MVC: Thread in Model Class mit Ausgabe in TextArea AWT, Swing, JavaFX & SWT 10
B JavaFX mvvmfx - Model AWT, Swing, JavaFX & SWT 3
J JavaFX - mehrere Views, Model durchreichen AWT, Swing, JavaFX & SWT 10
T JavaFX Model Daten übergeben AWT, Swing, JavaFX & SWT 4
S Zwei JTree, ein Model, bei Selection im ersten JTree soll der zweite die Inhlate anzeigen AWT, Swing, JavaFX & SWT 2
M JList Model filtern AWT, Swing, JavaFX & SWT 4
O Swing JTextField Sync View -> Model AWT, Swing, JavaFX & SWT 3
S Swing Tabelle mit Model bei eingeschaltetem Filter synchronisieren AWT, Swing, JavaFX & SWT 6
P jTable model setzen AWT, Swing, JavaFX & SWT 6
D SWT TreeViewer: Daten aus Model gelöscht... trotzdem noch im Baum AWT, Swing, JavaFX & SWT 4
F Swing GUI und Model mit Timer AWT, Swing, JavaFX & SWT 13
earlgrey_tea JTextfield Model AWT, Swing, JavaFX & SWT 14
L Swing Model für ComboBox AWT, Swing, JavaFX & SWT 14
O Swing JTable - Zeilen färben (mit Model) AWT, Swing, JavaFX & SWT 13
C Swing JTable verbindet sich nicht mit Model AWT, Swing, JavaFX & SWT 20
D Swing JList <-> AdapterModel <-> Model AWT, Swing, JavaFX & SWT 4
C Swing MVC Verbindung von Model und Db AWT, Swing, JavaFX & SWT 23
R Model View Controller Konzept AWT, Swing, JavaFX & SWT 2
N update model nach dem filtern AWT, Swing, JavaFX & SWT 2
R Swing Designfrage - Zusammenspiel Model / View AWT, Swing, JavaFX & SWT 10
D Swing JList, CellRenderer und Model AWT, Swing, JavaFX & SWT 6
J Swing SwingActions und das Problem auf den View bzw. das Model zuzugreifen AWT, Swing, JavaFX & SWT 2
K Swing JTable Model aktualisieren AWT, Swing, JavaFX & SWT 2
C Swing JComboBox probleme bei Set Model AWT, Swing, JavaFX & SWT 5
T JTable Model AWT, Swing, JavaFX & SWT 5
D Swing JTable Model View Problem AWT, Swing, JavaFX & SWT 6
F unspezifizierte Frage zu JTable/ Model AWT, Swing, JavaFX & SWT 6
D ComboBox-Model mit Observer AWT, Swing, JavaFX & SWT 3
M Swing Model an View binden AWT, Swing, JavaFX & SWT 4
R Zugriff auf Model im MVC-Design aus SwingWorker heraus AWT, Swing, JavaFX & SWT 3
Z JLIST / Model erster EINTRAG AWT, Swing, JavaFX & SWT 11
G Model,Listener und background jobs AWT, Swing, JavaFX & SWT 4
X Swing JList -> Daten anders darstellen als im Model hinterlegt -> möglich ? AWT, Swing, JavaFX & SWT 9
N Model Aktualisieren AWT, Swing, JavaFX & SWT 4
N Swing JComboBox: Auf Model- und Selectionänderungen reagieren AWT, Swing, JavaFX & SWT 2
D JTable, Model, Fokus AWT, Swing, JavaFX & SWT 3
hdi Swing JTable: Löschen vom Daten im Model AWT, Swing, JavaFX & SWT 7
R Swing alle Frames nutzen das gleiche Model AWT, Swing, JavaFX & SWT 2
S JList mit Vector als Model? AWT, Swing, JavaFX & SWT 12
S JTree mit Daten aus Model füllen, eigenes TreeModel (gute Dokumentation des Problems) AWT, Swing, JavaFX & SWT 2
J JTable Model laesst sich nicht serialisieren? AWT, Swing, JavaFX & SWT 16
D ComboBox(Model) mit dummyItem AWT, Swing, JavaFX & SWT 10
G JComboBox mit eigenem Model vorhanden, wie selektieren AWT, Swing, JavaFX & SWT 29
M MVC: Grundidee verstanden aber was machen mit mehreren Model AWT, Swing, JavaFX & SWT 2
V JList ist leer -Model ist voll. Ja, ne is klaaa. AWT, Swing, JavaFX & SWT 8
K JSpinner - Model <-> View, unterschiedliche Werte AWT, Swing, JavaFX & SWT 9
W Suche großes vollständiges Swing GUI Beispiel nach MVC Model AWT, Swing, JavaFX & SWT 5
P jTable mit Model lässt sich nicht neu laden AWT, Swing, JavaFX & SWT 5
P JTable/Model füllen mit Fortschrittsbalken, Var. Rückgabetyp AWT, Swing, JavaFX & SWT 2
J model von jcombobox AWT, Swing, JavaFX & SWT 4
D Swing und MVC und doppeltes Model? AWT, Swing, JavaFX & SWT 5
G JTable und Model AWT, Swing, JavaFX & SWT 21
B View zeichnet Daten aus dem Model ohne Update AWT, Swing, JavaFX & SWT 4
J JTable / Model Daten verändern AWT, Swing, JavaFX & SWT 5
C Model View Controller - Beispielimplementation AWT, Swing, JavaFX & SWT 5
C [JTable] ArrayIndexOutOfBoundsException im Model AWT, Swing, JavaFX & SWT 8
Icewind Jlist zeigt neue elemente im model nicht sofort an AWT, Swing, JavaFX & SWT 3
Icewind JTable zeigt neue elemente im model nicht sofort an AWT, Swing, JavaFX & SWT 3
G Neues Model für JTextField erstellen AWT, Swing, JavaFX & SWT 8
A Gemeinsames Model für Baum- und Graphdarstellung-wie gehts? AWT, Swing, JavaFX & SWT 9
S Frage zu Table(Column)Model AWT, Swing, JavaFX & SWT 3
H Model umbauen ? AWT, Swing, JavaFX & SWT 5
M SWT und Model View Controller? AWT, Swing, JavaFX & SWT 8
J Table Model AWT, Swing, JavaFX & SWT 2
J Abstract Table Model AWT, Swing, JavaFX & SWT 7
D Model Listener beim JTree AWT, Swing, JavaFX & SWT 5

Ähnliche Java Themen

Neue Themen


Oben