R
R
reus2017-07-14 14:48:14
Java
reus, 2017-07-14 14:48:14

How to catch the user pressing the Esc button in the win console?

In general, there is a task, but one of the points is:
- abort the operation if the user pressed the Esc button
The implementation should work in the windows console, but I don't know how to implement it.
Can you tell me where to look for this issue?
PS GUI (swing / fx / etc) do not roll

Answer the question

In order to leave comments, you need to log in

1 answer(s)
S
Sergey Gornostaev, 2017-07-14
@reus

This is not possible without using JNI. If the use of native calls is acceptable for you, then the first thing we need is the java code itself. Let's put it in ExitOnEscape.java :

public class ExitOnEscape implements Runnable {
    private boolean doTheStuff = true; // Флаг активности рабочего потока

    public native boolean readConsole();

    public void run() { // Рабочий поток
        while (doTheStuff) { // Работать пока установлен флаг
            System.out.println("Doing something..."); // Основная логика программы
            try {
                Thread.sleep(500);
            }
            catch (InterruptedException exc) {}
        }
    }

    public void doSomething() {
        new Thread(this).start(); // Запускаем рабочий поток

        while(true) { // В главном потоке читаем консоль нативной функцией в бесконечном цикле
            if(readConsole()) { // Если нажат escape
                doTheStuff = false; // Сбрасываем флаг активности
                break; // И выходим из цикла
            }
        }
    }

    public static void main(String[] args) {
        System.loadLibrary("ExitOnEscape");
        ExitOnEscape exitOnEscape = new ExitOnEscape();
        exitOnEscape.doSomething();
    }
}

As you can see, there are only two lines in the code that are different from what you have to deal with on a daily basis. This is the declaration of the native method and loading the library Compile it: Now we need to generate a header file for our future library from the resulting class. The javah utility included in the JDK will help us with this: ExitOnEscape.h file with the following content should appear in the working directory:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class ExitOnEscape */

#ifndef _Included_ExitOnEscape
#define _Included_ExitOnEscape
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     ExitOnEscape
 * Method:    readConsole
 * Signature: ()Z
 */
JNIEXPORT jboolean JNICALL Java_ExitOnEscape_readConsole
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

The only interesting thing about it is the function declaration, which has the form Java_<class name>_<method name> . The first parameter of the JNIEnv function is a pointer to a table of JNI mechanism functions that serve to provide interaction between java and c code. The second parameter is of type jobject and takes an instance of the ExitOnEscape class . Returns the jboolean function corresponding to the boolean type in java.
JNIEXPORT and JNICALL are compiler dependent macro definitions for exporting functions, they don't deserve much attention.
And now the most interesting part - the implementation of this function. Let's describe it in the file ExitOnEscape.c :
#include <stdio.h>
#include <conio.h>
#include "ExitOnEscape.h"

JNIEXPORT jboolean JNICALL Java_ExitOnEscape_readConsole(JNIEnv* env, jobject obj) {
    char c = getch(); // Считываем введённый символ
    if (c == 27) // Если это escape
        return JNI_TRUE; // Возвращаем true
    else
        return JNI_FALSE; // Иначе false
}

To compile on Windows, I used MinGW-w64 :
gcc -Wl,--add-stdcall-alias ^
-I"%JAVA_HOME%\include" ^
-I"%JAVA_HOME%\include\win32" ^
-shared -o ExitOnEscape.dll ExitOnEscape.c

The file ExitOnEscape.dll should appear in the working directory . After that, you can run the java program.
java ExitOnEscape

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question