有没有更好的方法以这种方式处理用户文本?

时间:2017-02-20 00:59:04

标签: java javafx key-events

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

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

2 个答案:

答案 0 :(得分:0)

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

这是结果

The result

这是代码

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);
    }
}

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

答案 1 :(得分:0)

  

我在我的版本中使用了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);
    }

}
  

注意:您的String文本不能包含下划线字符&#39; _&#39;。如果确实如此,它将永远是红色的。