JPanel mit zwei Methoden her beschreiben.

fhaslbs

Mitglied
Hallo zusammen
Ich mache gerade meine ersten Gehversuche mit der GUI Programmierung. Ich erzeuge ein GUI in der main() Methode. Sobald ein Button gedrückt wird, soll via ActionListener eine Tabelle in das JPanel herein kommen... Doch wenn ich den Button drücke bekomme ich eine NullPointerException...

Da ich bis jetzt noch nie GUIs oder Objektorierntiert programmiert habe wäre ich Dankbar für jede Hilfe🙂
Java:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;
import java.util.Scanner;
import javax.swing.*;

public class zinsrechner {
	// JFRAME GENERIEREN
	static JFrame frame;
	
	// JPANEL FÜR TABELLE GENERIEREN.
	static JPanel tabbut;
	
	// TEXTFELDER GENERIEREN
	static JTextField tf_zinssatz = new JTextField("", 10);
	static JTextField tf_kapital = new JTextField("", 10);

	// BUTTONS GENERIEREN
	static JButton button;

	// VARIABLEN GENERIEREN
	static double zinssatz;
	static double kapital;

	// JTABLE GENERIEREN
	static JTable table;

	public static void main(String[] args) {
		// FENSTER ERZEUGEN UND TITEL SETZEN
		JFrame frame = new JFrame();
		frame.setTitle("Zinsrechner");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setBackground(new Color(0, 0, 0));

		// INFORMATIONSFELDER ERZEUGEN
		Label tf_zinssatz_inf = new Label("Bitte Zinssatz in % hier Eingeben");
		tf_zinssatz_inf.setForeground(new Color(255, 255, 255));
		Label tf_kapital_inf = new Label("Bitte Startkapital in CHF Eingeben");
		tf_kapital_inf.setForeground(new Color(255, 255, 255));

		// LAYOUT MANAGER HINZUFÜGEN
		frame.setLayout(new BorderLayout());

		// JPANEL FÜR KAPITAL
		JPanel kapitalpanel = new JPanel();
		kapitalpanel.setLayout(new BorderLayout());
		kapitalpanel.add(tf_kapital_inf, BorderLayout.NORTH);
		kapitalpanel.add(zinsrechner.tf_kapital, BorderLayout.SOUTH);

		// JPANEL FÜR ZINSSATZ
		JPanel zinssatzpanel = new JPanel();
		zinssatzpanel.setLayout(new BorderLayout());
		zinssatzpanel.add(tf_zinssatz_inf, BorderLayout.NORTH);
		zinssatzpanel.add(zinsrechner.tf_zinssatz, BorderLayout.SOUTH);

		// START BUTTON HINZUFÜGEN
		JButton button = new JButton("Berechnen!");
		button.setBackground(new Color(0, 255, 0));
		button.setForeground(new Color(255, 0, 255));

		// ACTIONLISTENER FÜR BUTTON HINZUFÜGEN
		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				buttonStartClicked();

			}
		});

		// JPANEL KAPITAL UND JPANEL INFO ZUSAMMENSCHMEISSEN
		JPanel inffeld = new JPanel();
		inffeld.add(kapitalpanel, BorderLayout.NORTH);
		inffeld.add(zinssatzpanel, BorderLayout.SOUTH);

		// JPANEL FÜR TABELLE UND BUTTON
		zinsrechner.tabbut = new JPanel();

		tabbut.add(button, BorderLayout.SOUTH);

		// KOMPONENTEN IN FENSTER PACKEN
		frame.add(inffeld, BorderLayout.NORTH);
		frame.add(tabbut, BorderLayout.SOUTH);

		frame.pack();
		frame.setVisible(true);
	}

	// METHODE DIE AUSGEFÜHRT WIRD SOBALD BERECHNEN BUTTON GEKLICKT WIRD
	public static void buttonStartClicked() {

		// STRINGS AUS TEXTFELDERN HOLEN...
		String zinsstring = tf_zinssatz.getText();
		String kapitalstring = tf_kapital.getText();

		// ... UND IN DOUBLES PARSEN
		zinsrechner.zinssatz = Double.parseDouble(zinsstring);
		zinsrechner.kapital = Double.parseDouble(kapitalstring);
		
		// TABELLEN TITEL SETZEN, INHALT HOLEN
		String uberschrift[] = new String[] { "Zeitpunkt", "Kapital" };
		String Table[][];

		Table = rechnung(zinsrechner.zinssatz, zinsrechner.kapital);

		// TABELLE HINZUFÜGEN
		JTable table = new JTable(Table, uberschrift);
		table.setBackground(new Color(255, 215, 0));
		table.setForeground(new Color(0, 0, 0));
		
		tabbut.add(zinsrechner.table, BorderLayout.NORTH);

	}

	// METHODE DIE DIE GANZE RECHNUNG DURCHFÜHRT. GIBT DEN ZWEIDIMENSIONALEN
	// ARRAY FÜR DIE TABELLE ZURÜCK
	public static String[][] rechnung(double zinssatz, double kap0) {

		kap0 = zinsrechner.kapital;
		double kap1 = 0;
		double kap2 = 0;
		double kap3 = 0;
		double kap4 = 0;
		double kap5 = 0;

		DecimalFormat df = new DecimalFormat("0.00");

		for (int i = 1000; i <= 6000; i = i + 1000) {
			kap0 = i;
			kap1 = kap0 + ((kap0 * zinsrechner.zinssatz) / 100);
			kap2 = kap1 + ((kap1 * zinsrechner.zinssatz) / 100);
			kap3 = kap2 + ((kap2 * zinsrechner.zinssatz) / 100);
			kap4 = kap3 + ((kap3 * zinsrechner.zinssatz) / 100);
			kap5 = kap4 + ((kap4 * zinsrechner.zinssatz) / 100);

		}
		String kollonne0 = String.valueOf(df.format(kap0));
		String kollonne1 = String.valueOf(df.format(kap1));
		String kollonne2 = String.valueOf(df.format(kap2));
		String kollonne3 = String.valueOf(df.format(kap3));
		String kollonne4 = String.valueOf(df.format(kap4));
		String kollonne5 = String.valueOf(df.format(kap5));

		String Table[][] = new String[][] {
				{ "Startkapital", "CHF " + kollonne0 },
				{ "1.Jahr", "CHF " + kollonne1 },
				{ "2.Jahr", "CHF " + kollonne2 },
				{ "3.Jahr", "CHF " + kollonne3 },
				{ "4.Jahr", "CHF " + kollonne4 },
				{ "5.Jahr", "CHF " + kollonne5 } };
		return Table;
	}

}



