我的教授给了我一些示例代码来制作一个基本的聊天程序,其中一个要求就是允许用户通过按下按钮来连接和断开连接。我创建了按钮并为两者添加了动作侦听器,但是当我单击" connect"按钮,我明白了:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at Client.actionPerformed(Client.java:64)
at java.awt.Button.processActionEvent(Unknown Source)
at java.awt.Button.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$500(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
我将错误追溯到此块:
try{
myOutputStream.reset(); //this is line 64 in the full Java file
myOutputStream.writeObject(myObject);
}catch(IOException ioe){
System.out.println(ioe.getMessage());
}
我会说我确实对示例代码进行了更改,因此在进行一些编辑之前,上面的部分正在工作,这就是将一个启动连接的代码移动到if语句中检查按钮是否被点击。之前曾经在"客户"构造函数(我的教授为程序做的),并在启动Java程序时立即运行并连接。
完整的客户端类在这里:
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.util.*;
//THINGS TO DO:
//1: Add a means to add usernames
//2: Add something that adds a list of users
//3: Button to disconnect/connect
//4: Panel that allows you to draw things
public class Client extends Thread implements ActionListener{
ChatMessage myObject;
boolean sendingdone = false, receivingdone = false;
Scanner scan;
Socket socketToServer;
ObjectOutputStream myOutputStream;
ObjectInputStream myInputStream;
Button connect,disconnect;
Frame f;
TextField tf;
TextArea ta;
public Client(){
f = new Frame();
f.setSize(300,400);
f.setTitle("Chat Client");
f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent we){
System.exit(0);
}
});
tf = new TextField();
tf.addActionListener(this);
f.add(tf, BorderLayout.NORTH);
ta = new TextArea();
f.add(ta, BorderLayout.CENTER);
/////////////////////////
/*
try{
socketToServer = new Socket("127.0.0.1", 4000);
myOutputStream = new ObjectOutputStream(socketToServer.getOutputStream());
myInputStream = new ObjectInputStream(socketToServer.getInputStream());
start();
}
catch(Exception e){
System.out.println(e.getMessage());
}
*/this is the original spot
Panel b = new Panel();
connect = new Button("Connect");
disconnect = new Button("Disconnect");
connect.addActionListener(this);
disconnect.addActionListener(this);
b.add(connect);
b.add(disconnect);
f.add(b, BorderLayout.SOUTH);
f.setVisible(true);
}
public void actionPerformed(ActionEvent ae){
myObject = new ChatMessage();
myObject.setMessage(tf.getText());
tf.setText("");
try{
myOutputStream.reset();
myOutputStream.writeObject(myObject);
}catch(IOException ioe){
System.out.println(ioe.getMessage());
}
if (ae.getSource() == connect){
try{
socketToServer = new Socket("127.0.0.1", 4000);
myOutputStream =
new ObjectOutputStream(socketToServer.getOutputStream());
myInputStream =
new ObjectInputStream(socketToServer.getInputStream());
start();
}
catch(Exception e){
System.out.println(e.getMessage());
}
}
}
public void run(){
System.out.println("Listening for messages from server . . . ");
try{
while(!receivingdone){
myObject = (ChatMessage)myInputStream.readObject();
ta.append(myObject.getMessage() + "\n");
}
}catch(IOException ioe){
System.out.println("IOE: " + ioe.getMessage());
}catch(ClassNotFoundException cnf){
System.out.println(cnf.getMessage());
}
}
public static void main(String[] arg){
Client c = new Client();
}
}
我认为您还需要这两个Java类,ChatServer,它必须运行,客户端必须连接到ChatMessage,以及客户端用来创建消息的内容:
import java.io.*;
import java.net.*;
import java.util.*;
public class ChatServer{
public static void main(String[] args )
{
ArrayList<ChatHandler> AllHandlers = new ArrayList<ChatHandler>();
try
{ ServerSocket s = new ServerSocket(4000);
for (;;)
{ Socket incoming = s.accept( );
new ChatHandler(incoming, AllHandlers).start();
}
}
catch (Exception e)
{ System.out.println(e);
}
}
}
class ChatHandler extends Thread
{ public ChatHandler(Socket i, ArrayList<ChatHandler> h)
{
incoming = i;
handlers = h;
handlers.add(this);
try{
in = new ObjectInputStream(incoming.getInputStream());
out = new ObjectOutputStream(incoming.getOutputStream());
}catch(IOException ioe){
System.out.println("Could not create streams.");
}
}
public synchronized void broadcast(){
ChatHandler left = null;
for(ChatHandler handler : handlers){
ChatMessage cm = new ChatMessage();
cm.setMessage(myObject.getMessage());
try{
handler.out.writeObject(cm);
System.out.println("Writing to handler outputstream: " + cm.getMessage());
}catch(IOException ioe){
//one of the other handlers hung up
left = handler; // remove that handler from the arraylist
}
}
handlers.remove(left);
if(myObject.getMessage().equals("bye")){ // my client wants to leave
done = true;
handlers.remove(this);
System.out.println("Removed handler. Number of handlers: " + handlers.size());
}
System.out.println("Number of handlers: " + handlers.size());
}
public void run()
{
try{
while(!done){
myObject = (ChatMessage)in.readObject();
System.out.println("Message read: " + myObject.getMessage());
broadcast();
}
} catch (IOException e){
if(e.getMessage().equals("Connection reset")){
System.out.println("A client terminated its connection.");
}else{
System.out.println("Problem receiving: " + e.getMessage());
}
}catch(ClassNotFoundException cnfe){
System.out.println(cnfe.getMessage());
}finally{
handlers.remove(this);
}
}
ChatMessage myObject = null;
private Socket incoming;
boolean done = false;
ArrayList<ChatHandler> handlers;
ObjectOutputStream out;
ObjectInputStream in;
}
(我没有对这两个方面做过任何改动)
import java.io.*;
public class ChatMessage implements Serializable{
public String name;
public String message;
public ChatMessage(){}
public ChatMessage(String name, String message){
setName(name);
setMessage(message);
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setMessage(String message){
this.message = message;
}
public String getMessage(){
return message;
}
}
答案 0 :(得分:1)
永远不会初始化myOutputStream。你评论了它应该发生的部分。