有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在JavaFX setOnAction()方法中写入OutputStream

我正在编写一个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) 个答案

  1. # 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());
    
    });