Das problem ist bei der Klasse die vom ActionListener aufgerufen wird:


tabbut.add(zinsrechner.table, BorderLayout.NORTH);
 
weißt du was eine NullPointerException ist? irgendwas ist null was nicht null sein sollte

die Exception sagt dir weiterhin, dass der Fehler erst in einer inneren Methode auftritt,
tabbut ist also nicht null, natürlich vorher auch leicht nachzuprüfen,

damit dürfte klar sein was null ist oder?
und der nächste Schritt ist dann doch auch klar oder was ist da das Problem?
warum ist zinsrechner.table null, wer kümmert sich darum, kontrolliere diesen Code!

so ein schöner leichter Fehler..

---

Klassen übrigens unbedingt groß schreiben!
 
Ein Vorteil wäre es schon, wenn du wirklich eine Klasse Zinsrechner schreibst mit Konstruktor und Methoden etc.
Dadurch muss schon mal nicht alles static sein. (außer das war gewollt ;-))

Java:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;
import java.util.Scanner;
import javax.swing.*;
 
public class zinsrechner {
    // JFRAME GENERIEREN
    JFrame frame;
    
    // JPANEL FÜR TABELLE GENERIEREN.
    JPanel tabbut;
    
    // TEXTFELDER GENERIEREN
   JTextField tf_zinssatz = new JTextField("", 10);
   JTextField tf_kapital = new JTextField("", 10);
 
    // BUTTONS GENERIEREN
    JButton button;
 
    // VARIABLEN GENERIEREN
    double zinssatz;
    double kapital;
 
