#25 fix OOB on mouse down
[fanfix.git] / README.md
... / ...
CommitLineData
1Jexer - Java Text User Interface library
2========================================
3
4This library implements a text-based windowing system reminiscient of
5Borland's [Turbo Vision](http://en.wikipedia.org/wiki/Turbo_Vision)
6system. (For those wishing to use the actual C++ Turbo Vision
7library, see [Sergio Sigala's C++ version based on the sources
8released by Borland,](http://tvision.sourceforge.net/) or consider
9Free Pascal's [Free Vision
10library.](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 using UTF8 and SGR coordinates
18 are supported. For the demo application, this is the default
19 backend on non-Windows/non-Mac platforms.
20
21* The same command-line ECMA-48 / ANSI X3.64 type terminal as above,
22 but to any general InputStream/OutputStream or Reader/Writer. See
23 the file jexer.demos.Demo2 for an example of running the demo over a
24 TCP socket. jexer.demos.Demo3 demonstrates how one might use a
25 character encoding than the default UTF-8.
26
27* Java Swing UI. The default window size for Swing is 80x25 and 20
28 point font; this can be changed in the TApplication(BackendType)
29 constructor. For the demo applications, this is the default backend
30 on Windows and Mac platforms. This backend can be explicitly
31 selected for the demo applications by setting jexer.Swing=true.
32
33Additional backends can be created by subclassing
34jexer.backend.Backend and passing it into the TApplication
35constructor. See Demo5 and Demo6 for examples of other backends.
36
37The Jexer homepage, which includes additional information and binary
38release downloads, is at: https://jexer.sourceforge.io . The Jexer
39source code is hosted at: https://github.com/klamonte/jexer .
40
41
42
43License
44-------
45
46This project is licensed under the MIT License. See the file LICENSE
47for the full license text.
48
49
50
51Acknowledgements
52----------------
53
54Jexer makes use of the Terminus TrueType font [made available
55here](http://files.ax86.net/terminus-ttf/) .
56
57
58
59Usage
60-----
61
62Simply subclass TApplication and then run it in a new thread:
63
64```Java
65import jexer.*;
66
67class MyApplication extends TApplication {
68
69 public MyApplication() throws Exception {
70 super(BackendType.SWING); // Could also use BackendType.XTERM
71
72 // Create standard menus for File and Window
73 addFileMenu();
74 addWindowMenu();
75
76 // Add a custom window, see below for its code. The TWindow
77 // constructor will add it to this application.
78 new MyWindow(this);
79 }
80
81 public static void main(String [] args) {
82 try {
83 MyApplication app = new MyApplication();
84 (new Thread(app)).start();
85 } catch (Throwable t) {
86 t.printStackTrace();
87 }
88 }
89}
90```
91
92Similarly, subclass TWindow and add some widgets:
93
94```Java
95class MyWindow extends TWindow {
96
97 public MyWindow(TApplication application) {
98 // See TWindow's API for several constructors. This one uses the
99 // application, title, width, and height. Note that the window width
100 // and height include the borders. The widgets inside the window
101 // will see (0, 0) as the top-left corner inside the borders,
102 // i.e. what the window would see as (1, 1).
103 super(application, "My Window", 30, 20);
104
105 // See TWidget's API for convenience methods to add various kinds of
106 // widgets. Note that ANY widget can be a container for other
107 // widgets: TRadioGroup for example has TRadioButtons as child
108 // widgets.
109
110 // We will add a basic label, text entry field, and button.
111 addLabel("This is a label", 5, 3);
112 addField(5, 5, 20, false, "enter text here");
113 // For the button, we will pop up a message box if the user presses
114 // it.
115 addButton("Press &Me!", 5, 8, new TAction() {
116 public void DO() {
117 MyWindow.this.messageBox("Box Title", "You pressed me, yay!");
118 }
119 } );
120 }
121}
122```
123
124Put these into a file, compile it with jexer.jar in the classpath, run
125it and you'll see an application like this:
126
127![The Example Code Above](/screenshots/readme_application.png?raw=true "The application in the text of README.md")
128
129See the files in jexer.demos for many more detailed examples showing
130all of the existing UI controls. The available demos can be run as
131follows:
132
133 * 'java -jar jexer.jar' . This will use System.in/out with
134 xterm-like sequences on non-Windows non-Mac platforms. On Windows
135 and Mac it will use a Swing JFrame.
136
137 * 'java -Djexer.Swing=true -jar jexer.jar' . This will always use
138 Swing on any platform.
139
140 * 'java -cp jexer.jar jexer.demos.Demo2 PORT' (where PORT is a
141 number to run the TCP daemon on). This will use the telnet
142 protocol to establish an 8-bit clean channel and be aware of
143 screen size changes.
144
145 * 'java -cp jexer.jar jexer.demos.Demo3' . This will use
146 System.in/out with xterm-like sequences. One can see in the code
147 how to pass a different InputReader and OutputReader to
148 TApplication, permitting a different encoding than UTF-8.
149
150 * 'java -cp jexer.jar jexer.demos.Demo4' . This demonstrates hidden
151 windows and a custom TDesktop.
152
153 * 'java -cp jexer.jar jexer.demos.Demo5' . This demonstrates two
154 demo applications using different fonts in the same Swing frame.
155
156 * 'java -cp jexer.jar jexer.demos.Demo6' . This demonstrates one
157 application performing I/O to two screens: an xterm screen and a
158 Swing screen.
159
160
161
162More Screenshots
163----------------
164
165![Several Windows Open Including A Terminal](/screenshots/screenshot1.png?raw=true "Several Windows Open Including A Terminal")
166
167![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.")
168
169
170
171System Properties
172-----------------
173
174The following properties control features of Jexer:
175
176 jexer.Swing
177 -----------
178
179 Used only by jexer.demos.Demo1 and jexer.demos.Demo4. If true, use
180 the Swing interface for the demo application. Default: true on
181 Windows (os.name starts with "Windows") and Mac (os.name starts with
182 "Mac"), false on non-Windows and non-Mac platforms.
183
184 jexer.Swing.cursorStyle
185 -----------------------
186
187 Used by jexer.backend.SwingTerminal. Selects the cursor style to
188 draw. Valid values are: underline, block, outline. Default:
189 underline.
190
191 jexer.Swing.tripleBuffer
192 ------------------------
193
194 Used by jexer.backend.SwingTerminal. If true, use triple-buffering
195 which reduces screen tearing but may also be slower to draw on
196 slower systems. If false, use naive Swing thread drawing, which may
197 be faster on slower systems but also more likely to have screen
198 tearing. Default: true.
199
200 jexer.TTerminal.ptypipe
201 -----------------------
202
203 Used by jexer.TTerminalWindow. If true, spawn shell using the
204 'ptypipe' utility rather than 'script'. This permits terminals to
205 resize with the window. ptypipe is a separate C language utility,
206 available at https://github.com/klamonte/ptypipe. Default: false.
207
208
209
210Known Issues / Arbitrary Decisions
211----------------------------------
212
213Some arbitrary design decisions had to be made when either the
214obviously expected behavior did not happen or when a specification was
215ambiguous. This section describes such issues.
216
217 - See jexer.tterminal.ECMA48 for more specifics of terminal
218 emulation limitations.
219
220 - TTerminalWindow uses cmd.exe on Windows. Output will not be seen
221 until enter is pressed, due to cmd.exe's use of line-oriented
222 input (see the ENABLE_LINE_INPUT flag for GetConsoleMode() and
223 SetConsoleMode()).
224
225 - TTerminalWindow by default launches 'script -fqe /dev/null' or
226 'script -q -F /dev/null' on non-Windows platforms. This is a
227 workaround for the C library behavior of checking for a tty:
228 script launches $SHELL in a pseudo-tty. This works on Linux and
229 Mac but might not on other Posix-y platforms.
230
231 - Closing a TTerminalWindow without exiting the process inside it
232 may result in a zombie 'script' process.
233
234 - TTerminalWindow can only notify the child process of changes in
235 window size if using the 'ptypipe' utility, due to Java's lack of
236 support for forkpty() and similar. ptypipe is available at
237 https://github.com/klamonte/ptypipe.
238
239 - Java's InputStreamReader as used by the ECMA48 backend requires a
240 valid UTF-8 stream. The default X10 encoding for mouse
241 coordinates outside (160,94) can corrupt that stream, at best
242 putting garbage keyboard events in the input queue but at worst
243 causing the backend reader thread to throw an Exception and exit
244 and make the entire UI unusable. Mouse support therefore requires
245 a terminal that can deliver either UTF-8 coordinates (1005 mode)
246 or SGR coordinates (1006 mode). Most modern terminals can do
247 this.
248
249 - jexer.session.TTYSession calls 'stty size' once every second to
250 check the current window size, performing the same function as
251 ioctl(TIOCGWINSZ) but without requiring a native library.
252
253 - jexer.backend.ECMA48Terminal calls 'stty' to perform the
254 equivalent of cfmakeraw() when using System.in/out. System.out is
255 also (blindly!) put in 'stty sane cooked' mode when exiting.
256
257
258
259Roadmap
260-------
261
262Many tasks remain before calling this version 1.0. See docs/TODO.md
263for the complete list of tasks.