0

我有一个 ServerHandler 类,它创建一个新的 PrintWriter 并将其存储到 PrintWriter 数组中,通过为 selectedId 整数提供应该接收消息的客户端的 ID 号来发送消息。当我在 ServerHandler 类中调用 SendMessage() 方法时,它会毫无问题地发送消息,但是当我尝试从包含 GUI 的类中调用 SendMessage("some message") 方法时,它会给我一个 NullPointerException。

posljiSporocilo() 是实际的 SendMessage() 因为有些方法是我的语言

import java.net.*;
import java.io.*;
import java.awt.*;

  public class ServerHandler implements Runnable{
Socket klientSocket;
static int userCounter = 0;
static int selectedId = 0;
BufferedReader reader;
static PrintWriter writer;
static PrintWriter[] writerHolder = new PrintWriter[10];

static outputHelper out = new outputHelper();   


public ServerHandler(Socket klientSocket) throws IOException
{
    userCounter++;
    this.klientSocket = klientSocket;
    writer = new PrintWriter(this.klientSocket.getOutputStream());
    writerHolder[userCounter] = writer;

    InputStreamReader inReader = new      InputStreamReader(this.klientSocket.getInputStream());
    reader = new BufferedReader(inReader);

    out.frameOutput(this.klientSocket.getInetAddress().toString(), "Server sprejel povezavo:"); 

    selectedId = 1;
    posljiSporocilo("AutoSent");

当我在实际类中调用 posljiSporocilo() 方法时,它确实将消息发送到客户端。
}

public ServerHandler(){
    // Do not launch the main Constructor
}

public void run(){

    String inMessage = null;
    try{
        while((inMessage = reader.readLine()) != null){
            System.out.println("Server Sprejel: " + inMessage);
        }
    }catch(IOException ex){
        ex.printStackTrace();
    }

}

public  void selectId(int id){
    selectedId = id;
    out.frameOutput("ID Changed to: " + selectedId, "ID change");


}

public void posljiSporocilo(String message){
    try
    {
        writerHolder[selectedId].println(message);
        writerHolder[selectedId].flush();

    }catch(Exception ex)
    {
        out.frameOutput("ERROR Trying to send a message", "ERR_MESSAGE:");
        ex.printStackTrace();
    }

}


 }

包含 GUI 内容的类:

package homeControl;

 IMPORTS

public class mainWindow extends JFrame {

private JPanel contentPane;
private JTextField messageTextField;
ServerHandler svr = new ServerHandler();
outputHelper o = new outputHelper();

/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                mainWindow frame = new mainWindow();
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the frame.
 */
public mainWindow() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 450, 300);

    JMenuBar menuBar = new JMenuBar();
    setJMenuBar(menuBar);

    JMenu mnOptions = new JMenu("Options");
    menuBar.add(mnOptions);

    JMenu mnId = new JMenu("ID");
    menuBar.add(mnId);

    JMenuItem idEnaItem = new JMenuItem("ID: 1");
    mnId.add(idEnaItem);
    idEnaItem.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent event){
            if(event.getActionCommand() != null){
                svr.selectId(1);
                setTitle("ID changed to 1");
            }
        }
    });

    JMenuItem idDvaItem = new JMenuItem("ID: 2");
    mnId.add(idDvaItem);
    idDvaItem.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent event){
            if(event.getActionCommand() != null){
                svr.selectId(2);
                setTitle("ID changed to 2");
            }
        }
    });

    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);
    contentPane.setLayout(null);

    messageTextField = new JTextField();
    messageTextField.setBounds(10, 209, 292, 20);
    contentPane.add(messageTextField);
    messageTextField.setColumns(10);

    JButton sendButton = new JButton("Send");
    sendButton.setBounds(312, 208, 89, 23);
    contentPane.add(sendButton);
    sendButton.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent event){

            if(event.getActionCommand() != null)
            {
            svr.posljiSporocilo("THIS MESSAGE DOES NOT GET SENT");
            }

当我从这个类调用 posljiSporocilo() 方法时,它给了我一个 NullPointerException

        }
    });
}
 }

我希望我给了你足够的信息,谢谢!

调试模式 SS:http: //imageshack.us/f/543/1vea.png/

4

2 回答 2

0

你能告诉我为什么你在一开始就增加计数器吗?这将导致您的 writerHolder 数组中的第 0 个元素永远不会被填充。

userCounter++;
this.klientSocket = klientSocket;
writer = new PrintWriter(this.klientSocket.getOutputStream());
writerHolder[userCounter] = writer;

我猜你的 NPE 与此有关。如果您选择的 id 为 0,则方法 posljiSporocilo 中的代码将抛出 NPE。

于 2013-09-19T19:08:33.727 回答
0

但是当我尝试从包含 GUI 的类中调用 SendMessage("some message") 方法时,它给了我一个 NullPointerException。

这很难弄清楚,因为您没有显示条线实际上是在抛出 NPE。在查看您的代码时,我看到以下代码。我看到了writeHolder数组的初始化位置,但我想知道是否writerHolder[selectedId]可以null

public void posljiSporocilo(String message){
    try {
        writerHolder[selectedId].println(message);
        writerHolder[selectedId].flush();
        ...

可能大于值?selectedId_ 如果多个线程正在调用初始化,您可能应该使用 an而不是 non-synchronized 。userCounterAtomicIntegerstatic int

我将学习在 Eclipse 中使用调试器,并逐步执行您的程序,查看每个对象以查看哪个对象为空。

于 2013-09-19T19:09:13.180 回答