【问题标题】:Is there a better way to process user text in this way?有没有更好的方法来以这种方式处理用户文本?
【发布时间】:2026-01-11 03:55:01
【问题描述】:

我希望有一个标签和一个文本框。在文本框中,用户键入标签中的内容,例如打字测试。如果用户键入正确的字符,则标签中的字符变为绿色。

我将在 JavaFX 中实现这一点。我基本上会将标签转换为一个数组,看看它是否与文本框中的任何内容匹配。我不确定我需要用什么来检查文本框字符是否与数组匹配。

【问题讨论】:

  • “将标签转换为数组”——数组是什么?人物?为什么不直接使用字符串?
  • if (label.getText().startsWith(textField.getText())) { ... }...?不过,在开始之前,您可能需要注意文本字段中的所有文本都必须是相同的颜色:如果您希望不同的字母具有不同的颜色,TextField 根本不支持...

标签: java javafx key-events


【解决方案1】:

我编写了一个简单的测试 JavaFX 应用程序,可以满足您的要求。

这是结果

这是代码

package sample;

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        primaryStage.setTitle("Hello World");
        Scene scene = new Scene(new Group(), 300, 275);

        //Create a FlowPane that will contain many Text.
        FlowPane flowLabel = new FlowPane(Orientation.HORIZONTAL);
        flowLabel.setBackground(new Background(new BackgroundFill(Color.BEIGE, CornerRadii.EMPTY, Insets.EMPTY)));
        flowLabel.setColumnHalignment(HPos.LEFT);

        //This is the label text. The text that the user must insert
        final String text = "Hello world!";

        //Create a Text object for each character
        final Text[] characters = new Text[text.length()];
        for(int i = 0; i < text.length(); i++) {
            Character c = text.charAt(i);
            characters[i] = new Text(c.toString());
            flowLabel.getChildren().add(characters[i]);
        }

        //Create the text field and add a listener to do something when the text change.
        TextField field = new TextField();
        field.textProperty().addListener(new ChangeListener<String>() {
            @Override
            public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
                //Do the magic
                String fieldText = newValue;
                if(text.startsWith(fieldText)) {
                    for(int i = 0; i < text.length(); i++) {
                        if(i < fieldText.length()) {
                            characters[i].setFill(Color.GREEN);
                        } else {
                            characters[i].setFill(Color.BLACK);
                        }
                    }
                } else {
                    for(int i = 0; i < text.length(); i++) {
                        characters[i].setFill(Color.RED);
                    }
                }
            }
        });

        FlowPane pane = new FlowPane(Orientation.HORIZONTAL);
        pane.setVgap(8);
        pane.getChildren().add(flowLabel);
        pane.getChildren().add(field);

        ((Group)scene.getRoot()).getChildren().add(pane);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

我认为这不是最好的方法,但会帮助您继续。

【讨论】:

    【解决方案2】:

    我在我的版本中使用了 onkeyreleased。它现在处理空间:

    import java.util.ArrayList;
    import java.util.List;
    import javafx.application.Application;
    import javafx.event.EventHandler;
    import javafx.scene.Scene;
    import javafx.scene.control.TextArea;
    import javafx.scene.input.KeyEvent;
    import javafx.scene.layout.HBox;
    import javafx.scene.layout.VBox;
    import javafx.scene.paint.Color;
    import javafx.scene.text.Text;
    import javafx.stage.Stage;
    
    /**
     *
     * @author blj0011
     */
    public class JavaFXApplication35 extends Application {
    
        @Override
        public void start(Stage primaryStage) {        
    
            //Make each string char a text object
            String text = "Hello World!";
            List<Text> characters = new ArrayList();
            for(int i = 0; i < text.length(); i++)
            {
                characters.add(new Text(text.charAt(i) + ""));
            }
    
            //create text area and set on key release listener
            TextArea textarea = new TextArea();
            textarea.setOnKeyReleased(new EventHandler<KeyEvent>(){
                @Override
                public void handle(KeyEvent event) {                
                    for(int i = 0; i < characters.size(); i++)
                    {        
                        //handle when index i is less than the number of characters typed in the text area
                        if(i < textarea.getText().length())
                        {
                            //if the characters at the given index are equal, set the text object at that index to green
                            if(textarea.getText().charAt(i) == characters.get(i).getText().charAt(0))
                            {
                                characters.get(i).setFill(Color.GREEN);//If chars at given index are equal set to green: exception - space
                                if(textarea.getText().charAt(i)== '_')//Your text charters can not be char underscore by default. If so this will screw up.
                                {//if underscore is type make the space red even though it equals the red underscore
                                    characters.get(i).setText("_"); 
                                    characters.get(i).setFill(Color.RED);
                                }
                                else if(characters.get(i).getText().equals("_") && characters.get(i).getFill().equals(Color.RED)) 
                                {//if the text object was changed to underscore and the textarea char is now a space, change the text object back to space
                                    if(textarea.getText().charAt(i) == ' ')
                                    {
                                        characters.get(i).setText(" ");
                                    }                                
                                }
                            }                        
                            else//if the characters at the given index are not equal, set the text object at that index to red
                            {                            
                                if(characters.get(i).getText().equals(" "))
                                {
                                    characters.get(i).setText("_");
                                }
                                characters.get(i).setFill(Color.RED);
                            }
                        }
                        else//handle when index i is greater than or equally to the number of characters typed in the text area
                        {
                            characters.get(i).setFill(Color.BLACK);//set the text object at given index to black if the hasn't been enough charaters type to reach this index
                            if(characters.get(i).getText().equals("_"))
                            {
                                characters.get(i).setText(" ");
                            }
                        }
                    }
                }
            });
    
    
            HBox hbox = new HBox();//holds text objects
            hbox.getChildren().addAll(characters);//add text objects to hbox   
            VBox root = new VBox();//holds hbox and textarea
            root.getChildren().addAll(hbox, textarea);//add hbox. add textarea
    
            Scene scene = new Scene(root, 300, 250);
    
            primaryStage.setTitle("Hello World!");
            primaryStage.setScene(scene);
            primaryStage.show();
        }
    
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) {
            launch(args);
        }
    
    }
    

    注意:您的字符串文本不能包含下划线字符“_”。如果是这样,它将始终是红色的。

    【讨论】:

      最近更新 更多