Das Verhalten ist für mich absolut unverständlich. Gerade beim Konstruktor ist sichergestellt, dass wir eine Instanz haben bzw. gerade dabei sind, eine zu machen, und dann wird kein static gebraucht.
Vorab: wie vermutet, ist die MyTableModel-Instanz, auf der die updateTable-methode aufgrufen wird, nicht die, die zum Aufbau einer sichtbaren JTable dient. Du legst nämlich in der checkUser-Methode immer eine neue MyTableModel-Instanz an, die am Ende der Methode nicht mehr gebraucht wird und bei der nächsten Gelegenheit vom gc abgeräumt werden sollte.
MainWindowModel ist m. E. kein Model, weil es keine Daten enthält. Es weisst das MyTableModel lediglich an, sich neue Daten aus der db zu holen, wäre also eher ein Controller.
Ich finde Verknüpfung von MainWindowModel, MainWindowView und MainWindowController nicht gut gelöst. Eine Idee hinter dem MVC Konzept ist es, die Komponenten austauschbar zu machen, ohne existierenden Code anfassen zu müssen, ohne in den Model, View und Controller-Klasse unnötig Overhead rumzuschleppen, und ohne dass sich die Komponenten untereinander zu gut kennen müssen. Formal sind in deinem Code zwar Model, View und Controller getrennt, aber die ganzen Querbezüge zwischen den Klassen schränken die Wartbarkeit und Wiederverwendbarkeit stark ein. Deine Controller-Klasse macht im Prinzip auch nichts weiter als der View einen ActionListener hinzuzufügen und je nach ActionCommand eine Aktualisierung der Tabelle zu veranlassen. Dabei bedient sich der Controller mehrerer Variablen aus der View-Klasse, die dafür nach aussen zugänglich sein müssen. Wenn du auf verschiedene ButtonEvents reagieren möchtest, musst du jedesmal sowohl die View als auch den Controller anfassen und dafür sorgen, dass die ActionCommands und die aufgerufenen Methoden konsistent sind. Bei so wenig Funktionalität im Controller bei gleichzeitig so vielen Querbezügen ist m. E. eine extra Controller-Klasse überflüssig, sondern die Auswertung des Buttonklicks kann einfach über einen anonymen ActionListener erfolgen. Leider sieht man häufig Code, wo eine View JFrame erweitert und ein paar Komponenten enthält, es einen Controller gibt, der auf eine Komponente der View zugreifen muss, und deshalb die View mit einem Getter für die Komponente ausgestattet wird und die View komplett an den Controller übergeben wird, der sich dann bei Bedarf über den getter die benötigte Komponente aus der View holt und auswertet, aber sowas finde ich höchst unschön. Mag sein, dass so eine Architektur auf den ersten Blick den Anforderungen des MVC Pattern genügt, aber praktikabel finde ich es absolut nicht.
Hier mal ein Beispiel, wie stark man den Code vereinfachen kann. Ist gerade in einem Editor runterschrieben und deshalb weder auf Kompilierbarkeit noch Lauffähigkeit getestet.
[code=Java]
public class MainWindowView extends JFrame {
/**
*
*/
private static final long serialVersionUID = 3690599372483360842L;
public static final String CHECKUSER = "CHECKUSER";
private JButton checkuserbutton = new JButton("Testen");
private JTextField username = new JTextField(10);//kein static!
private MyTableModel model = new MyTableModel()
private JTable nutzerrechtetabelle1 = new JTable(model);//Die MyTableModel-Instanz sollte nicht anonym sein, damit sie direkt zugänglich ist.
private JScrollPane scrollPane1 = new JScrollPane(nutzerrechtetabelle1);
private JScrollPane scrollPane2 = new JScrollPane(nutzerrechtetabelle2);//warum 2. JScrollPane??
//Konstruktor
public MainWindowView(MainWindowModel model) {
super();
JPanel content = new JPanel();
content.setLayout(new FlowLayout());
//Auslesen von Nutzerrechten
content.add(username);
content.add(checkuserbutton);
checkuserbutton.setActionCommand(CHECKUSER);
//ein anonymer ActionListener als Controller:
//Benutzereingaben werden ausgewertet und Änderung am Model ausgelöst.
checkuserbutton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
DatenbankDaoImpl db = new DatenbankDaoImpl();
model.updateTable(db);
}
});
this.setContentPane(content);
nutzerrechtetabelle1.setPreferredScrollableViewportSize(new Dimension(800, 100));
this.add(scrollPane1);
this.setExtendedState(JFrame.MAXIMIZED_BOTH);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
}
[/code]
Edit: hier mal ein Link zu einem Thread, wo ich mich schonmal zum Thema "Programmaufbau" geäussert habe: http://www.java-forum.org/thema/programmaufbau-in-ordnung-problem-mit-paintcomponent.176062/