我正在尝试使我的第一个应用程序遇到障碍。该应用程序基本上只是一个简单的打字练习应用程序,在该应用程序中,为用户提供了他们要复制的字符串。我正在尝试实现对用户所犯错误数量进行计数的计数。
当前,我有使用侦听器观察用户输入到文本区域的字符串的代码。我有一个错误计数,每次用户字符串不等于提供的字符串时,都会添加一个错误计数,这是我只想对每个错误将1加到计数中。例如,当前如果您输入错误并键入2个错误的字符,则每次按下一个键时代码运行时,错误计数将上升为3,这意味着它将计算2个错误的字符和1个退格键来删除它们,我想这样做只将错误计数加1。
我当前拥有的代码如下:
public class MainController implements Initializable {
@FXML
private BorderPane errorStatus;
@FXML
private TextArea inputTextArea;
@FXML
public TextArea generatedText;
private String userText;
private String thePassage;
private Integer errorCount = 0;
private Boolean errorCheck = false;
timer time = new timer();
@Override
public void initialize(URL arg0, ResourceBundle arg1) {
thePassage = PassageData.getPassage();
generatedText.setText(thePassage);
inputTextArea.textProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> observable,
String oldValue, String newValue) {
if (!inputTextArea.getText().isEmpty()) {
time.start();
}
userText = newValue;
if (userText.equals("") || userText.equals(null)) {
errorStatus.setStyle(
"-fx-background-color: radial-gradient(radius 100%, white, white); -fx-background-radius: 10; -fx-border-radius: 10");
} else if (thePassage.regionMatches(0, userText, 0, userText.length())) {
errorCheck = false;
errorStatus.setStyle(
"-fx-background-color: radial-gradient(radius 100%, green, white); -fx-background-radius: 10; -fx-border-radius: 10");
} else {
errorCheck = true;
errorStatus.setStyle(
"-fx-background-color: radial-gradient(radius 100%, red, white); -fx-background-radius: 10; -fx-border-radius: 10");
}
if (userText.equals(thePassage)) {
thePassage = PassageData.getPassage();
generatedText.setText(thePassage);
Platform.runLater(() -> {
inputTextArea.clear();
});
errorStatus.setStyle(
"-fx-background-color: radial-gradient(radius 100%, white, white); -fx-background-radius: 10; -fx-border-radius: 10");
time.pause();
}
if (errorCheck) {
errorCount++;
System.out.println("Error count = " + errorCount);
}
}
});
}
}
答案 0 :(得分:4)
重复(跨多个问题),如果框架提供更高级别的支持,请不要使用低级别的侦听器!
在这种情况下,TextFormatter是对文本输入进行细粒度更改的高级支持,尤其是其过滤器属性。每当文本以任何方式更改(包括插入符号导航)时,此类过滤器都会收到通知,甚至允许修改更改-在textProperty更改之前的所有。
原始代码段,它将针对给定的文本计算错误-有关上下文,请参见the Zephyr's answer
UnaryOperator<TextFormatter.Change> filter = c -> {
if (c.isAdded()) {
// tbd: guard against off-range
int pos = c.getRangeStart();
if (!c.getText().equals(target.substring(pos, pos + 1))) {
errorCount.set(errorCount.get() +1);
}
}
return c;
};
textArea.setTextFormatter(new TextFormatter<>(filter));
答案 1 :(得分:0)
您将要为TextArea
设置一个更改侦听器,然后将输入String
的每个字符与输入文本的每个字符进行比较。
下面的MCVE演示了这一点:
import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
VBox root = new VBox(5);
root.setPadding(new Insets(10));
root.setAlignment(Pos.CENTER);
IntegerProperty errorCount = new SimpleIntegerProperty(0);
String target = "This is the sample text to be typed correctly.";
Label instructions = new Label(target);
TextArea textArea = new TextArea();
textArea.setWrapText(true);
HBox hbox = new HBox(5);
hbox.setAlignment(Pos.CENTER);
Label errorsLabel = new Label();
hbox.getChildren().addAll(new Label("Errors:"), errorsLabel);
// Bind the label to errorcount
errorsLabel.textProperty().bind(errorCount.asString());
// Listen for changes to the textArea text and check again target string
textArea.textProperty().addListener((observableValue, s, newValue) -> {
if (newValue != null) {
errorCount.set(getErrorCount(target, newValue));
}
});
root.getChildren().addAll(instructions, textArea, hbox);
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
private int getErrorCount(String target, String entered) {
int errors = 0;
// Compare each character in the strings
char[] targetChars = target.toCharArray();
char[] enteredChars = entered.toCharArray();
// Starting at the beginning of the entered text, check that each character, in order, matches the target String
for (int i = 0; i < enteredChars.length; i++) {
if (enteredChars[i] != targetChars[i]) {
errors++;
}
}
return errors;
}
}
因此,这里发生的是每次在TextArea
中键入(或删除)一个字符时,getErrorCount()
方法会将输入的文本与target
字符串进行比较。如果任何字符不正确,则会增加错误计数。
这与上面的注释中的“提交”按钮概念很相似,但是每次TextArea
中的文本更改时都执行该操作,不需要额外的按钮。