javafx TextArea.appendText()在发送带有TCP

时间:2017-05-21 19:10:29

标签: java javafx tcp

大家大家先谢谢你的帮助。我想创建一个简单的聊天程序,看看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)

我知道错误在哪里,但我该如何解决? 该守则还有其他一些缺陷,但是当我解决这里描述的问题时,我想处理它。

2 个答案:

答案 0 :(得分:0)

正如James_D已经在评论中建议的那样,对两个不同的.fxml文件使用相同的控制器会导致问题。我唯一做的就是创建一个新的ChatNameController类,这个类唯一做的就是检查聊天名是否正确,并将此信息(String)提供给Controller类。

答案 1 :(得分:0)

您在下面的行中收到NullPointerException。

'txtArea.appendText(serverMassege);'

textArea属性似乎有问题。

你可以检查你的XML文件txtArea属性名称应该与XML文件中的ID完全相同吗?