    // JTABLE GENERIEREN
    JTable table;

    public Zinsrechner()
    {
     // FENSTER ERZEUGEN UND TITEL SETZEN
        JFrame frame = new JFrame();
        frame.setTitle("Zinsrechner");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setBackground(new Color(0, 0, 0));
 
        // INFORMATIONSFELDER ERZEUGEN
        Label tf_zinssatz_inf = new Label("Bitte Zinssatz in % hier Eingeben");
        tf_zinssatz_inf.setForeground(new Color(255, 255, 255));
        Label tf_kapital_inf = new Label("Bitte Startkapital in CHF Eingeben");
        tf_kapital_inf.setForeground(new Color(255, 255, 255));
 
        // LAYOUT MANAGER HINZUFÜGEN
        frame.setLayout(new BorderLayout());
 
        // JPANEL FÜR KAPITAL
        JPanel kapitalpanel = new JPanel();
        kapitalpanel.setLayout(new BorderLayout());
        kapitalpanel.add(tf_kapital_inf, BorderLayout.NORTH);
        kapitalpanel.add(zinsrechner.tf_kapital, BorderLayout.SOUTH);
 
        // JPANEL FÜR ZINSSATZ
        JPanel zinssatzpanel = new JPanel();
        zinssatzpanel.setLayout(new BorderLayout());
        zinssatzpanel.add(tf_zinssatz_inf, BorderLayout.NORTH);
        zinssatzpanel.add(zinsrechner.tf_zinssatz, BorderLayout.SOUTH);
 
        // START BUTTON HINZUFÜGEN
        JButton button = new JButton("Berechnen!");
        button.setBackground(new Color(0, 255, 0));
        button.setForeground(new Color(255, 0, 255));
 
        // ACTIONLISTENER FÜR BUTTON HINZUFÜGEN
        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                buttonStartClicked();
 
            }
        });
 
        // JPANEL KAPITAL UND JPANEL INFO ZUSAMMENSCHMEISSEN
        JPanel inffeld = new JPanel();
        inffeld.add(kapitalpanel, BorderLayout.NORTH);
        inffeld.add(zinssatzpanel, BorderLayout.SOUTH);
 
        // JPANEL FÜR TABELLE UND BUTTON
        zinsrechner.tabbut = new JPanel();
 
        tabbut.add(button, BorderLayout.SOUTH);
 
        // KOMPONENTEN IN FENSTER PACKEN
        frame.add(inffeld, BorderLayout.NORTH);
        frame.add(tabbut, BorderLayout.SOUTH);
 
        frame.pack();
        frame.setVisible(true);
    }
 
    public static void main(String[] args) {
         new Zinsrechner();
    }
 
    // METHODE DIE AUSGEFÜHRT WIRD SOBALD BERECHNEN BUTTON GEKLICKT WIRD
    public void buttonStartClicked() {
 
        // STRINGS AUS TEXTFELDERN HOLEN...
        String zinsstring = tf_zinssatz.getText();
        String kapitalstring = tf_kapital.getText();
 
        // ... UND IN DOUBLES PARSEN
        zinssatz = Double.parseDouble(zinsstring);
        kapital = Double.parseDouble(kapitalstring);
        
        // TABELLEN TITEL SETZEN, INHALT HOLEN
        String uberschrift[] = new String[] { "Zeitpunkt", "Kapital" };
        String Table[][];
 
        Table = rechnung(zinssatz, kapital);
 
        // TABELLE HINZUFÜGEN
        table = new JTable(Table, uberschrift); //oben steht ja schon das die variable table ein JTable ist
        table.setBackground(new Color(255, 215, 0));
        table.setForeground(new Color(0, 0, 0));
        
        tabbut.add(table, BorderLayout.NORTH);
 
    }
 
    // METHODE DIE DIE GANZE RECHNUNG DURCHFÜHRT. GIBT DEN ZWEIDIMENSIONALEN
    // ARRAY FÜR DIE TABELLE ZURÜCK
    public String[][] rechnung(double zinssatz, double kap0) {
 
        kap0 = zinsrechner.kapital;
        double kap1 = 0;
        double kap2 = 0;
        double kap3 = 0;
        double kap4 = 0;
        double kap5 = 0;
 
        DecimalFormat df = new DecimalFormat("0.00");
 
        for (int i = 1000; i <= 6000; i = i + 1000) {
            kap0 = i;
            kap1 = kap0 + ((kap0 * zinssatz) / 100);
            kap2 = kap1 + ((kap1 * zinssatz) / 100);
            kap3 = kap2 + ((kap2 * zinssatz) / 100);
            kap4 = kap3 + ((kap3 * zinssatz) / 100);
            kap5 = kap4 + ((kap4 * zinssatz) / 100);
 
        }
        String kollonne0 = String.valueOf(df.format(kap0));
        String kollonne1 = String.valueOf(df.format(kap1));
        String kollonne2 = String.valueOf(df.format(kap2));
        String kollonne3 = String.valueOf(df.format(kap3));
        String kollonne4 = String.valueOf(df.format(kap4));
        String kollonne5 = String.valueOf(df.format(kap5));
 
        String Table[][] = new String[][] {
                { "Startkapital", "CHF " + kollonne0 },
                { "1.Jahr", "CHF " + kollonne1 },
                { "2.Jahr", "CHF " + kollonne2 },
                { "3.Jahr", "CHF " + kollonne3 },
                { "4.Jahr", "CHF " + kollonne4 },
                { "5.Jahr", "CHF " + kollonne5 } };
        return Table;
    }
 
}
 
