Thompadude
Thompadude

Reputation: 21

Is there a way to print out a String in console which the user can edit?

My question is about Java.

Is there a way to print out a String in the console when using Scanner so the user can edit and/or add more to it?

For example...

String aString = "Hello!"
System.out.println("Write some text, please.");
aString = scanner.nextLine();

And now I want some sort of System.out of aString but editable. I want the user to be able to simply edit aString. When user finish editing, Scanner will save everything to aString again.

My solution right now is I let the user input some new text and then just add it to the end of the String using:

    aString += scanner.nextLine();

Appreciate any help. Thank you.

Upvotes: 2

Views: 947

Answers (1)

Julian Wright
Julian Wright

Reputation: 705

You may be able to approach what you want with the Robot class. Try the following, for example:

import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.util.Scanner;

public class RobotText {

    static private Robot robot;

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.println("Enter some text, blank line to end.");
        int count = 1;
        while (true) {
            System.out.print("?>");
            insert("Line " + count);
            count++;
            String line = input.nextLine();
            if (line.length() == 0) break;
            System.out.println("You entered '" + line + "'");
        }
        System.out.println("That's all folks!");
        input.close();
    }

    private static void insert(String text) {
        if (robot == null) {
            // Lazily initialise the robot
            try {
                robot = new Robot();
                robot.setAutoDelay(5);
                robot.setAutoWaitForIdle(true);
            } catch (AWTException e) {
                e.printStackTrace();
            }
        }
        char[] chars = text.toCharArray();
        for (char c : chars) {
            int code = KeyEvent.getExtendedKeyCodeForChar(c);
            robot.keyPress(code);
            robot.keyRelease(code);
        }
    }
}

This inserts the text you want the user to edit as keystrokes, before using the Scanner to read the resulting line. Note - don't insert a newline or the user will never get a chance to type!

Unfortunately you will still be at the mercy of whatever line editing facility is provided by the shell you run your application from. In my case that means that all the user can do with the above is backspace over as much of the pre-entered text as needed before retyping a replacement.

To avoid this you will need to replace the use of Scanner with something a bit more sophisticated. I haven't tried it, but it looks like JLine may fill your needs here.

For extreme overkill, in an environment where a GUI can run, or if for some reason you are not able to add new jars to your classpath, you could also use JOptionPane for input:

    ...
    while (true) {
        String line = JOptionPane.showInputDialog("Enter some text","Line "+count);
        count++;
        if (line == null || line.length() == 0) break;
        System.out.println("You entered '" + line + "'");
    }
    ...

This does start up a new Swing Event thread for each line of input, and then shut it down again afterwards, so it really is using a cannon to kill a fly! But of course it requests input in a separate window from the console, which may deviate too far from your goal.

Ultimately the answer would be to give your application a graphical interface, as every text input widget provided by every toolkit I've ever met allows you to pre-initialise the widget with text that can be subsequently edited by the user. I shall leave the choice of toolkit and the implementation as an exercise to the reader. :)

Upvotes: 1

Related Questions