A Swing-based read-eval-print interface
I've long been interested in improved commend-line interfaces. The latest Kawa (in SVN) has a new implementation of a command interface window. If you start up Kawa with the -w flag:
kawa -w
you get a new Swing JFrame
, whose
interesting component is a JTextPane
for typing in expressions, and displaying the results.
The following example uses Kawa's default language Scheme,
but works for other Kawa languages, including XQuery.
Color coding
Here the command prompt is in green, and the input command is in bold-face, because it seems useful to emphasize the input as a way of visually separating one command from the previous. The standard error output is in red. Standard output has the plain default style. This is because standard output may have embedded in it other objects and nested styled text.
All of these are implemented using Swing style objects. There is currently no mechanism to modify one these styles, except by modifying the source code, but at some point we will support that.
Input editing
While the color-coding is pretty, even more important is
command-line editing. That is you can move the input cursor
along the input line, and insert, delete, or replace text
before hitting Enter
.
This is previously available using
the GNU readline library, which has some nice features, including
a searchable history mechanism. However, you cannot move the
cursor using the mouse, which is surprising to many.
Currently, the entire text pane is editable using the
default JTextPane
keystrokes and mouse handlers.
(It would be better that at least the prompt be non-editable.)
Nothing gets sent to the receiving reader until you type
Enter
. At that point the entire line containing
the cursor, except for the prompt, is sent to the reader.
(More precisely: If the cursor is at or after the output position,
the rest of the line after the output position is sent.
Otherwise, usually it's a way of repeating or modifying a previous
line. In that case the contents of that line, except any initial
prompt segment, are first copied to the end of the text buffer,
as if typed there, before being sent to the reader.)
If you paste a multi-line string (commonly using ctrl-V),
then ReplPane
magically interleaves the prompt string and
output with the input text. For example if you paste the following text:
(display "foo") (newline) (display "bar") (newline)
You get this result:
Note that the prompt for line 4 is different because it's a continuation line. (Alas, this feature is not very robust; it is easy to get Swing exceptions.)
Embedding Components
A powerful feature is that you "print" java.awt.Component
objects. These are embedded in the JTextPane
.
The following Scheme example creates a list of 3 JButton
objects, and that list is then "printed":
We can of course save a reference to the button in a variable:
That allows us to modify properies of the button.
Here we change its text
property, in line 4,
and the button is updated as soon as we hit enter:
One anomaly when "printing" a Component
is that a Component
can only appear once.
If we "print" it a second time, it is as a side-effect
removed from the first place it was printed:
This isn't really the right behavior, but it's unavoidable
when "printing" a Component
.
To avoid the problem, we need to "print" a some kind of
"model" object rather than "view" objects.
Embedding Viewable objects
The experimental swing-gui
library provides
"viewable model" objects that can also be "printed" to a TextPane
.
For example, the gnu.kawa.models.Button
class
goes beyond Swing's ButtonModel
in also having
text and an action procedure.
When a gnu.kawa.models.Button
is "printed" the
implementation automatically creates a JButton
that
is co-ordinated with the gnu.kawa.models.Button
:
Again, we can change the text property:
Here we do some more complex layout,
creating a Row
displaying the same button twice,
separated by a spacer. Then we create a column
that displays the same row twice, separated by a text field.
(For some reason the text field isn't displaying properly.)
Playing with composable Java2D pictures
The swing-gui
library also provides
convenience wrappers to the
gnu.kawa.models.Paintable
interface,
which makes it easy to create, compose, and transform Java2D Shape
objects.
Issues
- The
ReplPane
is not very solid. It's not hard to type something which causes a Swing exception, which is usually not recoverable. - There should be a
View
menu to modify fornts and styles, and a standardEdit
menu to Cut/Copy/Paste, at least. TheFile
menu should have a way to save the typescript. - The
Utilities->Purge Buffer
menu item doesn't work. - The display should be integrated with the Kawa pretty-printer, so that changing the window width recalculates line-breaks.
- It would be nice to emit styled "inline" (text) objects,
such as a "red string".
Maybe we should be using Swing's
HTMLDocument
instead ofDefaultStyledDocument
. Another toolkit to consider is Flying Saucer.