Eingabe vom Scanner erst bei bestimmter Position initiieren

Letzify

Grünschnabel
Hallo Community,

ich habe ein Problem mit dem Scanner und komme nicht auf die richtige Lösung. Wenn ich mein Programm starte, kann ich sofort eine Eingabe tätigen, obwohl das gar nicht gewünscht ist. Das führt dann im Folgeschritt zu einer Fehlmessung. Außerdem scheint er sich das "Enter" zu merken und im nächsten Schritt ungefragt wieder nutzen. Ich würde den Scanner deshalb gerne später initiieren und nach der Eingabe auch gleich schließen lassen.

Mit scan.close() hat es leider nicht funktioniert.

So sieht momentan der Code aus. Hoffentlich könnt ihr mir helfen. Der Scanner wird übrigens in der Klasse initiiert und deshalb hier nicht zu sehen. Egal wo ich ihn initialisiere, während des kompletten Programms kann ich eine Eingabe tätigen, die dann auch schon gemessen wird...
Code:
	void reaktion()
	{
		System.out.println("BLITZER-ALARM******!!");

		Date reaktionsZeit = new Date();
		long reaktionAnfang = reaktionsZeit.getTime();

		scan.hasNextLine();

		Date reaktionsZeit2 = new Date();
		long reaktionEnde = reaktionsZeit2.getTime();
		
		if(reaktionEnde-reaktionAnfang < level)
		{
		System.out.println("Du hast fuer deine Reaktion " + (reaktionEnde-reaktionAnfang) + " ms benoetigt");
		level = level - 100;
		nextLevel();
		}
		else 
		System.out.println("Du hast leider " + ((reaktionEnde-reaktionAnfang)-level) + " ms zu lange benoetigt.\n");
		System.out.println("Danke, dass du \"Blitzer-Alarm\" gespielt hast.");
		level = 1000;
		scan.close();
	}
 
Hallo,

schau mal hier:
- Eingaben vor ignoreInput = false; werden ignoriert, so werden die Reaktionsmessungen nicht mehr so einfach verfälscht.

Java:
package de.tutorials.training;

import java.io.IOException;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ReactionTest implements AutoCloseable {

    private InputStreamReader input;

    private ExecutorService runner;

    private Lock lock = new ReentrantLock();

    private Condition keyPress = lock.newCondition();

    private volatile boolean ignoreInput = true;

    public ReactionTest() {
        this.input = new InputStreamReader(System.in);
        this.runner = Executors.newSingleThreadExecutor();

    }

    void startInputTracking() {
        this.runner.submit(newInputTracker());
    }

    Runnable newInputTracker() {
        return new Runnable() {
            @Override
            public void run() {
                try {
                    while (ignoreInput) {
                        input.read();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }

                lock.lock();
                try {
                    keyPress.signal();
                } finally {
                    lock.unlock();
                }
            }
        };
    }

    public static void main(String[] args) throws Exception {
        try (ReactionTest reactionTest = new ReactionTest()) {
            reactionTest.run();
        }
    }

    void run() throws Exception {
        log("Gleich geht es los!");

        startInputTracking();
        sleepMillisWithMinAndMax(500, 2000);

        log("Jetzt!");
        ignoreInput = false;

        long durationMillis = -System.currentTimeMillis();
        waitForEnterKeyPress();
        durationMillis += System.currentTimeMillis();

        log("Reaktionszeit: %s ms", durationMillis);
    }

    private void sleepMillisWithMinAndMax(int min, int max) throws InterruptedException {
        TimeUnit.MILLISECONDS.sleep(min + (int) ((max - min) * Math.random()));
    }

    private void log(String msg, Object... args) {
        Object[] copy = new Object[args.length + 1];
        copy[0] = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss.SSS").format(new Date());
        System.arraycopy(args, 0, copy, 1, args.length);
        System.out.printf("%s: " + msg + "%n", copy);
    }

    private void waitForEnterKeyPress() throws InterruptedException {
        lock.lock();
        try {
            keyPress.await();
        } finally {
            lock.unlock();
        }
    }

    @Override
    public void close() throws Exception {
        this.input.close();
        this.runner.shutdownNow();
    }
}

Ausgabe:
Code:
21.05.2013 00:36:09.246: Gleich geht es los!
21.05.2013 00:36:10.779: Jetzt!


21.05.2013 00:36:11.593: Reaktionszeit: 814 ms

Gruß Tom
 
Zurück