Class StreamBasedTerminal
- java.lang.Object
-
- com.googlecode.lanterna.terminal.AbstractTerminal
-
- com.googlecode.lanterna.terminal.ansi.StreamBasedTerminal
-
- All Implemented Interfaces:
InputProvider
,Terminal
,java.io.Closeable
,java.lang.AutoCloseable
- Direct Known Subclasses:
ANSITerminal
public abstract class StreamBasedTerminal extends AbstractTerminal
An abstract terminal implementing functionality for terminals using OutputStream/InputStream. You can extend from this class if your terminal implementation is using standard input and standard output but not ANSI escape codes (in which case you should extend ANSITerminal). This class also contains some automatic UTF-8 to VT100 character conversion when the terminal is not set to read UTF-8.
-
-
Field Summary
Fields Modifier and Type Field Description private InputDecoder
inputDecoder
private java.util.Queue<KeyStroke>
keyQueue
private TerminalPosition
lastReportedCursorPosition
private java.util.concurrent.locks.Lock
readLock
private java.nio.charset.Charset
terminalCharset
private java.io.InputStream
terminalInput
private java.io.OutputStream
terminalOutput
private static java.nio.charset.Charset
UTF8_REFERENCE
-
Constructor Summary
Constructors Constructor Description StreamBasedTerminal(java.io.InputStream terminalInput, java.io.OutputStream terminalOutput, java.nio.charset.Charset terminalCharset)
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description void
bell()
Prints 0x7 to the terminal, which will make the terminal (emulator) ring a bell (or more likely beep).void
close()
Closes the terminal, if applicable.private byte[]
convertToCharset(char input)
private byte[]
convertToVT100(char code)
byte[]
enquireTerminal(int timeout, java.util.concurrent.TimeUnit timeoutTimeUnit)
Retrieves optional information from the terminal by printing the ENQ (\u005) character.void
flush()
Callsflush()
on the underlyingOutputStream
object, or whatever other implementation this terminal is built around.protected java.nio.charset.Charset
getCharset()
InputDecoder
getInputDecoder()
Returns theInputDecoder
attached to thisStreamBasedTerminal
.KeyStroke
pollInput()
Returns the nextKey
off the input queue or null if there is no more input events available.void
putCharacter(char c)
Prints one character to the terminal at the current cursor location.void
putString(java.lang.String string)
Prints a string to the terminal at the current cursor location.KeyStroke
readInput()
Returns the nextKey
off the input queue or blocks until one is available.private KeyStroke
readInput(boolean blocking, boolean useKeyQueue)
(package private) void
resetMemorizedCursorPosition()
Used by the cursor reporting methods to reset any previous position memorized, so we're guaranteed to return the next reported positionprotected byte[]
translateCharacter(char input)
(package private) TerminalPosition
waitForCursorPositionReport()
Waits for up to 5 seconds for a terminal cursor position report to appear in the input stream.protected void
writeToTerminal(byte... bytes)
This method will write a list of bytes directly to the output stream of the terminal.-
Methods inherited from class com.googlecode.lanterna.terminal.AbstractTerminal
addResizeListener, newTextGraphics, onResized, onResized, removeResizeListener
-
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-
Methods inherited from interface com.googlecode.lanterna.terminal.Terminal
clearScreen, disableSGR, enableSGR, enterPrivateMode, exitPrivateMode, getCursorPosition, getTerminalSize, resetColorAndSGR, setBackgroundColor, setCursorPosition, setCursorPosition, setCursorVisible, setForegroundColor
-
-
-
-
Field Detail
-
UTF8_REFERENCE
private static final java.nio.charset.Charset UTF8_REFERENCE
-
terminalInput
private final java.io.InputStream terminalInput
-
terminalOutput
private final java.io.OutputStream terminalOutput
-
terminalCharset
private final java.nio.charset.Charset terminalCharset
-
inputDecoder
private final InputDecoder inputDecoder
-
keyQueue
private final java.util.Queue<KeyStroke> keyQueue
-
readLock
private final java.util.concurrent.locks.Lock readLock
-
lastReportedCursorPosition
private volatile TerminalPosition lastReportedCursorPosition
-
-
Method Detail
-
putCharacter
public void putCharacter(char c) throws java.io.IOException
Prints one character to the terminal at the current cursor location. Please note that the cursor will then move one column to the right, so multiple calls toputCharacter
will print out a text string without the need to reposition the text cursor. If you reach the end of the line while putting characters using this method, you can expect the text cursor to move to the beginning of the next line.You can output CJK (Chinese, Japanese, Korean) characters (as well as other regional scripts) but remember that the terminal that the user is using might not have the required font to render it. Also worth noticing is that CJK (and some others) characters tend to take up 2 columns per character, simply because they are a square in their construction as opposed to the somewhat rectangular shape we fit latin characters in. As it's very difficult to create a monospace font for CJK with a 2:1 height-width proportion, it seems like the implementers back in the days simply gave up and made each character take 2 column. It causes issues for the random terminal programmer because you can't really trust 1 character = 1 column, but I suppose it's "しょうがない". If you try to print non-printable control characters, the terminal is likely to ignore them (all
Terminal
implementations bundled with Lanterna will). TheStreamBasedTerminal
class will attempt to translate some unicode characters to VT100 if the encoding attached to thisTerminal
isn't UTF-8.- Parameters:
c
- Character to place on the terminal- Throws:
java.io.IOException
- If there was an underlying I/O error
-
putString
public void putString(java.lang.String string) throws java.io.IOException
Prints a string to the terminal at the current cursor location. Please note that the cursor will then move one column to the right, so multiple calls toputString
will print out a text string without the need to reposition the text cursor. If you reach the end of the line while putting characters using this method, you can expect the text cursor to move to the beginning of the next line.You can output CJK (Chinese, Japanese, Korean) characters (as well as other regional scripts) but remember that the terminal that the user is using might not have the required font to render it. Also worth noticing is that CJK (and some others) characters tend to take up 2 columns per character, simply because they are a square in their construction as opposed to the somewhat rectangular shape we fit latin characters in. As it's very difficult to create a monospace font for CJK with a 2:1 height-width proportion, it seems like the implementers back in the days simply gave up and made each character take 2 column. It causes issues for the random terminal programmer because you can't really trust 1 character = 1 column, but I suppose it's "しょうがない".
If you try to print non-printable control characters, the terminal is likely to ignore them (all
Terminal
implementations bundled with Lanterna will).You can use this method to place emoji characters on the terminal, since they take up more than one char with Java's built-in UTF16 encoding. The
StreamBasedTerminal
class will attempt to translate some unicode characters to VT100 if the encoding attached to thisTerminal
isn't UTF-8.- Parameters:
string
- String to place on the terminal- Throws:
java.io.IOException
- If there was an underlying I/O error
-
writeToTerminal
protected void writeToTerminal(byte... bytes) throws java.io.IOException
This method will write a list of bytes directly to the output stream of the terminal.- Parameters:
bytes
- Bytes to write to the terminal (synchronized)- Throws:
java.io.IOException
- If there was an underlying I/O error
-
enquireTerminal
public byte[] enquireTerminal(int timeout, java.util.concurrent.TimeUnit timeoutTimeUnit) throws java.io.IOException
Description copied from interface:Terminal
Retrieves optional information from the terminal by printing the ENQ (\u005) character. Terminals and terminal emulators may or may not respond to this command, sometimes it's configurable.- Parameters:
timeout
- How long to wait for the talk-back message, if there's nothing immediately available on the input stream, you should probably set this to a somewhat small value to prevent unnecessary blockage on the input stream but large enough to accommodate a round-trip to the user's terminal (~300 ms if you are connection across the globe).timeoutTimeUnit
- What unit to use when interpreting thetimeout
parameter- Returns:
- Answer-back message from the terminal or empty if there was nothing
- Throws:
java.io.IOException
- If there was an I/O error while trying to read the enquiry reply
-
bell
public void bell() throws java.io.IOException
Description copied from interface:Terminal
Prints 0x7 to the terminal, which will make the terminal (emulator) ring a bell (or more likely beep). Not all terminals implements this. Wikipedia has more details.- Throws:
java.io.IOException
- If there was an underlying I/O error
-
getInputDecoder
public InputDecoder getInputDecoder()
Returns theInputDecoder
attached to thisStreamBasedTerminal
. Can be used to add additional character patterns to recognize and tune the way input is turned inKeyStroke
:s.- Returns:
InputDecoder
attached to thisStreamBasedTerminal
-
resetMemorizedCursorPosition
void resetMemorizedCursorPosition()
Used by the cursor reporting methods to reset any previous position memorized, so we're guaranteed to return the next reported position
-
waitForCursorPositionReport
TerminalPosition waitForCursorPositionReport() throws java.io.IOException
Waits for up to 5 seconds for a terminal cursor position report to appear in the input stream. If the timeout expires, it will return null. You should have sent the cursor position query already before calling this method.- Returns:
- Current position of the cursor, or null if the terminal didn't report it in time.
- Throws:
java.io.IOException
- If there was an I/O error
-
pollInput
public KeyStroke pollInput() throws java.io.IOException
Description copied from interface:InputProvider
Returns the nextKey
off the input queue or null if there is no more input events available. Note, this method call is not blocking, it returns null immediately if there is nothing on the input stream.- Returns:
- Key object which represents a keystroke coming in through the input stream
- Throws:
java.io.IOException
- Propagated error if the underlying stream gave errors
-
readInput
public KeyStroke readInput() throws java.io.IOException
Description copied from interface:InputProvider
Returns the nextKey
off the input queue or blocks until one is available. NOTE: In previous versions of Lanterna, this method was not blocking. From lanterna 3, it is blocking and you can callpollInput()
for the non-blocking version.- Returns:
- Key object which represents a keystroke coming in through the input stream
- Throws:
java.io.IOException
- Propagated error if the underlying stream gave errors
-
readInput
private KeyStroke readInput(boolean blocking, boolean useKeyQueue) throws java.io.IOException
- Throws:
java.io.IOException
-
flush
public void flush() throws java.io.IOException
Description copied from interface:Terminal
Callsflush()
on the underlyingOutputStream
object, or whatever other implementation this terminal is built around. Some implementing classes of this interface (like SwingTerminal) doesn't do anything as it doesn't really apply to them.- Throws:
java.io.IOException
- If there was an underlying I/O error
-
close
public void close() throws java.io.IOException
Description copied from interface:Terminal
Closes the terminal, if applicable. If the implementation doesn't support closing the terminal, this will do nothing. The Swing/AWT emulator implementations will translate this into a dispose() call on the UI resources, the telnet implementation will hang out the connection.- Throws:
java.io.IOException
- If there was an underlying I/O error
-
getCharset
protected java.nio.charset.Charset getCharset()
-
translateCharacter
protected byte[] translateCharacter(char input)
-
convertToVT100
private byte[] convertToVT100(char code)
-
convertToCharset
private byte[] convertToCharset(char input)
-
-