JavaFx 聊天 TextField 和按钮键侦听器

JavaFx Chat TextField and Button Key Listener

我是一个使用 javafx 进行简单聊天的初学者,我已经搜索过类似的问题,但没有找到合适的解决方案。我需要做的第一件事是图形。我的第一个问题是,我的按钮的 MousEvent 侦听器不工作,我只是无法以某种方式单击按钮。我的第二个问题是,一旦应用程序 运行ning 并且我在 TextField 之外的某个地方单击,我就无法 return 它并输入新文本。就像 TextField 的侦听器一样,不再 运行 侦听 KeyStroke 事件。代码:

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.ScrollPane.ScrollBarPolicy;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class ChatView extends Application {
    String s;

    @Override
    public void start(Stage stage){
        s = "";
        StackPane rootPane = new StackPane();
        TextField enterMessageField = new TextField();
        enterMessageField.setEditable(true);


        TextArea displayAllMessages = new TextArea();   
        displayAllMessages.setPrefHeight(500);
        displayAllMessages.setEditable(false);
        ScrollPane scrollPane = new ScrollPane();
        scrollPane.setContent(displayAllMessages);
        scrollPane.setVbarPolicy(ScrollBarPolicy.ALWAYS);
        displayAllMessages.setPrefWidth(650);

        Button button = new Button("Send Message");

        VBox vBoxChat = new VBox();
        vBoxChat.setPadding(new Insets(650, 200, 20, 20));
        vBoxChat.getChildren().addAll( enterMessageField);

        VBox vBoxChatIncoming = new VBox();
        vBoxChatIncoming.setPadding(new Insets(20, 20, 20, 20));
        vBoxChatIncoming.getChildren().addAll( scrollPane);

        VBox vBoxEnter = new VBox();
        vBoxEnter.setPadding(new Insets(650, 20, 20, 550));
        vBoxEnter.getChildren().add(button);


        rootPane.getChildren().addAll(vBoxChat, vBoxEnter, vBoxChatIncoming);
        Scene scene = new Scene(rootPane, 700, 700, Color.WHITE);
        stage.setScene(scene);
        stage.setTitle("Chat");
        stage.show();


        enterMessageField.setOnKeyPressed(new EventHandler <KeyEvent> () {
            @Override
            public void handle(KeyEvent event){

                if (event.getCode() == KeyCode.ENTER){
                    s = enterMessageField.getText() + "\n";
                    enterMessageField.setText("");
                    displayAllMessages.appendText(s);
                 }  


        }
        });

        button.setOnAction((event) -> {
            s = enterMessageField.getText() + "\n";
            enterMessageField.setText("");
            System.out.println(s);
            });

    }
    public static void main(String[] args){
        launch(args);

    }
}

感谢您的帮助!

我将 rootPane 更改为 GridPane,这解决了问题。

实际上 StackPane 不适合多组件界面的类型。在这里查看类似的问题:Mouse Events get Ignored on the Underlying Layer

查看下面的改进代码:

public class ChatView extends Application {
    String s = "";

    @Override
    public void start(Stage stage) {
        TextField enterMessageField = new TextField();
        enterMessageField.setEditable(true);

        TextArea displayAllMessages = new TextArea();
        displayAllMessages.setPrefHeight(500);
        displayAllMessages.setEditable(false);
        ScrollPane scrollPane = new ScrollPane();
        scrollPane.setContent(displayAllMessages);
        scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);
        displayAllMessages.setPrefWidth(650);

        Button button = new Button("Send Message");
        button.setDefaultButton(true);

        VBox vBoxChat = new VBox(enterMessageField);
        vBoxChat.setPadding(new Insets(10, 10, 10, 10));

        VBox vBoxChatIncoming = new VBox(displayAllMessages);
        vBoxChatIncoming.setPadding(new Insets(10, 10, 10, 10));

        VBox vBoxEnter = new VBox(button);
        vBoxEnter.setPadding(new Insets(10, 10, 10, 10));

        GridPane rootPane = new GridPane();
        rootPane.add(vBoxChatIncoming, 0, 0);
        rootPane.add(vBoxChat, 0, 1);
        rootPane.add(vBoxEnter, 1, 1);

        Scene scene = new Scene(rootPane, 800, 700, Color.WHITE);
        stage.setScene(scene);
        stage.setTitle("Chat");
        stage.show();

        enterMessageField.setOnKeyPressed(event -> {
            if (event.getCode() == KeyCode.ENTER) {
                s = enterMessageField.getText() + "\n";
                enterMessageField.setText("");
                displayAllMessages.appendText(s);
            }
        });

        button.setOnAction((event) -> {
            s = enterMessageField.getText() + "\n";
            enterMessageField.setText("");
            System.out.println(s);
        });
    }

    public static void main(String[] args) {
        launch(args);
    }
}