java.lang.NullPointerException

  • Themenstarter Themenstarter petetheat
  • Beginndatum Beginndatum
Status
Nicht offen für weitere Antworten.
P

petetheat

Gast
Ich hab folgendes Problem. Ich moechte Zeilen aus einer Textdatei einlesen und in Textfeldern ausgeben. In einem anderen Programm hat's auch super funktioniert.
In diesem hab ich eigentlich alles genauso uebernommen, bis auf den Unterschied, dass die Textfelder jetzt in einer anderen Klasse (InputView) eingebaut sind, waehrend bei dem anderen waren diese in der Hauptklasse (Main).
Da ich das GUI Fenster mit JPanel geteilt habe, sind jetzt die Textfelder halt in der Klasse InputView.

Code:
public void actionPerformed(ActionEvent e) {
        JFileChooser fc = new JFileChooser();
        fc.setAcceptAllFileFilterUsed(true);
        int returnVal = fc.showOpenDialog(inputView);
        
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File file = fc.getSelectedFile();
            inputView.setTxt(file.getPath());
        } else {
            inputView.setTxt("No File selected");
        }
        
    }

Die Stelle inputView.setTxt(file.getPath()); ruft dann die java.lang.NullPointerException hervor.

Bei dem Programm, das funktioniert, steht derselbe Code wie oben, nur anstatt inputView steht dort main, weil dort setTxt und die Textfelder stehen.

Gruss, Pete
 
Wo wird der Variable inputView ein Wert zugewiesen? Antwort: Nirgends, deswegen bekommst du auch eine NullPointerException. Irgendwo musst du stehn haben this.inputView = new InputView oder this.inputView = inputView
 
Ich glaube, ich hab das ganze etwas missverstaendlich formuliert.

Also, im Code

Code:
public void actionPerformed(ActionEvent e) { 
        JFileChooser fc = new JFileChooser(); 
        fc.setAcceptAllFileFilterUsed(true); 
        int returnVal = fc.showOpenDialog(inputView); 
        
        if (returnVal == JFileChooser.APPROVE_OPTION) { 
            File file = fc.getSelectedFile(); 
            inputView.setTxt(file.getPath()); 
        } else { 
            inputView.setTxt("No File selected"); 
        } 
        
    }

ruft die Stelle inputView.setTxt(file.getPath()); die Exception hervor.

In der Klasse InputView ist aber setTxt definiert als:

Code:
public void setTxtNew(String filePath) {
        inputFields[1].setText(filePath);
    }

Also er soll erstmal nur den Pfad in das Textfeld schreiben.
Woran kann das liegen, dass das nicht funktioniert?
 
Niki hat gesagt.:
Wo wird der Variable inputView ein Wert zugewiesen? Antwort: Nirgends, deswegen bekommst du auch eine NullPointerException. Irgendwo musst du stehn haben this.inputView = new InputView oder this.inputView = inputView

Und wo gehoert das rein?!?
 
irgendwo/ irgendwann VOR dem Aufruf,

wenn du einen Kuchen backen willst, dann musst du vorher auch die Zutaten einkaufen und in deiner Küche bereitstellen,
wann du das machst kann niemand sagen, hauptsache sie sind da, wenn du anfangen willst zu backen
 
Wahrscheinlich in den Konstruktor. Ich bin ja kein Hellseher und weiß daher nicht wie du deine Applikation aufgebaut hast. Erzeugst du z.B. alle deine GUI Objekte an einer Stelle, dann gehört inputView als Paramenter dem Konstruktor der anderen Klasse (dort wo actionPerformed drinnen ist) übergeben. Im Konstruktor kannst du dann schreiben:
this.inputView = inputView (inputView muss dann sowohl dein Attribut als auch der Paramenter heißen)
Hier zur Verdeutlichung:
Code:
public static void main(String[] args){
  InputView iv = new InputView();
  HauptFenster hf = new HauptFenster(iv);

  hf.setVisible(true);
//.....

}


public class InputView extends JPanel{

}


public class HauptFenster extends JFrame{

  private InputView inputView = null;

  public HauptFenster(InputView inputView){
    this.inputView = inputView;
  }
}
 
Ich hab's aber schon drin stehen:

Code:
public class OpenFile implements ActionListener {
    
    InputView inputView;
    
    public OpenFile(MainFrame mainFrame) {
        
        this.inputView = inputView;
    }

    public void actionPerformed(ActionEvent e) {
        JFileChooser fc = new JFileChooser();
        fc.setAcceptAllFileFilterUsed(true);
        int returnVal = fc.showOpenDialog(inputView);
        
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File file = fc.getSelectedFile();
            inputView.setTxtNew(file.getPath());
        } else {
            inputView.setTxtNew("No File selected");
        }
        
    }
    
}
 
Nein hast du nicht, du müsstest eigentlich eine Warning angezeigt bekommen, dass die Zuweisung keinen Sinn ergibt. Du übergibt inputView nicht als Parameter. Das was du machst ist das selbe wie this.inputView = this.inputView.
 
Deine Zeile 7 darf nicht lauten

Code:
this.inputView = inputView;

sondern muss lauten:

Code:
this.inputView = new InputView();

Gruß
Eminent
 
Ok, der Fehler ist jetzt weg, ich hab die Stelle gefunden, wo's reingehoert.
Aber ich verstehe trotzdem nicht, warum das ueberhaupt dort rein muss, ich meine hab ja eine Klasse InputView.

