Unterste Zeile der Java Konsole für Input reservieren?

2 Antworten

Vom Fragesteller als hilfreich ausgezeichnet

"Es kann nur einen geben"

...das gilt nicht nur für den Highlander, sondern (und vor allem) auch bei schreibenden Threads.

Multithreading erfordert einen hohen organisatorischen Aufwand, damit es keine Kollisionen gibt. Dein Output ist ein Zusammenstoß...

Dein Log-Thread schreibt munter in die System.Console und diese hat nur einen Schreibcursor, welcher (wenn nicht durch Positionierungsbefehle explizit gesteuert) einfach nur mit jedem Zeichen horizotal weiterrückt und bei einem Linefeed in die nächste Zeile wechselt. Mehr ist da nicht.

Jetzt hast Du aber einen 2. parallelen Thread der genau das gleiche tut. Wenn du etwas eingibst wird es an die aktuelle Position des Cursors "geechot".

Beide Threads wissen nichts voneinander , also schicken sie einfach ihre Zeichen an die Console und der ist es völlig Wumpe woher die Zeichen kommen. Die bringt alles wie es kommt auf den Bildschirm. Das Deine Eingegebenen Buchstaben gerade vorn gelandet sind, ist mehr oder weniger dem Umstand geschuldet, das Du langsamer tippst als der Log-Thread schreibt.

...wie z.B. bei Minecraft Servern, wo die Unterste Zeile der Konsole IMMER für Eingaben reserviert ist.

Dass ist eine ganz andere Sache. Derartige "Consolen" sind sind GUIs die aussehen wie "Console" oder echte Consoleanwendungen , die so ausgelegt sind, das das sie in Dauerschleife versuchen Zeichen einzeln lesen und an eine festgelegte Position schreiben. In der "Freizeit" zwischen den Leseoperationen ,kümmert sich die schleife um das Schreiben von gebufferten Daten anderer Threads/Prozesse. Damit ist sichergestellt, das nur einer sich um das Schreiben (und die Cursorpositionierung) kümmert.

Parallele Prozesse legen ihre "Schreibwünsche" in einen "Briefkasten" (FIFO-Buffer)

Wenn ich Dir so ein Ding schreiben würde wäre das wohl eher eine "Fred Feuerstein"-Nummer und wir wollen ja nicht in Richtung Steinzeit.

Die einfachere Variante wäre ein Ereignisgesteuertes GUI ( wenn man möcht kann man ja den Hintergrund Schwarz machen und die Schrift Weiß... dann siehts nach Console aus, hat aber die volle Funktionalität einer GUI. Damit musst Du lediglich um das Layout kümmern und dem für den Output zuständigen Textfeld per Event mitteilen, dass neue Daten hat und wo diese abzuholen sind...

oder

Woher ich das weiß:eigene Erfahrung – Ich mach das seit 30 Jahren

Da musste ich tatsächlich mal ChatGPT anschmeißen. Versuche mal das:

import java.util.Scanner;


public class Main {
  public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);


    Thread inputThread = new Thread(() -> {
      while (true) {
        String input = scanner.nextLine();
        // hier können Sie die Eingabe verarbeiten
      }
    });


    Thread logThread = new Thread(() -> {
      while (true) {
        // hier können Sie das Ausgabe-Logging durchführen
        System.out.println("Temperatur von Thermometer ID:...");
      }
    });


    inputThread.start();
    logThread.start();
  }
}


In diesem Beispiel liest der Thread

inputThread

die Eingabezeilen über einen

Scanner

ein, während der Thread

logThread

die Ausgabezeilen auf die Konsole schreibt. Da diese Threads getrennt ausgeführt werden, sollten die Ein- und Ausgabeaufforderungen in getrennten Zeilen angezeigt werden.

In C# kann man mit lock() die Konsole einfach sperren und so den Input des Users erlauben und verschiedene Loggingtools davon abhalten, sich nicht zu vermischen. Vielleicht hilft die Lösung von ChatGPT schon weiter?

Woher ich das weiß:Berufserfahrung – 💻 Zertifizierter Sr. Cloud Engineer im IT-Consulting

Nentonde 
Fragesteller
 08.05.2023, 17:17

Mein Problem existiert leider immernoch

0