-3

I want there to be a label and a textbox. In the textbox the user types in what is in the label, like a typing test. If the user types the right character in then the character in the label becomes green.

I am going to implement this in JavaFX. I will basically transform the label into an array and see if it matches anything in the textbox. I'm not sure what I need to use to to check if the textbox character matches the array.

Ken White
  • 123,280
  • 14
  • 225
  • 444
xAnnette97
  • 13
  • 3
  • "transform the label into an array" - an array of what? Characters? Why not just use a String? – D M Feb 20 '17 at 01:10
  • 1
    `if (label.getText().startsWith(textField.getText())) { ... }`...? Before you start, though, you might want to note that all the text in a text field has to be the same color: if you are intending different letters to be different colors, `TextField` simply won't support that... – James_D Feb 20 '17 at 01:12

2 Answers2

0

I wrote a simple test JavaFX application that do what you are asking.

This is the result

The result

And this is the code

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

I think that this isn't the best way to do that, but will help you to proceed.

Flood2d
  • 1,338
  • 8
  • 9
0

I used onkeyreleased in my version. It now handles space:

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

}

Note: Your String text can not contain the underscore character '_'. It will always be red if it does.

SedJ601
  • 12,173
  • 3
  • 41
  • 59