问题描述
我正在尝试创建一个程序,该程序可以从选择框、复选框和文本字段中获取数据,并将其放入单个 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;
}
}
}