Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Best PracticeAuf DefaultTableModel in andere Klasse zugreifen
Hallo,
ich habe eine Klasse MainWindow.java. Dort wird die grafische Oberfläche meines Programms erstellt und u.A. auch ein JTable mit einem DefaultTableModel definiert.
Zum Aktualisieren des Inhaltes des JTables nutze ich die Funktion:
Java:
updateCustomerTable()
Nun möchte ich gerne aus einem anderen aktiven Fenster diese Funktion zum Neuzeichnen des Tabelle aufrufen.
Abschnitte aus der MainWindow.java:
Java:
public void updateCustomerTable() throws SQLException
{
Vector<String> VecColumnName = new Vector<String>();
VecColumnName.add("ID:");
VecColumnName.add("Name:");
VecColumnName.add("Vorname:");
VecColumnName.add("Geb.-Datum:");
VecColumnName.add("Straße:");
VecColumnName.add("PLZ:");
VecColumnName.add("Stadt:");
VecColumnName.add("Email:");
VecColumnName.add("Telefon:");
VecColumnName.add("Handy:");
VecColumnName.add("Bemerkung:");
// Tabellengrundgerüst erstellen
tableCustomer = new JTable();
tableCustomer.setSelectionBackground(Color.darkGray);
tableCustomer.setAutoCreateRowSorter(true);
// Tabellenüberschrift formatieren
JTableHeader header = tableCustomer.getTableHeader();
header.setFont( header.getFont().deriveFont(16) );
// Instanz des DBHandler wird erstellt
DBHandler dbH = new DBHandler();
// Ergebnis der Datenbankabfrage wird in Vector geschrieben
Vector<Vector<String>> VecData = new Vector<Vector<String>>();
VecData = dbH.getCustomerData();
// Neues DefaultTableModel wird erstellt
DefaultTableModel model = (DefaultTableModel) tableCustomer.getModel();
// Ergebnisse der Datenbankabfrage werden mit Spaltenüberschrift in Tabelle geschrieben
tableCustomer.setModel(new DefaultTableModel(VecData, VecColumnName));
scrollPaneCustomer.setViewportView(tableCustomer);
// Tabelle neu zeichnen
model.fireTableDataChanged();
}
Wie ist hierbei die beste practise?
Eine neue Instanz der MainWindow fällt raus, da hier dann wieder eine neue grafische Oberfläche erstellt wird. Ein statischer Zugriff ist ebenfalls nicht zu empfehlen.
public class Foo{
private MainClass main = null;
public Foo(MainClass main){
this.main = main;
}
// main.updateCustomerTable();
}
Wobei deine Methode keine updateMethode ist denn du erstellst immer wieder ein neues model und einen neuen table.
wenn du updaten / refreshen willst dann solltest du nur die daten neu holen und dem model übergeben.
Ich rufe das neue Fenster aus dem ich den Befehl an das Hauptfenster für das Neuzeichnen der Tabelle schicke, mittels ActionListener auf. Momentan sieht der Aufruf so aus:
Java:
CustomerWindow cw = new CustomerWindow();
cw.initWindow();
Auf der CustomerWindow.java Seite sieht es an entsprechender Seite aus:
Java:
public class CustomerWindow extends JDialog {
private final JPanel contentPanel = new JPanel();
private MainWindow main = null;
public void initWindow(MainWindow main){
this.main = main;
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
setVisible(true);
}
Welchen Übergabeparameter muss ich beim Funktionsaufruf aus der MainWindow.java übergeben?
Hallo
Man kann zwar eine Referenz übergeben, das ist auch sicher einfacher hat aber den Nachteil das dein Customer Window nicht mehr in Anderen Klassen verwendet werden kann welche dein MainWindow nicht kennen.
Meiner Meinung nach ist es besser und auch richtiger hier einen Listener bzw Callback zu verwenden. Du könntest z.B. einen PropertyChangeListener von Swing verwenden oder deinen eigenen Callback implementieren.
Hier ein kleines Beispiel wie sowas mit dem PropertyChangeListener geht.
Java:
package callback;
import callback.Gui.MainFrame;
import javax.swing.*;
public class App {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new MainFrame());
}
}
In der MainFrame Klasse wird der Listener implementiert und wenn die Property mit dem richtigen Namen kommt dann wird die UpdateMethode aufgerufen. Das Implementierte Interface wird der CustomerDialog Klasse jedesmal hinzugefügt wenn diese Initialisiert wird.
Java:
package callback.Gui;
import javax.swing.*;
import java.awt.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
public class MainFrame extends JFrame implements PropertyChangeListener {
public MainFrame() throws HeadlessException {
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setLayout(new FlowLayout());
setSize(500, 800);
setLocationRelativeTo(null);
setTitle("Callback Demo");
setVisible(true);
JButton buttonOpen = new JButton("Open");
buttonOpen.addActionListener(e -> onOpenAction());
add(buttonOpen);
}
private void onOpenAction() {
CustomerDialog cd = new CustomerDialog(this,"Customer Dialog", false);
cd.addPropertyChangeListener("testProperty", this);
cd.setVisible(true);
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals("testProperty")){
updateTable();
}
}
private void updateTable() {
System.out.println("MainFrame.updateTable");
}
}
In der CustomerDialog Klasse wird beim drücken des Buttons Action ein Event erzeugt welcher dann in der MainWindow Klasse ausgewertet wird.
Java:
package callback.Gui;
import javax.swing.*;
import java.awt.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
public class MainFrame extends JFrame implements PropertyChangeListener {
public MainFrame() throws HeadlessException {
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setLayout(new FlowLayout());
setSize(500, 800);
setLocationRelativeTo(null);
setTitle("Callback Demo");
setVisible(true);
JButton buttonOpen = new JButton("Open");
buttonOpen.addActionListener(e -> onOpenAction());
add(buttonOpen);
}
private void onOpenAction() {
CustomerDialog cd = new CustomerDialog(this,"Customer Dialog", false);
cd.addPropertyChangeListener("testProperty", this);
cd.setVisible(true);
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals("testProperty")){
updateTable();
}
}
private void updateTable() {
System.out.println("MainFrame.updateTable");
}
}