Terminal
De Terminal-component is een interactieve terminalemulator die zich gedraagt als een traditionele systeemconsole. Hij verwerkt tekstuitvoer, gebruikersinvoer, controle-sequenties en schermbuffers, waardoor hij geschikt is voor het bouwen van tools voor externe toegang, tekstdashboards, ingebedde opdracht-shells of debugconsoles.
Een terminal maken
Om de Terminal-component in je app te gebruiken, zorg ervoor dat je de volgende afhankelijkheid in je pom.xml opneemt.
<dependency>
<groupId>com.webforj</groupId>
<artifactId>webforj-terminal</artifactId>
</dependency>
Het volgende voorbeeld bouwt een interactieve opdracht-shell met getypte opdrachten, geschiedenisnavigatie en aangepaste uitvoer.
Toon Code
- TerminalView.java
- TerminalCommand.java
- ClearCommand.java
- DateCommand.java
- HelpCommand.java
- MsgCommand.java
- ConfirmCommand.java
- TimeCommand.java
- terminal-view.css
Hoe het werkt
De terminal beheert een raster van tekstcellen, verwerkt binnenkomende tekenstromen en reageert op gebruikersacties zoals typen of tekst selecteren. Hij interpreteert automatisch controlekarakters en escape-sequenties voor cursorbeweging, kleurveranderingen en het wissen van het scherm.
De belangrijkste functionaliteiten zijn:
- Gegevensinvoer: Gegevens schrijven naar de terminal werkt het scherm bij, inclusief zowel tekst als controle-sequenties.
- Gegevensuitvoer: Vangt toetsaanslagen van de gebruiker en geeft deze door als gestructureerde evenementen.
- Schermbeheer: Onderhoudt een scrollbare geschiedenisbuffer en huidige schermstatus.
- Cursorbeheer: Houdt de cursorpositie bij voor tekstinvoer en reacties op controle-sequenties.
De terminal is stateful, wat betekent dat hij correct multibyte-tekens reconstrueert en continuïteit behoudt over gefragmenteerde invoer.
Gegevens naar de terminal verzenden
Gegevens worden naar de terminal verzonden met de methods write en writeln:
write(Object data): Verzendt gegevens naar de terminalstroom.writeln(Object data): Verzendt gegevens gevolgd door een nieuwe regel.
De terminal verwerkt alle binnenkomende gegevens als UTF-16-tekens. Hij verwerkt automatisch multibyte-tekens, zelfs wanneer de invoer in gefragmenteerde stukken arriveert.
Voorbeeld
terminal.write("echo Hello World\n");
terminal.writeln("Klaar.");
Je kunt ook een callback toevoegen die wordt uitgevoerd zodra het gegevenspakket is verwerkt:
terminal.write("Lang opdrachtuitvoer", e -> {
System.out.println("Gegevens verwerkt.");
});
Ontvangen gebruikersinvoer
De terminal vangt door de gebruiker gegenereerde invoer via twee evenementen:
- Gegevens evenement (
onData): Treedt op wanneer tekstinvoer plaatsvindt, en stuurt Unicode-tekens. - Toets evenement (
onKey): Treedt op voor elke toetsaanslag, inclusief informatie over toetsencodes en modifiers zoals Ctrl of Alt.
Deze evenementen kunnen worden gebruikt om gebruikersinvoer naar een backend door te geven, UI-elementen bij te werken of aangepaste acties te activeren.
Voorbeeld
terminal.onData(event -> {
String userInput = event.getValue();
backend.send(userInput);
});
terminal.onKey(event -> {
if (event.isControlKey() && "C".equals(event.getKey())) {
backend.send("SIGINT");
}
});
Alle door de terminal vastgelegde gebruikersinvoer (zoals van onData-evenementen) wordt uitgezonden als UTF-16-tekens.
Als je backend een andere codering verwacht (zoals UTF-8-bytes), moet je de gegevens handmatig transcoderien.
Grote gegevensstromen beheren
Omdat de terminal niet onmiddellijk onbeperkte invoer kan weergeven, houdt hij een interne invoerbuffer bij. Als deze buffer te groot wordt (standaard ongeveer 50MB), kan nieuwe binnenkomende gegevens worden verworpen om de systeemprestaties te beschermen.
Om snelle gegevensbronnen goed te beheren, moet je stroomcontrole implementeren.
Basis voorbeeld van stroomcontrole
Pauzeer je backend totdat de terminal klaar is met het verwerken van een pakket:
pty.onData(chunk -> {
pty.pause();
terminal.write(chunk, result -> {
pty.resume();
});
});
Voorbeeld van watermerkstroomcontrole
Voor efficiëntere controle, gebruik hoge/lage watermerken:
int HIGH_WATERMARK = 100_000;
int LOW_WATERMARK = 10_000;
int bufferedBytes = 0;
pty.onData(chunk -> {
bufferedBytes += chunk.length;
terminal.write(chunk, e -> {
bufferedBytes -= chunk.length;
if (bufferedBytes < LOW_WATERMARK) {
pty.resume();
}
});
if (bufferedBytes > HIGH_WATERMARK) {
pty.pause();
}
});
Toon Code
- ServerLogsView.java
Aanpassing
Terminal opties
De TerminalOptions-klasse stelt je in staat om het gedrag te configureren:
- Cursor knipperen.
- Lettertype-instellingen (familie, grootte, gewicht).
- Scrollback buffer grootte.
- Regelhoogte en letterspatiëring.
- Toegankelijkheidsinstellingen (schermlezer-modus).
Voorbeeld:
TerminalOptions options = new TerminalOptions()
.setCursorBlink(true)
.setFontFamily("Courier New, monospace")
.setFontSize(13)
.setScrollback(5000);
terminal.setOptions(options);
Terminalthema
Je kunt de terminal opmaken met behulp van TerminalTheme, die definieert:
- Achtergrond- en voorgrondkleuren.
- Standaard
ANSIkleurpalet. - Cursor- en selectiesachtergrondkleuren.
Voorbeeld:
TerminalTheme theme = new TerminalTheme();
theme.setBackground("#1e1e1e");
theme.setForeground("#cccccc");
terminal.setTheme(theme);
Toon Code
- TerminalThemePickerView.java
Ondersteunde sequenties
De terminal ondersteunt een breed scala aan standaard controle-sequenties die worden gebruikt voor cursorbeweging, schermupdates en tekstopmaak.
Herkenbare groepen:
C0controlecodes (een-byte 7-bits opdrachten,\x00,\x1F, zoals backspace en line feed)C1controlecodes (een-byte 8-bits opdrachten,\x80,\x9F)ESCsequenties (beginnend metESC(\x1B), zoals cursor opslaan/herstellen, schermuitlijning)CSIsequenties (Control Sequence Introducer,ESC [ofCSI (\x9B), voor operaties zoals scrollen, wissen en stijlen)DCSsequenties (Device Control Strings,ESC PofDCS (\x90))OSCsequenties (Operating System Commands,ESC ]ofOSC (\x9D), voor het instellen van venstertitels, hyperlinks en kleuren)
Sommige exotische sequentietypes zoals APC, PM en SOS worden herkend maar stilzwijgend genegeerd.
Aangepaste sequenties kunnen indien nodig worden ondersteund via integraties.