如何使用 JavaFX 将选择框、复选框和文本字段实现为一个按钮

问题描述

我正在尝试创建一个程序,该程序可以从选择框、复选框和文本字段中获取数据,并将其放入单个 textArea 作为输出。我怎样才能通过一个按钮将所有信息结合起来。我已经创建了选择框、复选框和文本字段。

-有两个文本字段。其中一个需要一个名字,另一个需要一个数字。该数字将决定程序循环的次数

-复选框将采用什么样的前缀放在名字前面(先生、女士等)。

-选择框给出了将给出什么后续语句的选项。 (你今天过得怎么样?,我喜欢你的帽子等)

点击按钮后,如果 textField 中的数字输入为 2,程序将在 textArea 中显示类似内容

“1约翰逊先生你好。你今天过得怎么样?”

“2约翰逊先生你好。你今天过得怎么样?”

这就是我在按钮事件处理程序中的内容。它只实现了文本字段

 private class CreateButtonHandler implements EventHandler<ActionEvent> {
        @Override
        public void handle(ActionEvent event) {
        int i = 0;
        String myString = number.getText();
        int foo = Integer.parseInt(myString);
        do {
             OutputTxtArea.setText(OutputTxtArea.getText() + (i + 1) + "Hello " + firstNameTxtFld.getText() + "\n");
        } while(i<foo);
}
}

解决方法

绑定!

如果将布局与数据和动作分开,然后让动作处理数据,事情就会更容易。这使屏幕只是一个屏幕,您不必担心“我如何处理获取 CheckBox 值?”诸如此类的问题。

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import org.jetbrains.annotations.NotNull;

import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class Greeter extends Application {

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

    @Override
    public void start(Stage primaryStage) {
        Model model = new Model();
        ChoiceBox<String> questionChoiceBox = new ChoiceBox<>(model.questionList);
        TextArea textArea = new TextArea("");
        textArea.textProperty().bind(model.greetingProperty());
        VBox vBox = new VBox(20,createBoundCheckBox("Miss",model.isMissProperty()),createBoundCheckBox("Missus",model.isMissusProperty()),createBoundCheckBox("Mister",model.isMisterProperty()),questionChoiceBox,createBoundTextField(model.nameProperty()),createBoundTextField(model.loopCountProperty()),textArea);
        primaryStage.setScene(new Scene(vBox,200,300));
        primaryStage.show();
    }

    @NotNull
    private Node createBoundCheckBox(String label,BooleanProperty boundProperty) {
        CheckBox checkBox = new CheckBox(label);
        boundProperty.bind(checkBox.selectedProperty());
        return checkBox;
    }

    private Node createBoundTextField(StringProperty boundProperty) {
        TextField textField = new TextField();
        boundProperty.bind(textField.textProperty());
        return textField;
    }

    class Model {
        private StringProperty loopCount = new SimpleStringProperty("");
        private BooleanProperty isMister = new SimpleBooleanProperty(false);
        private BooleanProperty isMissus = new SimpleBooleanProperty(false);
        private BooleanProperty isMiss = new SimpleBooleanProperty(false);
        private StringProperty name = new SimpleStringProperty("");
        private StringProperty question = new SimpleStringProperty("");
        private ObservableList<String> questionList = FXCollections.observableArrayList();

        Model() {
            questionList.add("How was your day?");
            questionList.add("Would you like kippers for breakfast");
        }

        public StringProperty loopCountProperty() {
            return loopCount;
        }

        public BooleanProperty isMisterProperty() {
            return isMister;
        }

        public BooleanProperty isMissusProperty() {
            return isMissus;
        }

        public BooleanProperty isMissProperty() {
            return isMiss;
        }

        public StringProperty nameProperty() {
            return name;
        }

        public StringProperty questionProperty() {
            return question;
        }

        public ObservableList<String> getQuestionList() {
            return questionList;
        }

        public ObservableValue<String> greetingProperty() {
            return Bindings.createStringBinding(() -> buildGreeting(),loopCount,isMiss,isMissus,isMister,question,name);
        }

        private String buildGreeting() {
            int howMany;
            try {
                howMany = Integer.parseInt(loopCount.get());
            } catch (Exception e) {
                return "";
            }
            String title = "Master of Time and Space";
            if (isMiss.get()) {
                title = "Miss";
            }
            if (isMissus.get()) {
                title = "Mrs.";
            }
            if (isMister.get()) {
                title = "Mr.";
            }
            String greeting = "Hello " + title + " " + name.get() + " " + question.get();
            return IntStream.range(1,howMany + 1).mapToObj(idx -> idx + greeting).collect(Collectors.joining("\n"));
        }
    }
}

