NullPointerException bei JTextField

Status
Nicht offen für weitere Antworten.

Kizz

Mitglied
Hi,

folgendes Problem: Ich lese ein JTextField aus und gebe dann den String weiter. Soweit so gut, ist ja auch kein großer Akt. Hat auch schon bei zig Tests einwandfrei funktioniert. Also stürze ich mich nun auf den nächsten Teil meines Programms, probier wieder bissl rum (Text auslesen funktioniert weiterhin einwandfrei) doch plötzlich bringt er mir
beim auslesen des JTextFields eine NullPointerException.

Code:
java.lang.NullPointerException
	at Client.checkDoubleName(Client.java:42)
	at Login.actionPerformed(Login.java:61)
	at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
	at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
	at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
	at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
	at javax.swing.AbstractButton.doClick(AbstractButton.java:357)
	at javax.swing.plaf.basic.BasicRootPaneUI$Actions.actionPerformed(BasicRootPaneUI.java:191)
	at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1636)
	at javax.swing.JComponent.processKeyBinding(JComponent.java:2849)
	at javax.swing.KeyboardManager.fireBinding(KeyboardManager.java:267)
	at javax.swing.KeyboardManager.fireKeyboardAction(KeyboardManager.java:216)
	at javax.swing.JComponent.processKeyBindingsForAllComponents(JComponent.java:2926)
	at javax.swing.JComponent.processKeyBindings(JComponent.java:2918)
	at javax.swing.JComponent.processKeyEvent(JComponent.java:2812)
	at java.awt.Component.processEvent(Component.java:5815)
	at java.awt.Container.processEvent(Container.java:2058)
	at java.awt.Component.dispatchEventImpl(Component.java:4410)
	at java.awt.Container.dispatchEventImpl(Container.java:2116)
	at java.awt.Component.dispatchEvent(Component.java:4240)
	at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1848)
	at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:697)
	at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:962)
	at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:834)
	at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:661)
	at java.awt.Component.dispatchEventImpl(Component.java:4282)
	at java.awt.Container.dispatchEventImpl(Container.java:2116)
	at java.awt.Window.dispatchEventImpl(Window.java:2429)
	at java.awt.Component.dispatchEvent(Component.java:4240)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)

Ich bin grad ziemlich ratlos und verwirrt, weil ich vor allem in den Klassen Login und Client, die oben angegeben sind, nichts verändert hab. Zeile 61 bei Login ist übrigens der EventHandler für den Button, wo das JTextField ausgelesen und weitergegeben wird und Zeile 42 in Client da, wo das weitergegebene ankommt und gespeichert wird.

Code zu posten hat denk ich keinen Sinn, denn daran kann es eigentlich nicht liegen, wenn es nicht verändert wurde und vorher schon funktioniert hat.

Danke schonmal.

Gruß, Kizz
 
Tipp: Code posten


evtl. bekommst du nun Events zu anderen Zeitpunkten,
etwa beim Aufbau der GUI wenn noch nicht alle Komponenten initialisiert sind
 
Ok, dann pflück ich mal das relevante raus:

Login.java:

Code:
public void actionPerformed(ActionEvent ae){
		
		Object source=ae.getSource();
		
		if(source==loginButton){
			
			if(loginNameField.getText().length()>0){
				client.checkDoubleName(loginNameField.getText());
			}else{
				this.setVisible(false);
				JLabel lbl = new JLabel("Bitte einen Namen eingeben!");	 
	            JOptionPane.showMessageDialog(this,lbl,"Name fehlt",JOptionPane.ERROR_MESSAGE);
	            this.setVisible(true);
			}
		}
	}


Client.java:

Code:
void checkDoubleName(String name){
		try{
			this.name=name;
			out.write("checkdouble"+name);
			out.newLine();
			out.flush();
		}catch(Exception e){e.printStackTrace();}
	}

Die Zeile mit out.write(); ist die oben angegebene, wo der Fehler auch auftritt.

In Konstruktor von Client wird ein Objekt der neuen Klasse, an der ich grad dran bin und wo es dann plötzlich mittendrin hakte, erstellt:

Code:
public Client(String ip,int port,Login login){
	   this.ip=ip;
	   this.port=port;
	   this.login=login;
	   users=new ArrayList<String>();
	   uv=new UserView(this);
	}

Später, nach erfolgreichem Login, wird dann das neue Fenster angezeigt. Ich häng dann mal die Klasse UserView auch noch an, denn irgendwie muss ja fast der Fehler dort sein...nur wie gesagt eigentlich unlogisch, da er ja nichtmal das JTextField auslesen kann...

UserView.java:
Dies ist allerdings noch totale Baustelle, kämpfe grad damit, wie ich es schaffe, für jeden User einen Button einzurichten und anzeigen zu lassen etc pp...egal ^^

Code:
import java.net.*;
import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

class UserView extends JFrame{

	int screenWidth;
	int screenHeight;
	Container mainFrame;
	Client c;
	JPanel userPanel;
	JScrollPane scrollPanel;
	ArrayList<String> users;
	
