# JPanel aktualisieren



## pope (20. Mrz 2009)

Ich stehe etwas am Berg

Ich möchte in einer update()-Funktion eine JTable in mein GUI einfügen/aktualisieren
Dazu wird im moment einfach eine neue Tabelle gezeichnet       

[highlight=Java]public void update() {
              String[] titel = {"Frequenz", "Re(Z)", "Img(Z"};
              String[][] datas = data.getMeasuresString();
              table = new JTable(datas, titel);
              frame.add(new JScrollPane(table));
}
[/highlight]
Ich möchte sie aber in ein Panel schreiben, das Panel also quasi updaten.
Gibt es da irgend eine geschickte Möglichkeit?
Am liebste wäre mir wenn ich die Tabelle komplett definieren könnte und einfach in der update Methode mit neuen Werten füllen, hab da aber nichts passendes gefunden

Was muss ich wo definieren und was muss ich wie updaten?


----------



## Hadernlump (20. Mrz 2009)

Schreib dir dafür am besten ein eigenes TableModel.  

Siehe:
http://www.java-forum.org/java-faq-beitraege/4841-jtable-ubersicht-teil-1-teil-8-a.html


----------



## pope (20. Mrz 2009)

werds mir mal durchlesen, danke


----------



## pope (20. Mrz 2009)

Also so wie ich das verstanden habe, hilft mir das Model meine Tabelle nach einem bestimmten Muster zu füllen.
Wenn ich nun meine Tabelle einfach neu zeichnen möchte müsste das ja gehen - zwar noch keine saubere Lösung, ist aber nur zu Testzwecken.

Was stört ihn wenn ich in der update()-methode einfach new JTable und panel.add(table) mache?


----------



## pope (24. Mrz 2009)

Ich habe mal den in Kapitel aufgeführten "einfachen Weg" etwas editiert.
Das sieht bei mir dann so aus:

data.getMeasuresString() gibt ein String[][] zurück

[highlight=Java]import javax.swing.table.AbstractTableModel;


class Model extends AbstractTableModel{

    private String[][] datas;


       public Model(DBController data){

        datas = data.getMeasuresString();

       }

       // Die Anzahl Columns
       public int getColumnCount() {
           return datas[0].length;
       }

       // Die Anzahl Rows
       public int getRowCount() {
           return datas.length;
       }

       // Die Titel der einzelnen Columns
       public String getColumnName(int column) {
        return "String";

       }

       // Der Wert der Zelle (rowIndex, columnIndex)
       public Object getValueAt(int rowIndex, int columnIndex) {

               return datas[ rowIndex ][ columnIndex ];


       }

       // Eine Angabe, welchen Typ von Objekten in den Columns angezeigt werden soll
       public Class getColumnClass(int columnIndex) {
        return String.class;
       }

       // Jede Zelle ist editierbar
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return true;
    }

    // Wird aufgerufen, falls der Wert einer Zelle verändert wurde
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {

                datas[ rowIndex ][ columnIndex ] = aValue.toString();

    }
}[/highlight]

Meine GUI.Java
[highlight=Java]
import java.awt.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import java.awt.event.*;
import java.io.*;
import java.io.IOException;
import javax.swing.table.DefaultTableModel;

public class GUI {

    public JTextArea input;
    public JTable table;
    public static DBController data = new DBController();
    public JPanel panelWest;
    public String[][] datas;
    Model model = new Model(data);
    JFrame frame = new JFrame("Datenbank");
    String[] titel = {"Frequenz", "Re(Z)", "Img(Z"};
    String[][] a = {{"a","b","c"},{"d","e","f"}};