所以现在布局只是一个布局,屏幕上的所有控件都将其值属性绑定到模型。然后模型具有将所有内容组合在一起以创建结果的代码。从技术上讲,该代码应该属于某种业务逻辑类,但这至少应该给你一个想法。

我省略了按钮,因为它并没有真正添加任何有意义的功能,而且它的 UI 有点问题。无法指示 TextArea 中的结果是否是最后一次按钮单击的当前结果。例如,您可以单击按钮,然后选择另一个标题复选框,现在屏幕上的选择与 TextArea 不匹配。但是用户无法知道这一点,要实现它,您可能必须使用 DirtyFX 库之类的东西。

但是如果你真的想要一个按钮,那么你所要做的就是为结果引入一个新的 StringProperty,然后让按钮在它的 EventHandler 中调用 Model.buildGreeting():

import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import org.jetbrains.annotations.NotNull;

import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class GreeterButton extends Application {

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

    @Override
    public void start(Stage primaryStage) {
        Model model = new Model();
        ChoiceBox<String> questionChoiceBox = new ChoiceBox<>(model.questionList);
        TextArea textArea = new TextArea("");
        textArea.textProperty().bind(model.greetingProperty());
        Button button = new Button("Say Hi!");
        button.setOnAction(evt -> model.updateGreeting());
        VBox vBox = new VBox(20,button,BooleanProperty boundProperty) {
        CheckBox checkBox = new CheckBox(label);
        boundProperty.bind(checkBox.selectedProperty());
        return checkBox;
    }

    private Node createBoundTextField(StringProperty boundProperty) {
        TextField textField = new TextField();
        boundProperty.bind(textField.textProperty());
        return textField;
    }

    class Model {
        private StringProperty loopCount = new SimpleStringProperty("");
        private BooleanProperty isMister = new SimpleBooleanProperty(false);
        private BooleanProperty isMissus = new SimpleBooleanProperty(false);
        private BooleanProperty isMiss = new SimpleBooleanProperty(false);
        private StringProperty name = new SimpleStringProperty("");
        private StringProperty question = new SimpleStringProperty("");
        private StringProperty greeting = new SimpleStringProperty("");
        private ObservableList<String> questionList = FXCollections.observableArrayList();

        Model() {
            questionList.add("How was your day?");
            questionList.add("Would you like kippers for breakfast");
        }

        public StringProperty loopCountProperty() {
            return loopCount;
        }

        public BooleanProperty isMisterProperty() {
            return isMister;
        }

        public BooleanProperty isMissusProperty() {
            return isMissus;
        }

        public BooleanProperty isMissProperty() {
            return isMiss;
        }

        public StringProperty nameProperty() {
            return name;
        }

        public StringProperty questionProperty() {
            return question;
        }

        public ObservableList<String> getQuestionList() {
            return questionList;
        }

        String buildGreeting() {
            int howMany;
            try {
                howMany = Integer.parseInt(loopCount.get());
            } catch (Exception e) {
                return "";
            }
            String title = "Master of Time and Space";
            if (isMiss.get()) {
                title = "Miss";
            }
            if (isMissus.get()) {
                title = "Mrs.";
            }
            if (isMister.get()) {
                title = "Mr.";
            }
            String greeting = "Hello " + title + " " + name.get() + " " + question.get();
            return IntStream.range(1,howMany + 1).mapToObj(idx -> idx + greeting).collect(Collectors.joining("\n"));
        }

        public void updateGreeting() {
            greeting.set(buildGreeting());
        }

        public StringProperty greetingProperty() {
            return greeting;
        }
    }
}