Wczytanie klawisza ze standard input

0

Rozważam napisanie pewnego programu w Java działający w konsoli. Wcześniej taki sam program napisałem w C#. Oprócz samego pisania tekstu potrzebowałbym odczytu naciśnięć klawiszy. Nie chodzi o napisanie tekstu i naciśnięcie Enter, tylko o reakcję na każde naciśnięcie klawisza. Wszystko, co znalazłem w internecie sprowadza się tak naprawdę do dwóch wariantów tego, co napisałem. Okazuje się, że po uruchomieniu tego w Linux działa tak, że jak się naciska litery, to nic się nie dzieje, a jak się naciśnie Enter, to wypiszą się numery wszystkich dotychczas naciśniętych liter.

package testcon;
import java.io.Console;

public class testcon{

    public static void main(String[] args)
    {
        Console console = System.console();
        if (console == null)
        {
            System.out.println("No console: non-interactive mode!");
            System.exit(0);
        }

        int Variant = 1;

        while (true)
        {
            try
            {
                int Chr = 0;
                if (Variant == 1)
                {
                    Chr = System.in.read();
                }
                if (Variant == 2)
                {
                    Chr = console.reader().read();
                }
                System.out.println(">" + Chr + "");
            }
            catch (Exception E)
            {
                System.out.print("*");
            }
        }
    }    
}

W jaki sposób w Java można odczytać klawisz? Chodzi o odpowiednik funkcji Console.Readkey() z C#.

0
_13th_Dragon napisał(a):

https://sourceforge.net/projects/javaconio/

Jest to jakieś wyjście, jednak jest to biblioteka specjalizowana dla Windows (zapewne można dla każdego OS znaleźć podobną). Czy to znaczy, ze Java sama w sobie, w odróżnieniu od C#, nie zapewnia możliwości pełnej obsługi konsoli?

2

Technicznie to bardziej konsola nie wspiera czegoś takiego jak czytanie znaków bez entera....ale

zobacz sobie "Java non-blocking console input on Linux" tutaj:

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

0
jarekr000000 napisał(a):

Technicznie to bardziej konsola nie wspiera czegoś takiego jak czytanie znaków bez entera....ale

W takim razie ja chyba czegoś nie rozumiem. ZTCW, każdy OS, zarówno DOS/Windows, jak i Unix/Linux zaczynał swoją historię od konsoli, która działała na pełnym ekranie, wtedy to się nazywało tryb tekstowy. Od zarania dziejów każdy program przechwytywał klawisze na bieżąco i robił to, co zaimplementował programista. Bez reakcji na pojedyncze klawisze raczej nie mogłyby zostać napisane znane programy Norton Commander i Midnight Commander. Z powyższego wynika, że to, co nazywa się wiersz polecenia, konsola, terminal w systemach operacyjnych to nie jest nic nowego, tylko rzecz stara i działająca, ale zminiaturyzowana do okna, bez zmiany zasady działania.

Konsola czekająca na Enter, to chyba nawiązanie do epoki kamienia łupanego, kiedy nie było monitorów ekranowych, a jedynym narzędziem porozumiewania się komputera z użytkownikiem była drukarka z klawiaturą lub elektryczna maszyna do pisania i to z tego się wzięło, że w wielu językach programowania, polecenie wypisania tekstu nazywa się "print". Jak cofniemy się do tamtych czasów, to wtedy zgodzę się, że nie było technicznej możliwości, żeby konsola reagowała na klawisze na bieżąco.

2

Unix na pewno zaczynał od konsoli,
a wyglądała ona tak:

a tu pierwszy produkt Microsoftu w działaniu

Jest to zdecydowanie zaszłość historyczna, zgadzam się. Ale jest - po prostu jest.

2
andrzejlisek napisał(a):
jarekr000000 napisał(a):

Technicznie to bardziej konsola nie wspiera czegoś takiego jak czytanie znaków bez entera....ale

Konsola czekająca na Enter, to chyba nawiązanie do epoki kamienia łupanego, kiedy nie było monitorów ekranowych, a jedynym narzędziem porozumiewania się komputera z użytkownikiem była drukarka z klawiaturą lub elektryczna maszyna do pisania i to z tego się wzięło, że w wielu językach programowania, polecenie wypisania tekstu nazywa się "print". Jak cofniemy się do tamtych czasów, to wtedy zgodzę się, że nie było technicznej możliwości, żeby konsola reagowała na klawisze na bieżąco.

Nie widzisz drugiego dna. Czekanie na enter, sprawia, że konsolka nie jest responsywna. Z drugiej strony pisanie takiej aplikacji jest proste i co najważniesze: można jej używać w trybie nie wymagającym interakcji z człowiekiem np. poprzez użycia linuxowego pipa.

Jak chcesz wygody to szukaj pod hasłem java tui library. Do go i pythona jest dużo fajnych bibliotek, w świecie javy nie wiem jak to jest

2

To tak, standardowo wczytuje się do entera i stdin jest blokujący, można użyć termios biblioteki, która umożliwia za pomocą ioctl, ustawianie stdin jako non block, wtedy zwraca od razu bez czekania na enter.

Na linuxie pliki są konfigurowalne jak zewnętrzne urządzenia.

2

Wbrew temu co napisali tutaj inni - terminal Linuxa wspiera wczytywanie znak po znaku. Widocznie masz terminal tty ustawiony w trybie kanonicznym - czyli takim, który czeka na zatwierdzenie komendy enter-em. Przejdź na tryb niekanoniczny - wtedy powinieneś dostawać znak po znaku:

stty -F tty -icanon

bez konieczności potwierdzania enter-em.
Ale ja nie używam Javy i nie wiem jak to tam ustawić.

2

To chyba jest dobre miejsce, żeby zacząć https://stackoverflow.com/questions/439799/whats-a-good-java-curses-like-library-for-terminal-applications

Biblioteki, które tam wrzucono zanim jakoś muszą rozwiązywać ten problem i można popatrzeć w źródłach, albo użyć gotowca.

1 użytkowników online, w tym zalogowanych: 0, gości: 1