2016-04-17 13 views
0

私の教授からサンプルコードを与えられて、基本的なチャットプログラムを作成しました。要件の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; 
    } 
} 

答えて

1

myOutputStreamは決して初期化されません。あなたはそれが起こるはずの部分をコメントしました。

+0

これはそうしたようです。 64行目の前にtry/catchブロックを移動すると、myOutputStreamが作成され、ボタンをクリックすると接続されます。ありがとう! – Edax

関連する問題