	public UserView(Client c){
		super("LH-Chat UserList");
		this.c=c;
		//get user's screensize
		screenWidth=getToolkit().getScreenSize().width;
		screenHeight=getToolkit().getScreenSize().height;
		//set JFrame size and position
		setSize(screenWidth/5,screenHeight/3);
		setLocation(screenWidth/5*3,screenHeight/3);
		setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		//MainFrame
		mainFrame=getContentPane();
		
		mainFrame.add(userPanel);
		setContentPane(mainFrame);
	}
	
	void updateUser(){
		mainFrame.removeAll();
		//getting current user list and create buttons for each user
		users=c.getUsers();
		if(users.size()<15){
			userPanel=new JPanel(new GridLayout(15,1));
		}else{
			userPanel=new JPanel(new GridLayout(users.size(),1));
		}
		System.out.println(users);
		createUserButtons(users);
		scrollPanel=new JScrollPane(userPanel);
		scrollPanel.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
        scrollPanel.setBorder(null);
		mainFrame.add(scrollPanel);
		setContentPane(mainFrame);
	}
	
	void createUserButtons(ArrayList<String> users){
		ListIterator<String> it=users.listIterator();
		for(int a=0;a<users.size();a++){
			JButton temp=new JButton(it.next());
			temp.setBounds(2,2,100,20);
			userPanel.add(temp);
		}
	}
}
 
Die Zeile mit out.write(); ist die oben angegebene, wo der Fehler auch auftritt.

Dann wird out in dem Fall null sein.
Einfach zu überprüfen mit
Code:
System.out.println("Out null? -> " + out==null);

lr
 
Nein, out ist nicht null.

Was noch zu erwähnen ist, was ich vergaß:
Die oben angegebene Fehlermeldung kam, als ich die Klasse UserView mal komplett weggelassen hab.
Wenn sie erstellt wird etc dann sieht sie so aus:

Code:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at Login.actionPerformed(Login.java:61)
	at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
	at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
	at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
	at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
	at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
	at java.awt.Component.processMouseEvent(Component.java:6038)
	at javax.swing.JComponent.processMouseEvent(JComponent.java:3265)
	at java.awt.Component.processEvent(Component.java:5803)
	at java.awt.Container.processEvent(Container.java:2058)
	at java.awt.Component.dispatchEventImpl(Component.java:4410)
	at java.awt.Container.dispatchEventImpl(Container.java:2116)
	at java.awt.Component.dispatchEvent(Component.java:4240)
	at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4322)
	at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3986)
	at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3916)
	at java.awt.Container.dispatchEventImpl(Container.java:2102)
	at java.awt.Window.dispatchEventImpl(Window.java:2429)
	at java.awt.Component.dispatchEvent(Component.java:4240)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)

Da kommt er dann nichtmal bis zur Client.java

...Ok, das mit out ist geklärt. Schon ein wenig peinlich, wenn der Server garnicht läuft ^^
Nichtsdestotrotz bleibt obige Fehlermeldung, ausser ich kommentier die Erstellung von UserView aus.

Könnte es irgendwie sein, dass durch das Übergeben des Client-Objekts an UserView, was ja vor dem auslesen passiert, das Login-Objekt ein Problem hat, auf das Client-Objekt zuzugreifen bzw. nicht findet und somit eine NullPE wirft?
 
Also entweder Du postest die kompletten Klassen, oder es wird hier schwer, Dir irgendwie zu helfen.
Mit dem Geposteten kann man jedenfalls m.E. nicht sehr viel anfangen.

lr
 
Ok. UserView is oben schon, dann hier Login.java:

Code:
import java.net.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Login extends JFrame implements ActionListener{
	
	int screenWidth;
	int screenHeight;
	Container mainFrame;
	JButton loginButton;
	RandomAccessFile data;
	Client client;
	JTextField loginNameField;
	
	public Login(){
		super ("LH-Chat Login");
		//get user's screensize
		screenWidth=getToolkit().getScreenSize().width;
		screenHeight=getToolkit().getScreenSize().height;
		//set JFrame size and position
		setSize(screenWidth/4,screenHeight/10);
		setLocation(screenWidth/8*3,screenHeight/20*9);
		setResizable(false);
		//MainFrame
		mainFrame=getContentPane();
		setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		
		JPanel loginPanel=new JPanel();
		JLabel loginNameInfo=new JLabel("Chatname eingeben: ");
		loginNameField=new JTextField(15);
		loginButton=new JButton("Login");
		loginButton.addActionListener(this);
		getRootPane().setDefaultButton(loginButton);
		
		
		loginPanel.add(loginNameInfo);
		loginPanel.add(loginNameField);
		loginPanel.add(loginButton);
				
		mainFrame.add(loginPanel);
		
		setContentPane(mainFrame);

		//connection to server
		try{
			data=new RandomAccessFile("clientdata.txt","r");
			client=new Client(data.readLine(),Integer.parseInt(data.readLine()),this);
			client.startClient();
		}catch(Exception e){}
	}
	
	public void actionPerformed(ActionEvent ae){
		
		Object source=ae.getSource();
		
		if(source==loginButton){
			
			if(loginNameField.getText().length()>0){
				client.checkDoubleName(loginNameField.getText());
			}else{
				this.setVisible(false);
				JLabel lbl = new JLabel("Bitte einen Namen eingeben!");	 
	            JOptionPane.showMessageDialog(this,lbl,"Name fehlt",JOptionPane.ERROR_MESSAGE);
	            this.setVisible(true);
			}
		}
	}
}

