Il pattern MVC (in Java in questo esempio) è un modello di architettura del software molto utilizzato nella programmazione orientata agli oggetti e in quella per il web. È composto da tre parti il model, la view e il controller.
Il model gestisce i dati e la logica dell’applicazione, la view è la rappresentazione o le rappresentazioni grafiche delle informazioni ed il controller si occupa degli input dell’utente modificando il comportamento del model e della view.
Ho creato una semplicissima app per salvare delle note di testo in un file in formato csv
.
Model
Il model è rappresentato dalla classe Note.java
che rappresenta la nota
package spacecoding.patterns.mvc.model;
import java.io.Serializable;
public class Note implements Serializable {
private String title;
private String body;
private int priority;
public Note(String title,String body,int priority){
this.title=title;
this.body=body;
this.priority=priority;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public int getPriority() {
return priority;
}
public void setPriority(int priority) {
this.priority = priority;
}
}
View
Le view è rappresentata da un JFrame
SWING con i seguenti componenti: JPanel
, JTextField
, JTextArea
e JButton
. Il layout adottato è il BorderLayout
e gli elementi sono disposti nel seguente modo:

La classe NoteWindow.java
package spacecoding.patterns.mvc.view;
import javax.swing.*;
import java.awt.*;
public class NoteWindow {
private JFrame frm;
private JPanel pnl;
private JButton btnSaveNote;
private JTextField txtTitle;
private JTextArea txtNote;
public NoteWindow(){
frm=new JFrame("Java Note");
pnl=new JPanel();
txtTitle=new JTextField();
txtTitle.setBounds(100,0,300,30);
txtNote=new JTextArea();
txtTitle.setText("");
txtNote.setText("");
btnSaveNote=new JButton("Save");
pnl.setLayout(new BorderLayout());
pnl.add(txtTitle,BorderLayout.NORTH);
pnl.add(txtNote,BorderLayout.CENTER);
pnl.add(btnSaveNote,BorderLayout.SOUTH);
frm.setContentPane(pnl);
frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frm.setSize(400,600);
frm.setVisible(true);
}
public JFrame getFrm() {
return frm;
}
public JPanel getPnl() {
return pnl;
}
public JButton getBtnSaveNote() {
return btnSaveNote;
}
public JTextField getTxtTitle() {
return txtTitle;
}
public JTextArea getTxtNote() {
return txtNote;
}
}
Nota che la classe non agisce direttamente sui dati ma oltre a fare il setup dei componenti SWING ha dei metodi getters
per restituire i componenti stessi ad una classe chiamante.
Controller
Il controller preleverà i dati dalla vista e li memorizzerà grazie alla classe FileWriter
nel nostro file csv notes.csv
.
Viene controllato se il contenuto della nota è vuoto, in quel caso grazie ad un JOptionPane
comunicheremo all’utente che non può essere salvata (non avrebbe senso logico). Nel caso solo il titolo della nota fosse vuoto verrà usato un titolo di default SENZA NOME. A salvataggio terminato utilizzeremo ancora il JOptionPane
per comunicare all’utente il successo nell’operazione di memorizzazione.
La classe Controller.java
package spacecoding.patterns.mvc.controller;
import spacecoding.patterns.mvc.model.Note;
import spacecoding.patterns.mvc.view.NoteWindow;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class Controller implements ActionListener {
private NoteWindow noteWindow;
private JDialog dialog;
private String noteTitle;
private String noteBody;
private File notes;
private FileWriter fileWriter;
private Note note;
public Controller(NoteWindow noteWindow){
this.noteWindow=noteWindow;
this.noteWindow.getBtnSaveNote().addActionListener(this);
notes=new File("notes.csv");
note=new Note();
}
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource()==noteWindow.getBtnSaveNote()){
JLabel lblDialog=new JLabel("La nota è vuota non può essere salvata");
System.out.println("Save Button clicked");
note.setTitle(noteWindow.getTxtTitle().getText());
note.setBody(noteWindow.getTxtNote().getText());
System.out.println(note.toString());
if(note.getBody().equals("")){
JOptionPane.showMessageDialog(noteWindow.getFrm(),"La nota è vuota");
}else{
if(note.getTitle().equals("")){
noteTitle="SENZA NOME"+";";
}else{
noteTitle=note.getTitle()+";";
}
noteBody=note.getBody();
try {
try {
fileWriter=new FileWriter(notes,true);
} catch (IOException ex) {
throw new RuntimeException(ex);
}
fileWriter.write(noteTitle);
fileWriter.write(noteBody);
fileWriter.write("\n");
JOptionPane.showMessageDialog(noteWindow.getFrm(),"Nota salvata con successo");
fileWriter.flush();
fileWriter.close();
noteWindow.getTxtTitle().setText("");
noteWindow.getTxtNote().setText("");
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
}
}
}
In questa prima versione della app ho voluto mantenere le cose in modo semplice, elementare per concentrarci su come comunicano la view, il controller e il model.
Classe entry-point Main.java
per avviare le componenti dell’applicazione
package spacecoding.patterns.mvc;
import spacecoding.patterns.mvc.controller.Controller;
import spacecoding.patterns.mvc.view.NoteWindow;
public class Main {
public static void main(String[] args) {
NoteWindow noteWindow=new NoteWindow();
Controller controller=new Controller(noteWindow);
}
}
Utilizzando questo esempio si possono successivamente implementare altre funzionalità.
Link utili