a.b.c.d

1) könnte Attribut d von Attribut c von Attribut b der aktuell sichtbaren Variablen a sein
2) könnte die Klasse d im package a.b.c sein
3) könnte das statische Attribut d in der Klasse c im package a.b sein
und noch andere Varianten

mit eindeutiger Benennung, packages klein, Klassen groß, Variablen klein fällt der größte Teil der Ungewissheit weg
1) wäre die korrekte Standard-Interpretation für a.b.c.d
2) entspräche a.b.c.D (siehe deine Import import java.awt.event.ActionEvent; == klein.klein.klein.Groß)
3) entspräche a.b.C.d

in deinem Code ist zinsrechner.table für sich unklar, ist zinsrechner eine Variable oder die Klasse, da viele Leute sowieso gerne Variablen der Form [c]Zinsrechner zinsrechner = ..;[/c] anlegen,
"Zinsrechner.table" wäre dagegen ziemlich deutlich eine statische Variable in der Klasse
 
Das Problem ist nun, dass dass die Tabelle nach betätigen des Buttons nicht erscheint... (Wie) muss ich das ganze JFrame "aktualisieren"?
naja propiers einfach das JFrame nochmal auf setVisible(true) zu setzen. glaub so hab ich das immer gemacht.

Es ist keine Pflicht aber einfach eine eingebürgerte Schreibweise unter (Java-)Programmierern
Klassennamen fangen mit Großbuchstaben an, Variablennamen mit Kleinbuchstaben. So weiß man sofort was eine Klasse und was nur eine Variable ist!

Java:
zinsrechner.zinssatz
Hier würde man denken zinsrechner ist nur eine Variable, welche in dieser Klasse/Methode existiert.
Java:
Zinsrechner.zinssatz
So wissen andere sofort Zinsrechner ist eine Klasse und zinsatz ein Attribut dieser Klasse
 
das ist ein einleuchtender Grund...

hmmm futzt leider immer noch nicht. Muss ich das JPanel tabbut noch mals dem JFrame frame hinzufügen, und nochmals alles verpacken?
 
HAHAHA, Alles klar, problem gelöst -- Die Tabelle wurde eigentlich eingefügt, jedoch hat es die Fenstergrösse nicht angepasst, darum sah ich sie nicht.

Vielen Dank nochmals an Alle für euren Support.
 
erneut
frame.pack();
nach dem Hinzufügen der Komponente wäre eine Möglichkeit,

wenn es nicht gerade eine NullPointerException dann gäbe,
warum und wie zu korrigieren diesmal bitte in Eigenleistung 😉
 

Zurück
Oben