black-and-white palette support
[nikiroo-utils.git] / README.md
... / ...
CommitLineData
1Jexer - Java Text User Interface library
2========================================
3
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))
11
12Jexer currently supports three backends:
13
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
17 or linked to. xterm mouse tracking is supported using both UTF8 and
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.
21
22* The same command-line ECMA-48 / ANSI X3.64 type terminal as above,
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
25 TCP (telnet) socket. jexer.demos.Demo3 demonstrates how one might
26 use a character encoding than the default UTF-8.
27
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.
33
34Additional backends can be created by subclassing
35jexer.backend.Backend and passing it into the TApplication
36constructor. See Demo5 and Demo6 for examples of other backends.
37
38The Jexer homepage, which includes additional information and binary
39release downloads, is at: https://jexer.sourceforge.io . The Jexer
40source code is hosted at: https://gitlab.com/klamonte/jexer .
41
42
43
44License
45-------
46
47This project is licensed under the MIT License. See the file LICENSE
48for the full license text.
49
50
51Maven
52-----
53
54Jexer is available on Maven Central:
55
56```xml
57<dependency>
58 <groupId>com.gitlab.klamonte</groupId>
59 <artifactId>jexer</artifactId>
60 <version>0.3.0</version>
61</dependency>
62```
63
64
65
66Acknowledgements
67----------------
68
69Jexer makes use of the Terminus TrueType font [made available
70here](http://files.ax86.net/terminus-ttf/) .
71
72
73
74Usage
75-----
76
77Simply subclass TApplication and then run it in a new thread:
78
79```Java
80import jexer.*;
81
82class MyApplication extends TApplication {
83
84 public MyApplication() throws Exception {
85 super(BackendType.SWING); // Could also use BackendType.XTERM
86
87 // Create standard menus for File and Window
88 addFileMenu();
89 addWindowMenu();
90
91 // Add a custom window, see below for its code. The TWindow
92 // constructor will add it to this application.
93 new MyWindow(this);
94 }
95
96 public static void main(String [] args) throws Exception {
97 MyApplication app = new MyApplication();
98 (new Thread(app)).start();
99 }
100}
101```
102
103Similarly, subclass TWindow and add some widgets:
104
105```Java
106class MyWindow extends TWindow {
107
108 public MyWindow(TApplication application) {
109 // See TWindow's API for several constructors. This one uses the
110 // application, title, width, and height. Note that the window width
111 // and height include the borders. The widgets inside the window
112 // will see (0, 0) as the top-left corner inside the borders,
113 // i.e. what the window would see as (1, 1).
114 super(application, "My Window", 30, 20);
115
116 // See TWidget's API for convenience methods to add various kinds of
117 // widgets. Note that ANY widget can be a container for other
118 // widgets: TRadioGroup for example has TRadioButtons as child
119 // widgets.
120
121 // We will add a basic label, text entry field, and button.
122 addLabel("This is a label", 5, 3);
123 addField(5, 5, 20, false, "enter text here");
124 // For the button, we will pop up a message box if the user presses
125 // it.
126 addButton("Press &Me!", 5, 8, new TAction() {
127 public void DO() {
128 MyWindow.this.messageBox("Box Title", "You pressed me, yay!");
129 }
130 } );
131 }
132}
133```
134
135Put these into a file, compile it with jexer.jar in the classpath, run
136it and you'll see an application like this:
137
138![The Example Code Above](/screenshots/readme_application.png?raw=true "The application in the text of README.md")
139
140
141
142More Examples
143-------------
144
145The examples/ folder currently contains:
146
147 * A [prototype tiling window
148 manager](/examples/JexerTilingWindowManager.java) in less than 250
149 lines of code.
150
151 * A [prototype image thumbnail
152 viewer](/examples/JexerImageViewer.java) in less than 350 lines of
153 code.
154
155jexer.demos contains official demos showing all of the existing UI
156controls. The demos can be run as follows:
157
158 * 'java -jar jexer.jar' . This will use System.in/out with
159 xterm-like sequences on non-Windows non-Mac platforms. On Windows
160 and Mac it will use a Swing JFrame.
161
162 * 'java -Djexer.Swing=true -jar jexer.jar' . This will always use
163 Swing on any platform.
164
165 * 'java -cp jexer.jar jexer.demos.Demo2 PORT' (where PORT is a
166 number to run the TCP daemon on). This will use the telnet
167 protocol to establish an 8-bit clean channel and be aware of
168 screen size changes.
169
170 * 'java -cp jexer.jar jexer.demos.Demo3' . This will use
171 System.in/out with xterm-like sequences. One can see in the code
172 how to pass a different InputReader and OutputReader to
173 TApplication, permitting a different encoding than UTF-8.
174
175 * 'java -cp jexer.jar jexer.demos.Demo4' . This demonstrates hidden
176 windows and a custom TDesktop.
177
178 * 'java -cp jexer.jar jexer.demos.Demo5' . This demonstrates two
179 demo applications using different fonts in the same Swing frame.
180
181 * 'java -cp jexer.jar jexer.demos.Demo6' . This demonstrates two
182 applications performing I/O across three screens: an xterm screen
183 and Swing screen, monitored from a third Swing screen.
184
185
186
187More Screenshots
188----------------
189
190![Several Windows Open Including A Terminal](/screenshots/screenshot1.png?raw=true "Several Windows Open Including A Terminal")
191
192![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.")
193
194![Sixel Pictures Of Cliffs Of Moher And Buoy](/screenshots/sixel_images.png?raw=true "Sixel Pictures Of Cliffs Of Moher And Buoy")
195
196![Sixel Color Wheel](/screenshots/sixel_color_wheel.png?raw=true "Sixel Color Wheel")
197
198
199
200System Properties
201-----------------
202
203The following properties control features of Jexer:
204
205 jexer.Swing
206 -----------
207
208 Used only by jexer.demos.Demo1 and jexer.demos.Demo4. If true, use
209 the Swing interface for the demo application. Default: true on
210 Windows (os.name starts with "Windows") and Mac (os.name starts with
211 "Mac"), false on non-Windows and non-Mac platforms.
212
213 jexer.Swing.cursorStyle
214 -----------------------
215
216 Used by jexer.backend.SwingTerminal. Selects the cursor style to
217 draw. Valid values are: underline, block, outline. Default:
218 underline.
219
220 jexer.Swing.tripleBuffer
221 ------------------------
222
223 Used by jexer.backend.SwingTerminal. If true, use triple-buffering
224 which reduces screen tearing but may also be slower to draw on
225 slower systems. If false, use naive Swing thread drawing, which may
226 be faster on slower systems but also more likely to have screen
227 tearing. Default: true.
228
229 jexer.TTerminal.ptypipe
230 -----------------------
231
232 Used by jexer.TTerminalWindow. If true, spawn shell using the
233 'ptypipe' utility rather than 'script'. This permits terminals to
234 resize with the window. ptypipe is a separate C language utility,
235 available at https://gitlab.com/klamonte/ptypipe. Default: false.
236
237 jexer.TTerminal.closeOnExit
238 ---------------------------
239
240 Used by jexer.TTerminalWindow. If true, close the window when the
241 spawned shell exits. Default: false.
242
243 jexer.ECMA48.rgbColor
244 ---------------------
245
246 Used by jexer.backend.ECMA48Terminal. If true, emit T.416-style RGB
247 colors for normal system colors. This is expensive in bandwidth,
248 and potentially terrible looking for non-xterms. Default: false.
249
250 jexer.ECMA48.sixel
251 ------------------
252
253 Used by jexer.backend.ECMA48Terminal. If true, emit image data
254 using sixel, otherwise show blank cells where images could be. This
255 is expensive in bandwidth, very expensive in CPU (especially for
256 large images), and will leave artifacts on the screen if the
257 terminal does not support sixel. Default: true.
258
259
260
261Known Issues / Arbitrary Decisions
262----------------------------------
263
264Some arbitrary design decisions had to be made when either the
265obviously expected behavior did not happen or when a specification was
266ambiguous. This section describes such issues.
267
268 - See jexer.tterminal.ECMA48 for more specifics of terminal
269 emulation limitations.
270
271 - TTerminalWindow uses cmd.exe on Windows. Output will not be seen
272 until enter is pressed, due to cmd.exe's use of line-oriented
273 input (see the ENABLE_LINE_INPUT flag for GetConsoleMode() and
274 SetConsoleMode()).
275
276 - TTerminalWindow by default launches 'script -fqe /dev/null' or
277 'script -q -F /dev/null' on non-Windows platforms. This is a
278 workaround for the C library behavior of checking for a tty:
279 script launches $SHELL in a pseudo-tty. This works on Linux and
280 Mac but might not on other Posix-y platforms.
281
282 - Closing a TTerminalWindow without exiting the process inside it
283 may result in a zombie 'script' process.
284
285 - When using the Swing backend, and not using 'ptypipe', closing a
286 TTerminalWindow without exiting the process inside it may result
287 in a SIGTERM to the JVM causing it to crash. The root cause is
288 currently unknown, but is potentially a bug in more recent
289 releases of the 'script' utility from the util-linux package.
290
291 - TTerminalWindow can only notify the child process of changes in
292 window size if using the 'ptypipe' utility, due to Java's lack of
293 support for forkpty() and similar. ptypipe is available at
294 https://gitlab.com/klamonte/ptypipe.
295
296 - Java's InputStreamReader as used by the ECMA48 backend requires a
297 valid UTF-8 stream. The default X10 encoding for mouse
298 coordinates outside (160,94) can corrupt that stream, at best
299 putting garbage keyboard events in the input queue but at worst
300 causing the backend reader thread to throw an Exception and exit
301 and make the entire UI unusable. Mouse support therefore requires
302 a terminal that can deliver either UTF-8 coordinates (1005 mode)
303 or SGR coordinates (1006 mode). Most modern terminals can do
304 this.
305
306 - jexer.session.TTYSession calls 'stty size' once every second to
307 check the current window size, performing the same function as
308 ioctl(TIOCGWINSZ) but without requiring a native library.
309
310 - jexer.backend.ECMA48Terminal calls 'stty' to perform the
311 equivalent of cfmakeraw() when using System.in/out. System.out is
312 also (blindly!) put in 'stty sane cooked' mode when exiting.
313
314 - jexer.backend.ECMA48Terminal uses a single palette containing
315 MAX_COLOR_REGISTERS colors for all sixel images. These colors are
316 generated in the SixelPalette.makePalette() method with bits for
317 hue, saturation, and luminance, and the two extremes set to pure
318 black and pure white. This provides a reasonable general-purpose
319 palette light on CPU, but at a cost that individual images do not
320 look as good as the terminal is actually capable of.
321
322
323
324See Also
325--------
326
327[Tranquil Java IDE](https://tjide.sourceforge.io) is a TUI-based
328integrated development environment for the Java language that was
329built using a very lightly modified GPL version of Jexer. TJ provided
330a real-world use case to shake out numerous bugs and limitations of
331Jexer.
332
333
334
335Maintainers Wanted
336------------------
337
338Both Jexer and TJIDE are seeking additional maintainers. I am not in
339a position in life to take on significant off-hours programming work,
340and am willing to hand these projects over to one or more persons with
341time and interest.
342
343My personal code design philosophy for TJIDE/Jexer is outlined at
344https://gitlab.com/klamonte/tjide/blob/master/java/docs/code_design.txt
345. I realize that some of the features listed below may require
346deviations from this philosophy, but this is what I have built so far.
347
348Some of the areas that will likely require significant efforts are:
349
350 * Editor improvements. The editor is currently very minimalistic,
351 much closer to MS-DOS edit.com than a real programmer's editor.
352 Users will probably desire many more features: drag-and-drop, real
353 syntax or at least regexp highlighting (not just keywords), paren
354 matching, paragraph/comment reflow, and dozens more. The
355 underlying Document/Line/Word model is not going to be sufficient
356 to meet these features.
357
358 * Better Windows and OSX support. It would be nice to ship a
359 jlink'ed JVM on these platforms with the JRE, JDK, and JPDA
360 modules all together. For Windows, it might be preferable to
361 consider doing any of the following: ship a third-party terminal,
362 use PowerShell, or use the newer ConPTY for TTerminalWindow.
363
364 * Bug fixes. The Jexer codebase is quite large despite my best
365 efforts. Bugs are typically very small to fix, but can take some
366 time to find: a simple NPE or AssertionError can sometimes take
367 4-8 hours to squash. Fortunately, fixing issues in one place has
368 not often led to breakages elsewhere.
369
370 * New Jexer applications. So far as I know, Jexer is the only
371 mouse-supporting full TUI windowing framework with sixel image
372 support in existence. I cannot predict what kinds of applications
373 could be built out of it, and how those needs will push back to
374 the framework.
375
376These are what I can clearly see right now. Obviously users are
377capable of finding many more.
378
379I intend to continue poking on Jexer and TJIDE, and will maintain a
380branch to be "the fastest and simplest Java language IDE available",
381which will deliberately remain small.
382
383I hope that other languages choose to transliterate Jexer to provide
384TUIs to their own platforms. I will be happy to help them understand
385the code to support those efforts.