19

I want the user to enter information again in the first while loop after pressing any key on the keyboard. How do I achieve that? Am I doing something wrong with the while loops. SHould I just have one while loop?

 import java.util.Scanner;

 public class TestMagicSquare
 {
  public static void main(String[] args)
 {    
    boolean run1 =  true;
    boolean run2 = true;

    Square magic = new Square();

    Scanner in = new Scanner(System.in);

    while(run1 = true)
    {
        System.out.print("Enter an integer(x to exit): ");
        if(!in.hasNextInt())
        {
            if(in.next().equals("x"))
            {
                break;
            }

            else
            {
                System.out.println("*** Invalid data entry ***");               
            }                    
        }
        else
        {
            magic.add(in.nextInt());
        }
     }

    while(run2 = true)
    {
        System.out.println();
        if(!magic.isSquare())
        {
            System.out.println("Step 1. Numbers do not make a square");            
            break;
        }
        else
        {
            System.out.println("Step 1. Numbers make a square");
        }

        System.out.println();
        if(!magic.isUnique())
        {
            System.out.println("Step 2. Numbers are not unique");
            break;
        }
        else
        {
            System.out.println("Step 2. Numbers are unique");
        }

        System.out.println();
        magic.create2DArray();
        if(!magic.isMagic())
        {
            System.out.println("Step 3. But it is NOT a magic square!");
            break;
        }
        else
        {
            System.out.println("Step 3. Yes, it is a MAGIC SQUARE!");
        }

        System.out.println();
        System.out.print("Press any key to continue...");// Here I want the simulation
        in.next();
        if(in.next().equals("x"))
        {
            break;
        }
        else
        {
            run1 = true;
        }
      }
    }

   }
user2840682
  • 381
  • 2
  • 11
  • 23
  • 1
    You can't. Basically Java's implementation of the stdin will only return when the use presses [Enter]. You could use a JNA or JNI solution, but that might be more work then is worth it... – MadProgrammer Nov 08 '13 at 23:42
  • 1
    Add an action listener to the keyboard. – Isaiah Taylor Nov 08 '13 at 23:44
  • What are you doing with all those `runx` booleans? You only assign `true` values to them all the time. What's their purpose? – Andrei Nicusan Nov 08 '13 at 23:45
  • I am just going to link to this question: http://stackoverflow.com/questions/1066318/how-to-read-a-single-char-from-the-console-in-java-as-the-user-types-it . The top answer may give you some insight. – Lan Nov 08 '13 at 23:50

5 Answers5

26

You can create this function (good only for enter key) and use it where ever you want in your code:

 private void pressEnterToContinue()
 { 
        System.out.println("Press Enter key to continue...");
        try
        {
            System.in.read();
        }  
        catch(Exception e)
        {}  
 }

If your useing Scanner:

 private void pressEnterToContinue()
 { 
        System.out.println("Press Enter key to continue...");
        try
        {
            System.in.read();
            scanner.nextLine();
        }  
        catch(Exception e)
        {}  
 }
jacob
  • 25
  • 1
  • 9
E235
  • 11,560
  • 24
  • 91
  • 141
3

1) See while(run1 = true) and while(run2 = true)

= is assignment operator in java. use == operator to compare primitives

2) You can do like this

while(in.hasNext()){

}
Prabhakaran Ramaswamy
  • 25,706
  • 10
  • 57
  • 64
  • `true` (if you indulge the pun of words), but that doesn't solve OP's issue. Actually an infinite loop is a very common choice to have with a `Scanner`. – Mena Nov 08 '13 at 23:50
  • was about to answer. I'll +1 your answer only because nothing in it is wrong per se, yet you aren't solving OP's issue. However, solving OP's issue would imply recoding half his/her mess, so I'm voting to close instead. – Mena Nov 08 '13 at 23:55
2

