Question

I am writing a java program that runs a loop and keeps asking the user for input. The program then does a bunch of things with the string, and asks for another string and repeats.

The issue is that many strings are very similar, so i would like to populate the prompt with the input from the last time in the loop. For instance: If the user enters a value as follows:

Enter the SKU Number: APE-6603/A

... Then the next time it asks for an SKU, it will wait till the user presses enter as normal, but be ready with the last value before the user even types anything:

Enter the SKU Number: APE-6603/A

... And the user can make simple changes very fast like replace the /A with /B and press enter! If the string that holds the user input is called "lookFor", is there a way to populate the prompt with this value in Java? It would be VERY useful!

Thanks!

Était-ce utile?

La solution

After discussing this idea with a few people, it seems that what i want is not possible. The way of input is too simple to allow something like this.

My only possible solutions involve not running this from my IDE. I can either elect to use my application, or change the application into a GUI based applet. Running from the console will open up the "Press up" option, as suggested by rchirino, and using a GUI would let the value entered sit there for editing later.

If anyone is looking to do what i posted above, the answer is "Java cant do it!". Sorry. :)

Autres conseils

You might want to try something like this:

public String promptandgetWithShowDefault(String prompt, String supplied) {
  String prmpt = prompt + " (press Enter for \"" + supplied + "\"):";
  String tmpch = null;
  System.out.print(prmpt);
  tmpch = scanner.nextLine().trim();
  if (tmpch == null || tmpch.equals("")) {
     return supplied;
  } else {
     return tmpch;
  }
}

If the goal is to get a simple binar answer from the user like:

     Would you like to do that? (  y / n  ) y 

then the empty string returned by the user, in the answer from Dmv, will do the trick, except that when the user types "n" or attempts to delete the trailing "y", it won't disappear, so it would then be clearer to write the prompt like:

    Would you like to do that? ( [ y ] / n )

But when the goal is to get a long string, like the original question or a file path for instance, that the user can edit to correct a typo or not to overwrite previous file .... then you definitely need something else which doesn't seem to be available in Java.

Well do it in C then!!! with the help of libreadline...

it's probably possible, easier and more portable to do the same trick in Python, but I have no idea how to code in Python.

Here is a simple Java MRE to illustrate it:

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;

public class Main
{
    public static void main(String[] args)
    {
        String path = System.getProperty("user.home") + File.separatorChar + "Documents";
        File file = null;
        do {
            path = askForString("Enter the filepath to open:", path );
            if ( ( path == null) || ( path.isBlank())) break;
            file = new File( path );
        } while ( ! file.exists() );
        System.out.println("Openning " + path + "....");
        // ......
    }
    public static String askForString( String message, String defaultString)
    {
        String response = null;
        System.out.println( message);
        // any extra String in cmd[] will be added in readline history
        String[] cmd = { "/path/to/executable/ask4stringWdefault", defaultString};
        try
        {
          ProcessBuilder pb = new ProcessBuilder(cmd);
          // Make sure the subprocess can print on console and capture keyboard events
          pb.redirectInput(ProcessBuilder.Redirect.INHERIT); 
          pb.redirectOutput(ProcessBuilder.Redirect.INHERIT);
          Process p = pb.start();
          BufferedReader stderrBuffer = new BufferedReader(new InputStreamReader(p.getErrorStream()));
          int retcode= p.waitFor();
          if ( retcode != 0)
          {
               System.err.println("The process terminated with error code: " + retcode + "\n" + stderrBuffer.readLine());
               return null;
          }
          response = stderrBuffer.readLine();
        } catch( Exception e) {
            e.printStackTrace();
        }
        return response;
    }
}

To build the executable "ask4stringWdefault" you need first to get the GNU Readline Library utility and compile it, ideally cross-compile for any platform Java supports, to get a static library that you will link while compiling ( or cross-compiling ) the following C script:

#include <stdio.h>
#include <stdlib.h>
#include <readline/readline.h>
#include <readline/history.h>

const char *defstr;
int prefill(const char *txt, int i);
int main(int argc, const char * argv[])
{
    if ( argc < 2)
    {
        fprintf(stderr, "You must provide a default value\n");
        return -1;
    } else if ( argc > 2) {
        // * optional extra values can be passed to populate history * //
        if ( argc > 255) argc = 255;
        for ( unsigned char i=0; i < argc; i++)
        {
            add_history(argv[i]);
        }
    }
    defstr = argv[1];
    char *cbuffer;
    rl_startup_hook = prefill;
    if ((cbuffer = readline(NULL)) == NULL) /* if the user sends EOF, readline will return NULL */
        return 1;
    fprintf( stderr, "%s\n", cbuffer);
    free(cbuffer);
    return 0;
}
int prefill(const char *t, int i)
{
    rl_insert_text(defstr);
    return 0;
}

The result is printed on stderr as it is the only stream that Java can keep track of, stdout and stdin being under the control of the executable subprocess itself.

It works fine on a Mac with arm64 architecture, using Eclipse you can't actually edit the default provided, any character typed at the prompt will be append to default string, but just hitting return will send unchanged default value back, which can be enough for basic testing.

I think I understand what you want to do, but it's rather simple. If your program is a console application (command-line), which I'll assume, then you just need to press the UP key to populate the prompt with the last typed characters.

If you're working with GUI elements then you can check the API documentation for the particular class of object you're using and check out it's fields.

Hope this helps!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top