大家大家先谢谢你的帮助。我想创建一个简单的聊天程序,看看java中的.net库是如何工作的。因为我只使用javafx接口在java中工作,所以我决定使用它而不是awt或swt。我不确定,但也许我给同一个控制器访问两个不同的.fxml文件的方式可能导致问题。
在Main.java中,我加载了用于创建GUI的.fxml文件。逻辑主要在其他类中。
Main.java
package sample;
import TCP.TCP_Server;
import UDP.UDP_Server;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import java.io.IOException;
public class Main extends Application {
private Stage primaryStage;
private AnchorPane rootLayout;
@Override
public void start(Stage primaryStage) throws Exception{
this.primaryStage = primaryStage;
this.primaryStage.setTitle("AddressApp");
initTest();
}
public void initTest()
{
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("test.fxml"));
AnchorPane page = (AnchorPane) loader.load();
Stage dialogStage = new Stage();
dialogStage.setTitle("Chat Name");
dialogStage.initModality(Modality.WINDOW_MODAL);
dialogStage.initOwner(primaryStage);
Scene scene = new Scene(page);
dialogStage.setScene(scene);
Controller controller = loader.getController();
controller.setStage(primaryStage);
controller.setMain(this);
//Here I want a Username before someone can send messages or login
initNamePanel(dialogStage, controller);
dialogStage.showAndWait();
//controller.setServer(server);
} catch (IOException e) {
e.printStackTrace();
}
}
//only a panel to enter a chatname
public void initNamePanel(Stage primaryStage, Controller controller){
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("ChatNamePanel.fxml"));
AnchorPane page = (AnchorPane) loader.load();
Stage dialogStage = new Stage();
dialogStage.setTitle("Chat Name");
dialogStage.initModality(Modality.WINDOW_MODAL);
dialogStage.initOwner(primaryStage);
Scene scene = new Scene(page);
dialogStage.setScene(scene);
Controller crt = controller;
crt = loader.getController();
crt.setChatNameStage(dialogStage);
dialogStage.showAndWait();
}catch (IOException e){
e.printStackTrace();
System.out.print(e);
}
}
public static void main(String[] args) {
launch(args);
}
}
Controller.java
package sample;
import TCP.TCP_Client;
import TCP.TCP_Server;
import UDP.UDP_Client;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import sample.Main;
import java.net.SocketException;
public class Controller {
@FXML
private Label nameLable;
@FXML
private TextArea txtArea;
@FXML
private TextField inputField;
@FXML
private TextField chatnameField;
private Stage chatNameStage;
private Stage stage;
private TCP_Server server;
private TCP_Client client;
private Main main;
public Controller(){}
public void setStage(Stage stage){this.stage = stage;}
public void setChatNameStage(Stage stage){this.chatNameStage = stage;}
@FXML
public void OKbutton()
{
String msg = inputField.getText();
if(msg != "" || msg != null) {
client.SendToServer(msg);
//empty the input Field
inputField.setText("");
}
}
@FXML
public void closeButton(){
client.close();
stage.close();
}
@FXML
public void setChatName(){
String name = chatnameField.getText();
client = new TCP_Client();
client.setController(this);
if(name != null || name != "") {
client.setChatName(name);
(client).start();
chatNameStage.close();
}
else
System.out.print("Enter a Name");
}
@FXML
public void closeNamePannel(){
chatNameStage.close();
stage.close();
}
public void setRecivedMessage(String serverMassege){
txtArea.appendText(serverMassege); //the exception occures here but the massege was send with the correct login massege so serverMassege is not null
}
public void setMain(Main main){
this.main = main;
}
//newClient is not in use anymore but I dont want to delete it because of reasons
@FXML
public void newClient() {
main.initTest();
}
}
TCP_Client.java
package TCP;
import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils;
import sample.Controller;
import java.net.*;
import java.io.*;
public class TCP_Client extends Thread{
private static int serverPort = 4711;
private static String host = "localhost";
private Socket myClient;
private BufferedReader input;
private BufferedWriter output;
private Controller controller;
private boolean wait = true;
private String chatName;
public void setChatName(String chatName){
this.chatName = chatName;
}
public TCP_Client(){
try {
myClient = new Socket(host, serverPort);
} catch (IOException e) {
e.printStackTrace();
}
}
public void setController(Controller newController){
controller = newController;
}
public void run(){
createSocketStream();
login(chatName);
RecieveFromServer();
}
private void createSocketStream()
{
try {
output = new BufferedWriter(new OutputStreamWriter(myClient.getOutputStream()));
input = new BufferedReader(new InputStreamReader(myClient.getInputStream()));
} catch (UnknownHostException e) {
e.printStackTrace();
System.out.print("Don't know abot host: "+host);
} catch (IOException e) {
e.printStackTrace();
System.out.println(e);
}
}
//is called when I press the OK Button
public void SendToServer(String msg){
try {
if (msg == null || msg == "")
return;
System.out.print(msg);
output.write(msg);
output.newLine();
output.flush();
}catch (IOException e){
System.out.println(e);
}
}
//needs to run in a seperate thread so I need to put this in the run methode as I understand it
private void RecieveFromServer(){
try {
String response;
while (wait) {
response = input.readLine();
controller.setRecivedMessage(response);
if(response == "Quit")
break;
}
}catch (IOException e){
System.out.println(e);
}
}
public void close(){
try {
wait = false;
// System.out.print("Log out");
output.write("--QUIT");
output.newLine();
output.flush();
output.close();
input.close();
myClient.close();
}
catch (IOException e)
{
System.out.println(e);
}
}
private void login(String name){
try {
// System.out.print("Sending: " + name);
// output.writeChars(msg);
output.write("--NAME"+name);
output.newLine();
output.flush();
}catch (IOException e){
System.out.println(e);
}
}
}
TCP_Server.java
package TCP;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.LinkedList;
public class TCP_Server extends Thread{
private String line;
private LinkedList<BufferedWriter> outList;
private LinkedList<Socket> clientList;
private LinkedList<String> usernameList;
Socket actClient;
private BufferedWriter out;
private BufferedReader in;
public final static int port = 4711;
public static void main(String[] args) {
ServerSocket sSocket;
LinkedList<BufferedWriter> outs = new LinkedList<BufferedWriter>();
LinkedList<Socket> clients = new LinkedList<Socket>();
LinkedList<String> userNames = new LinkedList<String>();
boolean runServer = true;
try {
sSocket = new ServerSocket(port);
//runServer
while (System.in.available()==0){
Socket clientSocket = sSocket.accept();
(new TCP_Server(outs, clients, userNames, clientSocket)).start();
}
}catch (IOException e){
e.printStackTrace();
System.out.print(e);
}
}
private TCP_Server(LinkedList<BufferedWriter> outs, LinkedList<Socket> clients,
LinkedList<String> userNames, Socket clientSocket){
outList = outs;
clientList = clients;
usernameList = userNames;
actClient = clientSocket;
}
public void run(){
try {
out = new BufferedWriter(new OutputStreamWriter(actClient.getOutputStream()));
in = new BufferedReader(new InputStreamReader(actClient.getInputStream()));
line = in.readLine();
//check if name is allready used
for(String s : usernameList){
if(s.equals(line.substring(6)) || line.substring(6).length()<=1){
System.out.print("Name schon vergeben oder zu kurz");
return;
}
}
//the registration
if(line.startsWith("--NAME")){
synchronized (clientList) {
for (BufferedWriter o : outList) {
//I need the name of the user after the --NAME
o.write(line.substring(6) + " hase joint the chat");
o.newLine();
o.flush();
}
}
usernameList.add(line.substring(6));
outList.add(out);
clientList.add(actClient);
}
//when --Quit is send checkout the user
while ((line =in.readLine()).startsWith("--QUIT") == false){
if(line != "" || line != null) {
//tell everyone that the user hase left the chat
synchronized (clientList) {
for (BufferedWriter o : outList) {
o.write(line);
o.newLine();
o.flush();
}
}
}
}
//chekout
outList.remove(out);
clientList.remove(actClient);
synchronized (clientList) {
for (BufferedWriter o : outList) {
o.write(line.substring(6) + "hase left the chat");
o.newLine();
o.flush();
}
}
actClient.close();
}catch (IOException e){
System.out.print(e);
}
}
}
其他客户端收到我通过服务器发送的消息,但我无法将文本附加到TextArea。 以下异常将从重新传递消息的客户端抛出:
Exception in thread "Thread-4" java.lang.NullPointerException
at sample.Controller.setRecivedMessage(Controller.java:88)
at TCP.TCP_Client.RecieveFromServer(TCP_Client.java:87)
at TCP.TCP_Client.run(TCP_Client.java:43)
我知道错误在哪里,但我该如何解决? 该守则还有其他一些缺陷,但是当我解决这里描述的问题时,我想处理它。
答案 0 :(得分:0)
正如James_D已经在评论中建议的那样,对两个不同的.fxml文件使用相同的控制器会导致问题。我唯一做的就是创建一个新的ChatNameController类,这个类唯一做的就是检查聊天名是否正确,并将此信息(String)提供给Controller类。
答案 1 :(得分:0)
您在下面的行中收到NullPointerException。
'txtArea.appendText(serverMassege);'
textArea属性似乎有问题。
你可以检查你的XML文件txtArea属性名称应该与XML文件中的ID完全相同吗?