retrofit from gjexer
[nikiroo-utils.git] / README.md
CommitLineData
7d4115a5
KL
1Jexer - Java Text User Interface library
2========================================
3
3cb99336
KL
4This library implements a text-based windowing system loosely
5reminiscient of Borland's [Turbo
6Vision](http://en.wikipedia.org/wiki/Turbo_Vision) system. (For those
7wishing to use the actual C++ Turbo Vision library, see [Sergio
8Sigala's C++ version based on the sources released by
9Borland,](http://tvision.sourceforge.net/) or consider Free Pascal's
10[Free Vision library.](http://wiki.freepascal.org/Free_Vision))
30bd4abd 11
4b257bd8 12Jexer currently supports three backends:
1ac2ccb1 13
30bd4abd
KL
14* System.in/out to a command-line ECMA-48 / ANSI X3.64 type terminal
15 (tested on Linux + xterm). I/O is handled through terminal escape
16 sequences generated by the library itself: ncurses is not required
a69ed767 17 or linked to. xterm mouse tracking is supported using both UTF8 and
3cb99336
KL
18 SGR coordinates. Images are optionally rendered via sixel graphics
19 (see jexer.ECMA48.sixel). For the demo application, this is the
20 default backend on non-Windows/non-Mac platforms.
1ac2ccb1 21
55b4f29b 22* The same command-line ECMA-48 / ANSI X3.64 type terminal as above,
31b7033c
KL
23 but to any general InputStream/OutputStream or Reader/Writer. See
24 the file jexer.demos.Demo2 for an example of running the demo over a
3cb99336
KL
25 TCP (telnet) socket. jexer.demos.Demo3 demonstrates how one might
26 use a character encoding than the default UTF-8.
55b4f29b 27
c447c6e5
KL
28* Java Swing UI. The default window size for Swing is 80x25 and 20
29 point font; this can be changed in the TApplication(BackendType)
30 constructor. For the demo applications, this is the default backend
31 on Windows and Mac platforms. This backend can be explicitly
32 selected for the demo applications by setting jexer.Swing=true.
1ac2ccb1 33
a4406f4e
KL
34Additional backends can be created by subclassing
35jexer.backend.Backend and passing it into the TApplication
fe0770f9 36constructor. See Demo5 and Demo6 for examples of other backends.
1ac2ccb1 37
1c15371a
KL
38The Jexer homepage, which includes additional information and binary
39release downloads, is at: https://jexer.sourceforge.io . The Jexer
a69ed767 40source code is hosted at: https://gitlab.com/klamonte/jexer .
1c15371a 41
1ac2ccb1 42
7d4115a5
KL
43
44License
45-------
46
e16dda65
KL
47This project is licensed under the MIT License. See the file LICENSE
48for the full license text.
7d4115a5
KL
49
50
30bd4abd
KL
51
52Acknowledgements
53----------------
54
55Jexer makes use of the Terminus TrueType font [made available
56here](http://files.ax86.net/terminus-ttf/) .
57
58
59
7d4115a5
KL
60Usage
61-----
62
4b257bd8 63Simply subclass TApplication and then run it in a new thread:
7d4115a5
KL
64
65```Java
66import jexer.*;
67
4b257bd8 68class MyApplication extends TApplication {
7d4115a5 69
4b257bd8 70 public MyApplication() throws Exception {
a4406f4e 71 super(BackendType.SWING); // Could also use BackendType.XTERM
7d4115a5 72
fca67db0
KL
73 // Create standard menus for File and Window
74 addFileMenu();
75 addWindowMenu();
4b257bd8 76
d36057df
KL
77 // Add a custom window, see below for its code. The TWindow
78 // constructor will add it to this application.
79 new MyWindow(this);
7d4115a5
KL
80 }
81
82 public static void main(String [] args) {
4b257bd8
KL
83 try {
84 MyApplication app = new MyApplication();
85 (new Thread(app)).start();
86 } catch (Throwable t) {
87 t.printStackTrace();
88 }
7d4115a5
KL
89 }
90}
91```
92
4b257bd8
KL
93Similarly, subclass TWindow and add some widgets:
94
95```Java
96class MyWindow extends TWindow {
97
98 public MyWindow(TApplication application) {
99 // See TWindow's API for several constructors. This one uses the
100 // application, title, width, and height. Note that the window width
101 // and height include the borders. The widgets inside the window
102 // will see (0, 0) as the top-left corner inside the borders,
103 // i.e. what the window would see as (1, 1).
104 super(application, "My Window", 30, 20);
105
106 // See TWidget's API for convenience methods to add various kinds of
107 // widgets. Note that ANY widget can be a container for other
108 // widgets: TRadioGroup for example has TRadioButtons as child
109 // widgets.
110
111 // We will add a basic label, text entry field, and button.
112 addLabel("This is a label", 5, 3);
113 addField(5, 5, 20, false, "enter text here");
114 // For the button, we will pop up a message box if the user presses
115 // it.
116 addButton("Press &Me!", 5, 8, new TAction() {
117 public void DO() {
118 MyWindow.this.messageBox("Box Title", "You pressed me, yay!");
119 }
120 } );
121 }
122}
123```
124
125Put these into a file, compile it with jexer.jar in the classpath, run
126it and you'll see an application like this:
127
128![The Example Code Above](/screenshots/readme_application.png?raw=true "The application in the text of README.md")
129
130See the files in jexer.demos for many more detailed examples showing
92453213
KL
131all of the existing UI controls. The available demos can be run as
132follows:
4b257bd8
KL
133
134 * 'java -jar jexer.jar' . This will use System.in/out with
92453213
KL
135 xterm-like sequences on non-Windows non-Mac platforms. On Windows
136 and Mac it will use a Swing JFrame.
4b257bd8
KL
137
138 * 'java -Djexer.Swing=true -jar jexer.jar' . This will always use
139 Swing on any platform.
140
141 * 'java -cp jexer.jar jexer.demos.Demo2 PORT' (where PORT is a
142 number to run the TCP daemon on). This will use the telnet
143 protocol to establish an 8-bit clean channel and be aware of
144 screen size changes.
145
92453213
KL
146 * 'java -cp jexer.jar jexer.demos.Demo3' . This will use
147 System.in/out with xterm-like sequences. One can see in the code
148 how to pass a different InputReader and OutputReader to
149 TApplication, permitting a different encoding than UTF-8.
150
151 * 'java -cp jexer.jar jexer.demos.Demo4' . This demonstrates hidden
152 windows and a custom TDesktop.
153
88a99379
KL
154 * 'java -cp jexer.jar jexer.demos.Demo5' . This demonstrates two
155 demo applications using different fonts in the same Swing frame.
156
157 * 'java -cp jexer.jar jexer.demos.Demo6' . This demonstrates one
158 application performing I/O to two screens: an xterm screen and a
159 Swing screen.
160
4b257bd8
KL
161
162
163More Screenshots
164----------------
165
166![Several Windows Open Including A Terminal](/screenshots/screenshot1.png?raw=true "Several Windows Open Including A Terminal")
167
168![Yo Dawg...](/screenshots/yodawg.png?raw=true "Yo Dawg, I heard you like text windowing systems, so I ran a text windowing system inside your text windowing system so you can have a terminal in your terminal.")
169
3cb99336
KL
170![Sixel Pictures Of Cliffs Of Moher And Buoy](/screenshots/sixel_images.png?raw=true "Sixel Pictures Of Cliffs Of Moher And Buoy")
171
172![Sixel Color Wheel](/screenshots/sixel_color_wheel.png?raw=true "Sixel Color Wheel")
173
4b257bd8
KL
174
175
176System Properties
177-----------------
178
179The following properties control features of Jexer:
180
181 jexer.Swing
182 -----------
183
92453213
KL
184 Used only by jexer.demos.Demo1 and jexer.demos.Demo4. If true, use
185 the Swing interface for the demo application. Default: true on
186 Windows (os.name starts with "Windows") and Mac (os.name starts with
187 "Mac"), false on non-Windows and non-Mac platforms.
4b257bd8
KL
188
189 jexer.Swing.cursorStyle
190 -----------------------
191
d79f1f31
KL
192 Used by jexer.backend.SwingTerminal. Selects the cursor style to
193 draw. Valid values are: underline, block, outline. Default:
194 underline.
30bd4abd 195
e685a47d
KL
196 jexer.Swing.tripleBuffer
197 ------------------------
198
d79f1f31
KL
199 Used by jexer.backend.SwingTerminal. If true, use triple-buffering
200 which reduces screen tearing but may also be slower to draw on
201 slower systems. If false, use naive Swing thread drawing, which may
202 be faster on slower systems but also more likely to have screen
92453213 203 tearing. Default: true.
e685a47d 204
1d99a38f
KL
205 jexer.TTerminal.ptypipe
206 -----------------------
207
208 Used by jexer.TTerminalWindow. If true, spawn shell using the
209 'ptypipe' utility rather than 'script'. This permits terminals to
210 resize with the window. ptypipe is a separate C language utility,
a69ed767
KL
211 available at https://gitlab.com/klamonte/ptypipe. Default: false.
212
3cb99336
KL
213 jexer.TTerminal.closeOnExit
214 ---------------------------
215
216 Used by jexer.TTerminalWindow. If true, close the window when the
217 spawned shell exits. Default: false.
218
a69ed767
KL
219 jexer.ECMA48.rgbColor
220 ---------------------
221
222 Used by jexer.backend.ECMA48Terminal. If true, emit T.416-style RGB
223 colors for normal system colors. This is expensive in bandwidth,
224 and potentially terrible looking for non-xterms. Default: false.
1d99a38f 225
3cb99336
KL
226 jexer.ECMA48.sixel
227 ------------------
228
229 Used by jexer.backend.ECMA48Terminal. If true, emit image data
230 using sixel, otherwise show blank cells where images could be. This
231 is expensive in bandwidth, very expensive in CPU (especially for
232 large images), and will leave artifacts on the screen if the
233 terminal does not support sixel. Default: true.
234
30bd4abd 235
7d4115a5 236
92554d64
KL
237Known Issues / Arbitrary Decisions
238----------------------------------
239
240Some arbitrary design decisions had to be made when either the
241obviously expected behavior did not happen or when a specification was
242ambiguous. This section describes such issues.
243
bd8d51fa
KL
244 - See jexer.tterminal.ECMA48 for more specifics of terminal
245 emulation limitations.
246
a4406f4e
KL
247 - TTerminalWindow uses cmd.exe on Windows. Output will not be seen
248 until enter is pressed, due to cmd.exe's use of line-oriented
249 input (see the ENABLE_LINE_INPUT flag for GetConsoleMode() and
250 SetConsoleMode()).
92554d64 251
1d99a38f
KL
252 - TTerminalWindow by default launches 'script -fqe /dev/null' or
253 'script -q -F /dev/null' on non-Windows platforms. This is a
254 workaround for the C library behavior of checking for a tty:
255 script launches $SHELL in a pseudo-tty. This works on Linux and
256 Mac but might not on other Posix-y platforms.
b5f2a6db 257
5dfd1c11
KL
258 - Closing a TTerminalWindow without exiting the process inside it
259 may result in a zombie 'script' process.
260
3cb99336
KL
261 - When using the Swing backend, and not using 'ptypipe', closing a
262 TTerminalWindow without exiting the process inside it may result
263 in a SIGTERM to the JVM causing it to crash. The root cause is
264 currently unknown, but is potentially a bug in more recent
265 releases of the 'script' utility from the util-linux package.
266
1d99a38f
KL
267 - TTerminalWindow can only notify the child process of changes in
268 window size if using the 'ptypipe' utility, due to Java's lack of
269 support for forkpty() and similar. ptypipe is available at
a69ed767 270 https://gitlab.com/klamonte/ptypipe.
fe0770f9 271
e3dfbd23
KL
272 - Java's InputStreamReader as used by the ECMA48 backend requires a
273 valid UTF-8 stream. The default X10 encoding for mouse
274 coordinates outside (160,94) can corrupt that stream, at best
275 putting garbage keyboard events in the input queue but at worst
276 causing the backend reader thread to throw an Exception and exit
277 and make the entire UI unusable. Mouse support therefore requires
278 a terminal that can deliver either UTF-8 coordinates (1005 mode)
279 or SGR coordinates (1006 mode). Most modern terminals can do
280 this.
b5f2a6db
KL
281
282 - jexer.session.TTYSession calls 'stty size' once every second to
283 check the current window size, performing the same function as
284 ioctl(TIOCGWINSZ) but without requiring a native library.
285
d79f1f31
KL
286 - jexer.backend.ECMA48Terminal calls 'stty' to perform the
287 equivalent of cfmakeraw() when using System.in/out. System.out is
288 also (blindly!) put in 'stty sane cooked' mode when exiting.
55b4f29b 289
3cb99336
KL
290 - jexer.backend.ECMA48Terminal uses a single palette containing
291 MAX_COLOR_REGISTERS colors for all sixel images. These colors are
292 generated in the SixelPalette.makePalette() method with bits for
293 hue, saturation, and luminance, and the two extremes set to pure
294 black and pure white. This provides a reasonable general-purpose
295 palette light on CPU, but at a cost that individual images do not
296 look as good as the terminal is actually capable of.
b5f2a6db
KL
297
298
7d4115a5 299
3cb99336
KL
300See Also
301--------
302
303[Tranquil Java IDE](https://tjide.sourceforge.io) is a TUI-based
304integrated development environment for the Java language that was
305built using a very lightly modified GPL version of Jexer. TJ provided
306a real-world use case to shake out numerous bugs and limitations of
307Jexer.