und Client.java:

Code:
import java.net.*;
import java.io.*;
import java.util.*;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;

public class Client extends JFrame{
	
	private String ip;
	public String name;
	private int port;
	public Login login;
	BufferedWriter out;
	private ArrayList<String> users;
	public UserView uv;

	public Client(String ip,int port,Login login){
	   this.ip=ip;
	   this.port=port;
	   this.login=login;
	   users=new ArrayList<String>();
	   uv=new UserView(this);
	}
	
	void startClient() throws Exception{
		Socket s;
		String msg;
		s=new Socket(ip, port);
		out=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
		ClientBody cb=new ClientBody(s.getInputStream(),s.getOutputStream(),this);
		cb.start();
		while(!(cb.getMsg().trim()).equals("exit")){}
		out.close();
	}
	
	void checkDoubleName(String name){
		try{
			this.name=name;
			out.write("checkdouble"+name);
			out.newLine();
			out.flush();
		}catch(Exception e){e.printStackTrace();}
	}
	
	void doubleName(){
		login.setVisible(false);
		JLabel lbl = new JLabel("Der Name ist bereits vergeben!");	 
        JOptionPane.showMessageDialog(this,lbl,"Name vergeben",JOptionPane.ERROR_MESSAGE);
        login=new Login();
        login.setVisible(true);
	}
	
	ArrayList<String> getUsers(){
		return users;
	}
	
	void addUser(String name){
		users.add(name);
	}
	
	void sortUsers(){
		Collections.sort(users);
		System.out.println(users);
	}
	
	void updateUser(){
		uv.updateUser();
	}
}

class ClientBody extends Thread{
	
    private InputStream is;
    private OutputStream os;
    private Client c;
    public String msg;
    private int maxusers;
    
    public ClientBody(InputStream is,OutputStream os,Client c){
      this.is=is;
      this.os=os;
      this.c=c;
      maxusers=100;
    }
    
    public String getMsg(){
    	return msg;
    }

	public void run(){
		BufferedReader in;
	    BufferedWriter out;
	    String[] users=new String[maxusers];
	   
	    try{
		   in=new BufferedReader(new InputStreamReader(is));
		   out=new BufferedWriter(new OutputStreamWriter(os));
		   
		   while(true){
			   msg=in.readLine();
			   System.out.println(msg);
			   
			   if(msg!=null){
				   
		    	   //result of checking double names
				   if(msg.length()>=11 && msg.substring(0,11).equals("checkdouble")){
		    		   if(msg.substring(11,msg.length()).equals("true")){
		    			   c.login.setVisible(false);
		    			   c.uv.setVisible(true);
		    		   }else{
		    			   c.doubleName();
		    		   }
		    	   }
				   
				   //getting current userlist at startup
				   if(msg.length()>=9 && msg.substring(0,9).equals("currusers")){
					   if(msg.substring(9,msg.length()).equals("end")){
						   c.sortUsers();
						   c.updateUser();
					   }
					   else{
						   c.addUser(msg.substring(9,msg.length()));
					   }
				   }
			   }
	       } 
	    }catch (Exception e){e.printStackTrace();}   
    }
}
 
Änder mal in der Login.java:

Code:
      ...
      //connection to server
      try{
         data=new RandomAccessFile("clientdata.txt","r");
         client=new Client(data.readLine(),Integer.parseInt(data.readLine()),this);
         client.startClient();
      }catch(Exception e)
      {
      e.printStackTrace();
      }

Ich vermute, daß die Variable client null ist.

lr
 
In was? Und vor allem, warum hats vorher funktioniert?

Anyway, da ich weiterhin der Meinung war, dass es irgendwas mit dem Erstellen von UserView zu tun hat, hab ich nun in der Client.java die Erstellung aus dem Konstruktor (Zeile 25) rausgenommen und unten im ClientBody (zwischen Zeile 111 und 112) platziert und siehe da, es funktioniert.
Allerdings stellt sich nun die Frage, warum? Beim Erstellen von UserView wird ja das Client-Objekt übergeben bzw. die Referenz, oder? D.h., Login müsste doch auch weiterhin die Referenz auf das Client-Objekt haben?

Also Laienhaft ausgedrückt sieht es so aus, als würde sich das Client-Objekt komplett an UserView weitergeben und irgendwie dem Login die Referenz "entziehen". Daraus würde dann folgen, dass später beim ActionEvent die Variable null ist.

Das blick ich grad überhaupt net ^^
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben