我正在开发一个简单的Java消息传递程序。在开始研究更复杂的功能之前,我想让基本系统正常工作。目前
这段代码特别是出现错误的原因。它是我的ClientThread.java线程中的run()方法(实现了runnable)。该线程用于处理来自服务器的传入消息(发送消息可以正常工作)。
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class ClientThread implements Runnable{
private Socket server;
private DataInputStream in;
private DataOutputStream out;
public Text msgContent;
public void login(Stage stage, Scene main, String username, String password, String portString, String host) {
try {
int port = Integer.parseInt(portString);
this.server = new Socket(host, port);
this.in = new DataInputStream(server.getInputStream());
this.out = new DataOutputStream(server.getOutputStream());
stage.setScene(main);
Platform.runLater(new ClientThread());
}
catch (NumberFormatException e) {
System.out.println("Invalid Port");
return;
}
catch (IOException e) {
System.out.println("Error Connecting to Server");
return;
}
}
public void run() {
String msg = "";
try {
while (true) {
msg = in.readUTF(); //This line gives Errors
System.out.println("Read message from server");
msgContent.setText(msgContent.getText() + msg + "\n");
System.out.println("Added message from server to view");
}
}
catch(Exception ioe) {
ioe.printStackTrace();
System.out.println("Failed to read message from server and add to view.");
}
}
public void sendMsg(String msg) {
try {
out.writeUTF(msg);
} catch (Exception ioe) {
ioe.printStackTrace();
}
}
}
请注意,msgContent是我的JavaFX前端和服务器的inputStream中的Text对象。我的完整代码是here。我得到的错误是
显示java.lang.NullPointerException 在ClientThread.run(ClientThread.java:42) at com.sun.javafx.application.PlatformImpl $ 6 $ 1.run(Unknown Source) at com.sun.javafx.application.PlatformImpl $ 6 $ 1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at com.sun.javafx.application.PlatformImpl $ 6.run(Unknown Source) at com.sun.glass.ui.InvokeLaterDispatcher $ Future.run(Unknown Source) at com.sun.glass.ui.win.WinApplication._runLoop(Native Method) at com.sun.glass.ui.win.WinApplication.access $ 300(未知来源) at com.sun.glass.ui.win.WinApplication $ 4 $ 1.run(Unknown Source) 在java.lang.Thread.run(未知来源) 无法从服务器读取消息并添加到视图。
另请注意,我使用Platform.runLater()来运行此方法。我想知道如何解决上述错误,以便我的代码可以工作。提前谢谢。
答案 0 :(得分:1)
NullPointer异常的原因
in
为空。
发生NullPointerException是因为在此调用中您创建了ClientManager类的新实例:Platform.runLater(new ClientThread());
,因此它不会使用已初始化in
和{{}的ClientManager的现有实例。 1}}成员。相反,您可以使用out
来摆脱NullPointerException。
但是,您的代码还有其他问题......
不正确的并发编程
您正在挂起JavaFX应用程序线程,这将阻止您的应用程序呈现或响应UI输入。永远不要等待JavaFX应用程序线程。
完成您要做的事情的一种方法是使用JavaFX concurrency utilities,尤其是Task。
在它自己的线程上运行任务,然后它可以循环,永远接受输入,它不会阻止你的UI线程。您可以(可能)使您的线程成为非守护程序线程,以便在所有其他守护程序线程完成时自动退出。您可以使用Platform.runLater将输入反馈回UI。但是,对于您想要更新某些消息文本的简单示例,您可以调用updateMessage(请注意,这不需要Platform.runLater调用,因为Task类会为您处理这类详细信息)。要更新消息标签,可以将其text属性绑定到任务的消息属性。有关如何在Task javadoc中执行此操作的示例。