在JavaFX中写入OutputStream setOnAction()方法

时间:2017-08-24 13:11:30

标签: java javafx

我正在编写一个JavaFX应用程序(它应该是一个简单的聊天应用程序)。现在,每次按下按钮,我都会尝试写OutputStream。事实是,它不起作用,看起来信息是写的,但我无法从InputStream读取它。

我有两个类:其中一个是接口(extends Application)。它有一个TextField和一个“发送”按钮。当我在文本字段中写入内容并按下此按钮时,TextField中的文本将写入OutputStream。另一方面,另一个类Thread正在从InputStream读取。即使信息被写入流,readLine()方法也不起作用,它会一直等待接收数据。

有什么我想念的吗?提前谢谢。

JavaFX应用程序

import java.io.*;
import java.net.Socket;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.geometry.*;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;

public class ChatApp extends Application {

    int indexMsg = 0;

    Socket socket;
    BufferedReader br;
    PrintWriter pw;

    public ChatApp() throws IOException {

        this.socket = new Socket("localhost", 56700);
        this.pw = new PrintWriter(socket.getOutputStream());
        this.br = new BufferedReader(new InputStreamReader(socket.getInputStream()));

    }

    @Override
    public void start(Stage primaryStage) throws IOException {

        GridPane root = new GridPane();
        root.setAlignment(Pos.CENTER);
        root.setVgap(10);
        root.setPadding(new Insets(10,10,10,10));

        ScrollPane msgPane = new ScrollPane();
        msgPane.setPrefSize(280, 280);
        msgPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);

        GridPane msgPaneContent = new GridPane();
        msgPaneContent.setPrefWidth(270);
        msgPaneContent.setVgap(10);

        FlowPane writePane = new FlowPane(10,10);
        writePane.setAlignment(Pos.CENTER);
        writePane.setPrefWidth(280);

        TextField writeMsg = new TextField();
        writeMsg.setPrefWidth(200);
        writeMsg.setPromptText("Write your message");

        Button send = new Button("Send");


        send.setOnAction((ev) -> {
            TextArea msg = new TextArea(writeMsg.getText());
            msg.setMaxWidth(135);
            msg.setPrefRowCount(msg.getLength()/21 + 1);
            msg.setWrapText(true);

            GridPane.setConstraints(msg, 0, indexMsg++); 

            writeMsg.deleteText(0, writeMsg.getText().length());
            msgPaneContent.getChildren().add(msg);

            String message = msg.getText();

            pw.write(message);
            System.out.println("Sent " + msg.getText());

        });

        writePane.getChildren().addAll(writeMsg, send);

        GridPane.setConstraints(msgPane, 0, 0);
        GridPane.setConstraints(writePane, 0, 1);

        msgPane.setContent(msgPaneContent);
        root.getChildren().addAll(msgPane, writePane);

        Scene scene = new Scene(root, 300, 300);

        primaryStage.setTitle("Chat App");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws IOException {

        launch(args);

    }

}

接收者线程

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class ChatServer extends Thread {

    ServerSocket server;
    Socket socket;
    BufferedReader br;
    PrintWriter pw;

    public ChatServer() throws IOException {
        server = new ServerSocket(56700);
        socket = server.accept();
        br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        pw = new PrintWriter(socket.getOutputStream());

    }

    public void run() {
        String msg = null;

        while (true) {

            try {
                msg = br.readLine();
            } catch (IOException ex) {
                System.out.println("Error");
            }

            System.out.println(msg);
        }
    }

    public static void main(String[] args) throws IOException, InterruptedException {

        (new ChatServer()).start();
    }

}

1 个答案:

答案 0 :(得分:1)

您的邮件不包含行尾字符。服务器中的readLine()方法读取流中的所有内容,查找行结束标记,然后连接所有字符以形成文本行。所以你需要从客户端发送一个行尾字符。

您还应该在发送消息后刷新打印编写器 - 否则打印写入可能会在实际发送之前缓冲许多消息:

send.setOnAction((ev) -> {
    TextArea msg = new TextArea(writeMsg.getText());
    msg.setMaxWidth(135);
    msg.setPrefRowCount(msg.getLength()/21 + 1);
    msg.setWrapText(true);

    GridPane.setConstraints(msg, 0, indexMsg++); 

    writeMsg.deleteText(0, writeMsg.getText().length());
    msgPaneContent.getChildren().add(msg);

    String message = msg.getText();

    pw.write(message + "\n");
    pw.flush();

    System.out.println("Sent " + msg.getText());

});