This commit is contained in:
Kevin Lamonte 2019-03-08 20:25:38 -06:00
parent d6f0983d09
commit a7f45950d2
3 changed files with 50 additions and 298 deletions

348
README.md
View file

@ -2,54 +2,33 @@ Jexer - Java Text User Interface library
========================================
This library implements a text-based windowing system loosely
reminiscient of Borland's [Turbo
Vision](http://en.wikipedia.org/wiki/Turbo_Vision) system. (For those
wishing to use the actual C++ Turbo Vision library, see [Sergio
Sigala's C++ version based on the sources released by
Borland,](http://tvision.sourceforge.net/) or consider Free Pascal's
[Free Vision library.](http://wiki.freepascal.org/Free_Vision))
reminiscent of Borland's [Turbo
Vision](http://en.wikipedia.org/wiki/Turbo_Vision) system. It looks
like this:
Jexer currently supports three backends:
![Several Windows Open Including A Terminal](/screenshots/screenshot1.png?raw=true "Several Windows Open Including A Terminal")
* System.in/out to a command-line ECMA-48 / ANSI X3.64 type terminal
(tested on Linux + xterm). I/O is handled through terminal escape
sequences generated by the library itself: ncurses is not required
or linked to. xterm mouse tracking is supported using both UTF8 and
SGR coordinates. Images are optionally rendered via sixel graphics
(see jexer.ECMA48.sixel). For the demo application, this is the
default backend on non-Windows/non-Mac platforms.
Jexer works on both Xterm-like terminals and Swing, and supports
images in both Xterm and Swing. On Swing, images are true color:
* The same command-line ECMA-48 / ANSI X3.64 type terminal as above,
but to any general InputStream/OutputStream or Reader/Writer. See
the file jexer.demos.Demo2 for an example of running the demo over a
TCP (telnet) socket. jexer.demos.Demo3 demonstrates how one might
use a character encoding than the default UTF-8.
![Swing Snake Image](/screenshots/snake_swing.png?raw=true "Swing Snake Image")
* Java Swing UI. The default window size for Swing is 80x25 and 20
point font; this can be changed in the TApplication(BackendType)
constructor. For the demo applications, this is the default backend
on Windows and Mac platforms. This backend can be explicitly
selected for the demo applications by setting jexer.Swing=true.
On Xterm, images are dithered to a common palette:
Additional backends can be created by subclassing
jexer.backend.Backend and passing it into the TApplication
constructor. See Demo5 and Demo6 for examples of other backends.
The Jexer homepage, which includes additional information and binary
release downloads, is at: https://jexer.sourceforge.io . The Jexer
source code is hosted at: https://gitlab.com/klamonte/jexer .
![Xterm Snake Image](/screenshots/snake_xterm.png?raw=true "Xterm Snake Image")
License
-------
This project is licensed under the MIT License. See the file LICENSE
Jexer is available to all under the MIT License. See the file LICENSE
for the full license text.
Maven
-----
Obtaining Jexer
---------------
Jexer is available on Maven Central:
@ -61,87 +40,25 @@ Jexer is available on Maven Central:
</dependency>
```
Binary releases are available on SourceForge:
https://sourceforge.net/projects/jexer/files/jexer/
Acknowledgements
----------------
Jexer makes use of the Terminus TrueType font [made available
here](http://files.ax86.net/terminus-ttf/) .
The Jexer source code is hosted at: https://gitlab.com/klamonte/jexer
Usage
-----
Simply subclass TApplication and then run it in a new thread:
```Java
import jexer.*;
class MyApplication extends TApplication {
public MyApplication() throws Exception {
super(BackendType.SWING); // Could also use BackendType.XTERM
// Create standard menus for File and Window
addFileMenu();
addWindowMenu();
// Add a custom window, see below for its code. The TWindow
// constructor will add it to this application.
new MyWindow(this);
}
public static void main(String [] args) throws Exception {
MyApplication app = new MyApplication();
(new Thread(app)).start();
}
}
```
Similarly, subclass TWindow and add some widgets:
```Java
class MyWindow extends TWindow {
public MyWindow(TApplication application) {
// See TWindow's API for several constructors. This one uses the
// application, title, width, and height. Note that the window width
// and height include the borders. The widgets inside the window
// will see (0, 0) as the top-left corner inside the borders,
// i.e. what the window would see as (1, 1).
super(application, "My Window", 30, 20);
// See TWidget's API for convenience methods to add various kinds of
// widgets. Note that ANY widget can be a container for other
// widgets: TRadioGroup for example has TRadioButtons as child
// widgets.
// We will add a basic label, text entry field, and button.
addLabel("This is a label", 5, 3);
addField(5, 5, 20, false, "enter text here");
// For the button, we will pop up a message box if the user presses
// it.
addButton("Press &Me!", 5, 8, new TAction() {
public void DO() {
MyWindow.this.messageBox("Box Title", "You pressed me, yay!");
}
} );
}
}
```
Put these into a file, compile it with jexer.jar in the classpath, run
it and you'll see an application like this:
![The Example Code Above](/screenshots/readme_application.png?raw=true "The application in the text of README.md")
More Examples
Documentation
-------------
* [Java API Docs](https://jexer.sourceforge.io/apidocs/api/index.html)
* [Wiki](https://gitlab.com/klamonte/jexer/wikis/home)
Programming Examples
--------------------
The examples/ folder currently contains:
* A [prototype tiling window
@ -156,19 +73,18 @@ jexer.demos contains official demos showing all of the existing UI
controls. The demos can be run as follows:
* 'java -jar jexer.jar' . This will use System.in/out with
xterm-like sequences on non-Windows non-Mac platforms. On Windows
Xterm-like sequences on non-Windows non-Mac platforms. On Windows
and Mac it will use a Swing JFrame.
* 'java -Djexer.Swing=true -jar jexer.jar' . This will always use
Swing on any platform.
* 'java -cp jexer.jar jexer.demos.Demo2 PORT' (where PORT is a
number to run the TCP daemon on). This will use the telnet
protocol to establish an 8-bit clean channel and be aware of
screen size changes.
number to run the TCP daemon on). This will use the Xterm backend
on a telnet server that will update with screen size changes.
* 'java -cp jexer.jar jexer.demos.Demo3' . This will use
System.in/out with xterm-like sequences. One can see in the code
System.in/out with Xterm-like sequences. One can see in the code
how to pass a different InputReader and OutputReader to
TApplication, permitting a different encoding than UTF-8.
@ -179,7 +95,7 @@ controls. The demos can be run as follows:
demo applications using different fonts in the same Swing frame.
* 'java -cp jexer.jar jexer.demos.Demo6' . This demonstrates two
applications performing I/O across three screens: an xterm screen
applications performing I/O across three screens: an Xterm screen
and Swing screen, monitored from a third Swing screen.
@ -187,8 +103,6 @@ controls. The demos can be run as follows:
More Screenshots
----------------
![Several Windows Open Including A Terminal](/screenshots/screenshot1.png?raw=true "Several Windows Open Including A Terminal")
![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.")
![Sixel Pictures Of Cliffs Of Moher And Buoy](/screenshots/sixel_images.png?raw=true "Sixel Pictures Of Cliffs Of Moher And Buoy")
@ -196,11 +110,11 @@ More Screenshots
![Sixel Color Wheel](/screenshots/sixel_color_wheel.png?raw=true "Sixel Color Wheel")
Terminal Support
----------------
The table below lists terminals tested against Jexer's ECMA48/Xterm
backend.
The table below lists terminals tested against Jexer's Xterm backend:
| Terminal | Environment | Mouse Click | Mouse Cursor | Images |
| -------------- | ------------------ | ----------- | ------------ | ------ |
@ -233,189 +147,27 @@ backend.
System Properties
-----------------
The following properties control features of Jexer:
jexer.Swing
-----------
Used only by jexer.demos.Demo1 and jexer.demos.Demo4. If true, use
the Swing interface for the demo application. Default: true on
Windows (os.name starts with "Windows") and Mac (os.name starts with
"Mac"), false on non-Windows and non-Mac platforms.
jexer.Swing.cursorStyle
-----------------------
Used by jexer.backend.SwingTerminal. Selects the cursor style to
draw. Valid values are: underline, block, outline. Default:
underline.
jexer.Swing.tripleBuffer
------------------------
Used by jexer.backend.SwingTerminal. If true, use triple-buffering
which reduces screen tearing but may also be slower to draw on
slower systems. If false, use naive Swing thread drawing, which may
be faster on slower systems but also more likely to have screen
tearing. Default: true.
jexer.TTerminal.ptypipe
-----------------------
Used by jexer.TTerminalWindow. If true, spawn shell using the
'ptypipe' utility rather than 'script'. This permits terminals to
resize with the window. ptypipe is a separate C language utility,
available at https://gitlab.com/klamonte/ptypipe. Default: false.
jexer.TTerminal.closeOnExit
---------------------------
Used by jexer.TTerminalWindow. If true, close the window when the
spawned shell exits. Default: false.
jexer.ECMA48.rgbColor
---------------------
Used by jexer.backend.ECMA48Terminal. If true, emit T.416-style RGB
colors for normal system colors. This is expensive in bandwidth,
and potentially terrible looking for non-xterms. Default: false.
jexer.ECMA48.sixel
------------------
Used by jexer.backend.ECMA48Terminal. If true, emit image data
using sixel, otherwise show blank cells where images could be. This
is expensive in bandwidth, very expensive in CPU (especially for
large images), and will leave artifacts on the screen if the
terminal does not support sixel. Default: true.
Known Issues / Arbitrary Decisions
----------------------------------
Some arbitrary design decisions had to be made when either the
obviously expected behavior did not happen or when a specification was
ambiguous. This section describes such issues.
- See jexer.tterminal.ECMA48 for more specifics of terminal
emulation limitations.
- TTerminalWindow uses cmd.exe on Windows. Output will not be seen
until enter is pressed, due to cmd.exe's use of line-oriented
input (see the ENABLE_LINE_INPUT flag for GetConsoleMode() and
SetConsoleMode()).
- TTerminalWindow by default launches 'script -fqe /dev/null' or
'script -q -F /dev/null' on non-Windows platforms. This is a
workaround for the C library behavior of checking for a tty:
script launches $SHELL in a pseudo-tty. This works on Linux and
Mac but might not on other Posix-y platforms.
- Closing a TTerminalWindow without exiting the process inside it
may result in a zombie 'script' process.
- When using the Swing backend, and not using 'ptypipe', closing a
TTerminalWindow without exiting the process inside it may result
in a SIGTERM to the JVM causing it to crash. The root cause is
currently unknown, but is potentially a bug in more recent
releases of the 'script' utility from the util-linux package.
- TTerminalWindow can only notify the child process of changes in
window size if using the 'ptypipe' utility, due to Java's lack of
support for forkpty() and similar. ptypipe is available at
https://gitlab.com/klamonte/ptypipe.
- Java's InputStreamReader as used by the ECMA48 backend requires a
valid UTF-8 stream. The default X10 encoding for mouse
coordinates outside (160,94) can corrupt that stream, at best
putting garbage keyboard events in the input queue but at worst
causing the backend reader thread to throw an Exception and exit
and make the entire UI unusable. Mouse support therefore requires
a terminal that can deliver either UTF-8 coordinates (1005 mode)
or SGR coordinates (1006 mode). Most modern terminals can do
this.
- jexer.session.TTYSession calls 'stty size' once every second to
check the current window size, performing the same function as
ioctl(TIOCGWINSZ) but without requiring a native library.
- jexer.backend.ECMA48Terminal calls 'stty' to perform the
equivalent of cfmakeraw() when using System.in/out. System.out is
also (blindly!) put in 'stty sane cooked' mode when exiting.
- jexer.backend.ECMA48Terminal uses a single palette containing
MAX_COLOR_REGISTERS colors for all sixel images. These colors are
generated in the SixelPalette.makePalette() method with bits for
hue, saturation, and luminance, and the two extremes set to pure
black and pure white. This provides a reasonable general-purpose
palette light on CPU, but at a cost that individual images do not
look as good as the terminal is actually capable of.
See Also
--------
[Tranquil Java IDE](https://tjide.sourceforge.io) is a TUI-based
integrated development environment for the Java language that was
built using a very lightly modified GPL version of Jexer. TJ provided
a real-world use case to shake out numerous bugs and limitations of
Jexer.
* [Tranquil Java IDE](https://tjide.sourceforge.io) is a TUI-based
integrated development environment for the Java language that was
built using a very lightly modified GPL version of Jexer. TJ
provided a real-world use case to shake out numerous bugs and
limitations of Jexer.
* [LCXterm](https://lcxterm.sourceforge.io) is a curses-based terminal
emulator that allows one to use Jexer with full support on the raw
Linux console.
* [ptypipe](https://gitlab.com/klamonte/ptypipe) is a small C utility
that permits a Jexer TTerminalWindow to resize the running shell
when its window is resized.
Maintainers Wanted
------------------
Acknowledgements
----------------
Both Jexer and TJIDE are seeking additional maintainers. I am not in
a position in life to take on significant off-hours programming work,
and am willing to hand these projects over to one or more persons with
time and interest.
My personal code design philosophy for TJIDE/Jexer is outlined at
https://gitlab.com/klamonte/tjide/blob/master/java/docs/code_design.txt
. I realize that some of the features listed below may require
deviations from this philosophy, but this is what I have built so far.
Some of the areas that will likely require significant efforts are:
* Editor improvements. The editor is currently very minimalistic,
much closer to MS-DOS edit.com than a real programmer's editor.
Users will probably desire many more features: drag-and-drop, real
syntax or at least regexp highlighting (not just keywords), paren
matching, paragraph/comment reflow, and dozens more. The
underlying Document/Line/Word model is not going to be sufficient
to meet these features.
* Better Windows and OSX support. It would be nice to ship a
jlink'ed JVM on these platforms with the JRE, JDK, and JPDA
modules all together. For Windows, it might be preferable to
consider doing any of the following: ship a third-party terminal,
use PowerShell, or use the newer ConPTY for TTerminalWindow.
* Bug fixes. The Jexer codebase is quite large despite my best
efforts. Bugs are typically very small to fix, but can take some
time to find: a simple NPE or AssertionError can sometimes take
4-8 hours to squash. Fortunately, fixing issues in one place has
not often led to breakages elsewhere.
* New Jexer applications. So far as I know, Jexer is the only
mouse-supporting full TUI windowing framework with sixel image
support in existence. I cannot predict what kinds of applications
could be built out of it, and how those needs will push back to
the framework.
These are what I can clearly see right now. Obviously users are
capable of finding many more.
I intend to continue poking on Jexer and TJIDE, and will maintain a
branch to be "the fastest and simplest Java language IDE available",
which will deliberately remain small.
I hope that other languages choose to transliterate Jexer to provide
TUIs to their own platforms. I will be happy to help them understand
the code to support those efforts.
Jexer makes use of the Terminus TrueType font [made available
here](http://files.ax86.net/terminus-ttf/) .

BIN
screenshots/snake_swing.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

BIN
screenshots/snake_xterm.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB