【问题标题】:Writing to OutputStream in JavaFX setOnAction() method在 JavaFX setOnAction() 方法中写入 OutputStream
【发布时间】:2017-08-24 21:24:13
【问题描述】:

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

我有两个类:其中之一是接口(@98​​7654323@)。它有一个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();
    }

}

【问题讨论】:

    标签: java javafx


    【解决方案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());
    
    });
    

    【讨论】:

    • 没错,两次更正都是必要的!非常感谢。
    • 顺便说一句:在用户界面线程上发送网络 I/O 可能会导致应用程序无响应。
    猜你喜欢
    • 1970-01-01
    • 2011-06-18
    • 1970-01-01
    • 2016-10-19
    • 1970-01-01
    • 1970-01-01
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多