My answer still only works with the Enter key but it does so without leaving stuff on the input stream that could get in the way later (System.in.read() can potentially leave things on the stream that get read in on the next input). So I read the whole line (here I use Scanner but I guess that isn't actually necessary, you just need something to get rid of the entire line in the input stream):

public void pressEnterKeyToContinue()
{ 
        System.out.println("Press Enter key to continue...");
        Scanner s = new Scanner(System.in);
        s.nextLine();
}
Jay Laughlin
  • 154
  • 1
  • 8
1

Before getting into implementation details, I think you need to step back and re-examine your algorithm a bit. From what I gather, you want get a list of integers from the user and determine if they form a magic square. You can do the first step in a single while loop. Something like this pseudo-code:

while (true)
    print "Enter an integer (x to stop): "
    input = text from stdin
    if input is 'x'
        break
    else if input is not an integer
        print "non integer value entered, aborting..."
        return
    else
        add input to magic object

After that, you can output details about the numbers:

if magic is a magic square
    print "this is a magic square"
else
    print "this is not a magic square"

// etc, etc.....
upcrob
  • 165
  • 11
0

https://darkcoding.net/software/non-blocking-console-io-is-not-possible/

Go to the section Java non-blocking console input on Linux.

for your code, you could move your main() number computation to a new function magicSquare() and have it return false when

and modify the code linked like this


import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;

public class test {
    private static String ttyConfig;

/*
returns true if properly exiting, return false if exiting before all numbers were received from input
 */
    public static boolean magicSquare() {

        int nums = 0;

        Square magic = new Square();

        Scanner in = new Scanner(System.in);

        while (nums<2) {
            System.out.print("Enter an integer(x to exit): ");
            if (!in.hasNextInt()) {
                if (in.next().equals("x")) {
                    return false;
                } else {
                    System.out.println("*** Invalid data entry ***");
                }
            } else {
                nums++;
                magic.add(in.nextInt());
            }
        }

        System.out.println();
        if (!magic.isSquare()) {
            System.out.println("Step 1. Numbers do not make a square");
            return true;
        } else {
            System.out.println("Step 1. Numbers make a square");
        }

        System.out.println();
        if (!magic.isUnique()) {
            System.out.println("Step 2. Numbers are not unique");
            return true;
        } else {
            System.out.println("Step 2. Numbers are unique");
        }

        System.out.println();
        magic.create2DArray();
        if (!magic.isMagic()) {
            System.out.println("Step 3. But it is NOT a magic square!");
        } else {
            System.out.println("Step 3. Yes, it is a MAGIC SQUARE!");
        }
        return true;
    }

    public static void main(String[] args) {
        try {
            setTerminalToCBreak();
            boolean callMagicSquare = true;
            boolean run = true;
            while (run) {
                if (callMagicSquare) {
                    resetTerminal();  // sets console to get input only after enter is pressed
                    run = magicSquare();
                    System.out.println("Press any key except \'x\' to continue");
                    setTerminalToCBreak(); // sets console to read any key press prior
                    callMagicSquare = false;
                }
                
                if (System.in.available() != 0) {
                    int c = System.in.read();
                    if ((char) c == 'x') {
                        break;
                    } else {
                        callMagicSquare = true;
                        continue;
                    }
                }
            } // end while
        } catch (IOException e) {
            System.err.println("IOException");
        } catch (InterruptedException e) {
            System.err.println("InterruptedException");
        } finally {
            resetTerminal();
        }
    }

    private static void resetTerminal() {
        try {
            stty(ttyConfig.trim());
        } catch (Exception e) {
            System.err.println("Exception restoring tty config");
        }
    }

    private static void setTerminalToCBreak() throws IOException, InterruptedException {

        ttyConfig = stty("-g");

        // set the console to be character-buffered instead of line-buffered
        stty("-icanon min 1");

        // disable character echoing
        stty("-echo");
    }

    /**
     * Execute the stty command with the specified arguments
     * against the current active terminal.
     */
    private static String stty(final String args)
            throws IOException, InterruptedException {
        String cmd = "stty " + args + " < /dev/tty";

        return exec(new String[]{
                "sh",
                "-c",
                cmd
        });
    }

    /**
     * Execute the specified command and return the output
     * (both stdout and stderr).
     */
    private static String exec(final String[] cmd)
            throws IOException, InterruptedException {
        ByteArrayOutputStream bout = new ByteArrayOutputStream();

        Process p = Runtime.getRuntime().exec(cmd);
        int c;
        InputStream in = p.getInputStream();

        while ((c = in.read()) != -1) {
            bout.write(c);
        }

        in = p.getErrorStream();

        while ((c = in.read()) != -1) {
            bout.write(c);
        }

        p.waitFor();

        String result = new String(bout.toByteArray());
        return result;
    }


}