私の教授からサンプルコードを与えられて、基本的なチャットプログラムを作成しました。要件の1つは、ボタンを押して切断します。私は、ボタンを作成し、両方のためのアクションリスナーを追加しましたが、私は「接続」ボタンをクリックしたときに、私はこれを取得:"スレッド内の例外" AWT-EventQueue-0 "java.lang.NullPointerException"ボタンを押したとき
try{
myOutputStream.reset(); //this is line 64 in the full Java file
myOutputStream.writeObject(myObject);
}catch(IOException ioe){
System.out.println(ioe.getMessage());
}
私は言うだろう:
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)
が、私は戻って、このブロックにエラーをトレースしサンプルコードに変更を加えたので、の部分がだったので、ボタンをクリックしたかどうかをチェックするif文に接続を開始するコードをブロックに移動していました。以前は "クライアント"のコンストラクタ(私の教授がプログラムのために作ったもの)にいた前に、Javaプログラムの起動時に即座に実行して接続します。
フルClientクラスはここにある:
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();
}
}
は、私はあなたにも、同様にこれらの2つの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;
}
}
これはそうしたようです。 64行目の前にtry/catchブロックを移動すると、myOutputStreamが作成され、ボタンをクリックすると接続されます。ありがとう! – Edax