    public GUI() {

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(new BorderLayout());

        input = new JTextArea("....");
        JButton open = new JButton("open file");
        JPanel panelNorth = new JPanel();
        JPanel panelWest = new JPanel();
        table = new JTable( model );
        table.setModel(new DefaultTableModel());
        JScrollPane pane = new JScrollPane(table);
        panelWest.add(pane);


        JPanel panelCenter = new JPanel();
        panelCenter.add(input);
        panelCenter.add(open);

        frame.add(panelNorth, BorderLayout.NORTH);
        frame.add(panelWest, BorderLayout.WEST);
        frame.add(panelCenter, BorderLayout.CENTER);


        open.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                //       DBController data = new DBController();
                try {
                    data.chooser();
                } catch (FileNotFoundException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                } catch (IOException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
                input.setText(data.getParameters());
                update();

            }
        });


        frame.setSize(600, 500);
        frame.setVisible(true);

    }


    //Diese Methode sollte die JTable table mit dem Inhalt data.getMeasuresString() füllen
    public void update() {

        table.setModel( model );


    }
}
[/highlight]
das ganze gibt mir aber eine NullPointerException beim compilieren, obwohl das Model erst bei actionevent eines Buttons aufgeruft werden soll. :rtfm:

Kann es sein dass er ein Problem hat dass
[highlight=Java]     Model model = new Model(data);[/highlight]

den NPE verursacht weil data.getMeasuresString(); noch leer ist?

Mir fehlt da Momentan etwas der Durchblick


----------



## Verjigorm (24. Mrz 2009)

Wenn du schon kein lauffähiges Programm postest, dann solltest du wenigstens den Stacktrace der Exception angeben


----------



## SlaterB (24. Mrz 2009)

beim Kompilieren tritt nie eine NullPointerException auf 

beim Ausführen aber, dann sollte aber auch ein StackTrace dabei sein, der die genaue Zeilennummer angibt,
hast du den nicht?!

ich vermute, das Problem liegt bei
> table = new JTable( model );
>  table.setModel(new DefaultTableModel());

also in der ersten Zeile davon, die zweite zitiere ich nur, weil es total komisch ist, der Tabelle erst ein Model zu geben und direkt danach ein anderes?!

bei der ersten Zeile wird die JTable jedenfalls beim Model getColumnCount() und getRowCount() usw abfragen,
wenn dann String[][] datas im Model null ist, siehts böse aus

-----

noch eine Anmerkung: wieso gibt es auch in der GUI-Klasse ein String[][] datas?
immer den Code sauber halten, Ordnung ist das halbe Leben

von  String[] titel + String[][] a ganz zu schweigen


----------



## pope (24. Mrz 2009)

Wie würde man das sauber lösen, die Tabelle zwar direkt initialisieren, von mir aus mit default werten füllen, und wenn dann die action performed aufgerufen wird erst mit den richtigen Daten füllen?
Ein ganzes Model nur um Daten einzulesen?


----------



## SlaterB (24. Mrz 2009)

kommt darauf an, was dein Programm überhaupt machen soll, wie es in bestimmten Situationen wie reagieren soll,

WAS dein Programm macht weiß ich nicht, erzählst du nicht, 
Sätze wie 'Ein ganzes Model nur um Daten einzulesen?' scheinen mir mit dem Thema wenig zielführend verknüpft,

wenn ich mich an meinen vorherigen Gedanken orientiere, dann haben wir da ein Model ohne Daten, welches auf eine JTable losgelassen wird,
das ist nicht ganz abwegig, falls erst später die Daten dazukommen,

dann muss man nur noch dafür sorgen, dass es in der Anfangsituation nicht zu einer Exception kommt, 
ist doch möglich:

public int getRowCount() {
           return datas.length;
       }
führt zu einer Exception, wenn datas null ist,

public int getRowCount() {
if (datas == null) {
return 0;
}
           return datas.length;
       }
macht dagegen keinen Ärger, Problem gelöst?
so könnte man alle Methoden reparieren,

Voraussetzung wäre allerdings, dass man NullPointerExceptions erkennen und interpretieren kann,
z.B. sich den StackTrace anschaut und so die genaue Zeile des Fehlers findet


----------