Ich bin totaler Anfaenger in Java, aber das habt ihr sicherlich schon gemerkt 🙂
 
Eine Klasse zu haben heißt nicht dass du ein Objekt von dieser Klasse angelegt hast ( = Instanz).
Es gibt Methoden, die gehören zu Instanzen und es gibt Methoden die einer Klasse gehören. Methoden die zu einer Klasse gehören und keinen Instanz-Context haben sind mit dem Schlüsselwort "static" versehn:
z.B.

Code:
public class Duh {
public static void duhWasStatisch(){

}

public void duhWasNichtStatisch(){

}

//Aufrufe wären:
//statisch:
Duh.duhWasStatisch();

//nicht statisch:

//1. Objekt anlegen:
Duh duh = new Duh();
//2. Methode des Objektes aufrufen:
duh.duhWasNichtStatisch();

statische Methoden kannst du als Funktionen betrachten, die keinen Bezug zu einem Objekt haben. So wie die Methode Math.random().

Vielleicht ist dir ja jetzt so manches klarer 🙂
 
petetheat hat gesagt.:
Ok, der Fehler ist jetzt weg, ich hab die Stelle gefunden, wo's reingehoert.
Aber ich verstehe trotzdem nicht, warum das ueberhaupt dort rein muss, ich meine hab ja eine Klasse InputView.

Ich bin totaler Anfaenger in Java, aber das habt ihr sicherlich schon gemerkt 🙂

Du hast zwar eine Klasse InputView, aber um Methoden dieser Klasse aufrufen zu können musst du sie vorher instanziieren und das machst du mit dem new InputView(). Dadurch erhälst du eine Instanz der Klasse, mit der du dann weiter arbeiten kannst und vor allem von der du auch die Methoden der Klasse aufrufen kannst.
 
Das Problem mit der NullPointerException ist zwar geloest, aber dadurch, dass ich jetzt

Code:
public void setTxt(String sFilePath) {
        inputView = new InputView();
        inputView.setTxtNew(sFilePath);
    }

aufrufe, erzeuge ich ja eine neue Instanz (hab ich doch richtig verstanden, oder?)

Jetzt hab ich aber bereits vorher die Textfelder erzeugt und zwar in derselben Klasse InputView. Da ich aber jetzt die Instanze neu erzeuge, wird der Inhalt der Textdatei nicht in die bestehenden Textfelder geladen, sondern in die der neuen Instanz und diese sind nicht sichtbar.

Gibt es eine Moeglichtkeit, anstatt mit inputView = new InputView(); eine neue Instanz zu erzeugen, die bestehende aufzurufen?

Ich weiss nicht, ob das alles so Sinn macht, wie ich das schreibe, aber ich hoffe, es ist doch verstaendlich genug...
 
inputView = new InputView();
solltest du nicht in der Methode setText schreiben, sondern nur EINMAL im Konstruktor. Dann wird immer die selbe Instanz verwendet.
 
Aber das hab ich doch, oder nicht? Ich mein, ich mach das in der Klasse TextFrame

Code:
public TextFrame() {
        
        super(new BorderLayout());
        
        JPanel viewAll = new JPanel(new BorderLayout());
        
        JPanel inputPanel = new JPanel(new GridLayout(1,1));
                        
        inputView = new InputView();
        inputPanel.add(inputView);
                
        viewAll.add(inputPanel, BorderLayout.WEST);
        
        JPanel viewPanel = new JPanel(new GridLayout(5,1));
        viewAll.add(viewPanel, BorderLayout.EAST);
        
        add(viewAll);
        
    }

In InputView stehen dann die Textfelder, welche ich mit dem Dateiinhalt fuellen moechte.

Und TextFrame wird in der Mainklasse aufgerufen:

Code:
public void createView() {
        textFrame = new TextFrame();
        getContentPane().add(textFrame);
        
        setVisible(true);
    }

In dieser Mainklasse ist auch das Menu implementiert, aus dem der Aufruf kommt, die Datei zu laden.

setTxt so wie's im Post vorher steht, steht dann auch in der Mainklasse und soll dann setTxtNew ausfuehren, welches wiederrum in InputView steht.

Ich weiss, ist wahrscheinlich alles ziemlich umstaendlich, aber ich hab's so zum laufen bekommen....
 
petetheat hat gesagt.:
Code:
public void setTxt(String sFilePath) {
        inputView = new InputView();
        inputView.setTxtNew(sFilePath);
    }

Lösch das inputView = new InputView(); mal raus. Also so:

Code:
public void setTxt(String sFilePath) {       
        inputView.setTxtNew(sFilePath);
    }

Das könnte schon die Lösung für dein Problem sein
 
Das hatte ich ja ganz am Anfang so, dann hab ich die NullPointerException bekommen.

Ich hab das ganze jetzt folgendermassen geloest (unter Mithilfe eines Kollegen):

Ich hab in der Klasse TextFrame (wo ja inputView = new InputView(); schon aufgerufen wird) folgendes hinzugefuegt:

Code:
public InputView getInputView() {
        return this.inputView;
    }

Dann hab ich die Methode setTxt folgendermassen abgeaendert:

Code:
public void setTxt(String sFilePath) {
        textFrame.getInputView().setTxtNew(sFilePath);
   }

Jetzt laeuft's wie gewuenscht. Ist wahrscheinlich ziemlich umstaendlich, aber ich bin froh, dass es geht 🙂
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben