Frequently Asked Questions |
Please
mail me your questions to
be added to the FAQ. |
General |
Why is the library called "Charva"? |
It's a contraction of CHARacter-mode jaVA.
|
Why not name the "Charva Swing" package javax.swing
instead of charvax.swing ? That way, you could run
an existing Swing application as a Charva application just by
changing the classpath. |
According to the Sun license:
You may not create, or authorize your licensees to create, additional classes,
interfaces, or subpackages that are in any way identified as "java", "javax" or "sun".
In any case, it is not practical to run Swing applications as Charva
applications without modifying some lines of source code. In Swing, for
example, dimensions are measured in pixels, whereas in Charva they are in rows and
columns.
|
How scalable is Charva? Can Charva handle multiple users in one JVM? |
Because Charva uses ncurses, each user requires his/her own instance of Charva, in its own JVM.
Having said that, I've found that I can easily run 40 instances of the Charva "Tutorial" program
(included with the download zipfile), each simulating a busy user, on a single-CPU Pentium with a
1.5GHz CPU and 768 MByte of memory. With this number of simultaneous instances there is no swapping
of memory to disk.
Bearing in mind that (in 2006) RAM costs have dropped to, say, 25 US cents per megabyte, Charva is
well suited for "intranet"-type data-capture applications with up to several thousand
simultaneous users, provided you scale horizontally across multiple servers, with several hundred
users on each server.
|
Getting CHARVA to run |
When I run my CHARVA program, it just displays the message
"Exception in main ", and returns to the shell command prompt.
How do I find out the cause?
|
Any time an uncaught exception occurs in CHARVA, a stack-trace is produced
in the file $HOME/charva.log . This gives detailed information
about the cause of the error.
|
When I run the example programs, I get the error message
"java.lang.NoClassDefFoundError java/lang/Object" . Why? |
In versions of the Charva package before 0.8.5, the example script executed
the java interpreter by just calling an executable called "java". There may be
another executable called "java" in your PATH, occurring before the
JDK1.3/JDK1.4 version of "java". Check which executable is being executed by
using the command "which -a java" . (In Charva version 0.8.5 the
example scripts were changed to execute $JAVA_HOME/bin/java).
|
When I run a Charva program,
I get the error message "Exception in thread main" , and the
$HOME/charva.log file reports Java.lang.UnsatisfiedLinkError: no
Terminal in java.library.path . What is wrong? |
Java cannot find the shared library file libTerminal.so in
its library search path. Different flavors of Unix have different
methods of specifying the library search path. On Linux, use the command:
export LD_LIBRARY_PATH=directory_containing_libTerminal.so:$LD_LIBRARY_PATH
AIX uses LIBPATH and HP-UX uses SHLIB_PATH instead of LD_LIBRARY_PATH. Note
that on HP-UX, the library file name must be libTerminal.sl , not
libTerminal.so .
|
My CHARVA program throws the following exception:
"charva.awt.IllegalComponentStateException: no focus-traversable
components inside this Container" . What is wrong?
|
When displaying a Window (i.e. a JFrame or a JDialog), CHARVA needs
to move the keyboard input focus to a component (such as a JButton
or JTextField) inside that Window. If there are no focus-traversable
components in the window, CHARVA will throw the exception.
A focus-traversable component is one which is capable of accepting the keyboard
input focus, and of passing it on to the next component, when the user
presses TAB or BACK-TAB. Note that JLabel is not
focus-traversable. Also, components that are normally focus-traversable
become non-focus-traversable when their setEnabled(false) method
is called.
To my knowledge, there is never any need in a real-world application to
display a Window that contains only non-focus-traversable components such as
labels.
|
When I try to debug a Charva program inside my
IDE (Eclipse, IDEA or other), it throws the following exception:
"LINES value must be >= 2 and <=8021: got 1; initscr(): LINES=1
COLS=1: too small" . What is wrong?
|
You can't run ncurses programs inside a graphical IDE. You have to run
them in a "terminal session" (i.e. in an "xterm" session, or an "rlogin" or "ssh"
session, or on a real physical terminal, or in a DOS shell if you're running
Windows). Having said that, you can use the IDE's debugger to debug
Charva programs (see the question "How can I debug Charva applications?"
below).
|
Why does CHARVA do this, that or
the other? |
When I run a Charva program, garbage is displayed on
my terminal. Why? |
It is essential that the $TERM environment variable is correctly
set to match the type of terminal you are using, and that the terminfo
description file correctly describes the capabilities of your terminal. For
more information on ncurses and terminfo, look at
http://en.tldp.org/HOWTO/Text-Terminal-HOWTO.html and
http://www.gnu.org/software/ncurses/ncurses.html. There is also an
O'Reilly book on
terminfo.
Incidentally, don't use the "gnome-terminal" application, which is the standard
xterm emulator in the GNOME desktop environment; it is buggy and won't work
properly with Charva. Rather use the "konsole" emulator which is the standard
emulator in the KDE environment (see next question).
|
In running the tutorial program, instead of having the frame border,
I got some fuzzy characters like this:
”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â |
The problem is in your terminfo setting. Run "infocmp" and look at the setting of
"acsc". On my PuTTY screen, for example, the setting of "acsc" looks like this:
acsc=``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~
The "acsc" setting defines an array of ASCII characters that map to the line-drawing
characters of your terminal. If these are set incorrectly, you will get weird characters
instead of the line drawing characters. I suggest you try several other settings of your
$TERM variable and see if one of them causes the correct characters to be displayed.
Then edit your "terminfo" file appropriately and run "tic" as explained elsewhere in this FAQ.
|
On Red Hat Linux, using the KDE "konsole" terminal emulator
(which sets the $TERM environment variable to "xterm"), the cursor behaves
erratically. Why?
|
I have found that the standard "xterm" terminfo description file
(distributed with Red Hat Linux) is not totally compatible with the Konsole terminal
emulator. In the root directory of the Charva download zipfile you will
find a file named "xterm.ti", which is a terminfo description in source form;
it works fine with Charva and the Konsole emulator. You can compile it
using the command "tic xterm.ti" (you have to be root to do this). You may
want to save the original xterm description file (/usr/share/terminfo/x/xterm)
before doing this.
Note that this terminfo description defines CTRL-B as the back-tab key.
The "gnome-terminal" emulator, on the other hand, doesn't seem to work properly
with any terminfo file.
|
If I run "ps aux" while a Charva program is
running, I see about a dozen instances of the same java process running. Why? |
In Linux kernels before version 2.6, native threads are implemented as separate kernel
processes, so that each thread shows up separately in the output of "ps". To avoid this
you can use "green threads" instead of "native threads"; just use the
"-classic" command-line switch with the java interpreter (this option works
with Sun's JDK1.3, but is no longer supported in JDK1.4). In Linux kernel 2.6, and in
Red Hat Enterprise Linux, threads are implemented within a single process.
|
The JDialog component in Charva is always modal, in other
words its setVisible(true) method (and the equivalent show() method) always
blocks until the dialog is hidden again. Why?
|
I felt it didn't make sense to have non-modal dialogs on a text terminal.
Note that the JFrame.show() method also blocks, except for the first
time that the application program calls it.
|
When I press TAB the cursor moves to the next enabled component,
but I can't get the cursor to move back to the previous component.
Why? |
The back-tab key must be defined in the terminfo file, and
must be mapped to the correct key (usually SHIFT-TAB) so that
you can back-tab to the previous field or component. Enter
the infocmp command to check whether the
kcbt key is defined (use the man terminfo command and search
for kcbt to get more info on this). By default, the
kcbt capability is not defined for an xterm terminal on Red Hat
Linux. If the back-tab is not defined, edit the terminfo description
for your terminal, and add in a suitable key-code for the
kcbt capability (for example, kcbt=^B will set
it to CTRL-B); then use the tic command to compile the terminfo
description. To find out the suitable key-code, see the next item in this FAQ.
To get more information about the infocmp and tic
commands, use man infocmp and man tic
|
How do I .....? |
How can I debug Charva applications? |
Since version 1.1.3, Charva uses Jakarta
commons-logging. You should use the same mechanism for adding debug statements to your code.
See the commons-logging website for details.
Another way is to use a commercial IDE such as
IntelliJ IDEA which has a good debugger built into it. You have to start the debuggee application
with certain command-line options which cause it to listen on a specified TCP port;
the debugger then opens a connection to this port. The test scripts (test.sh and test.bat)
in the distribution tarball show examples of the required command-line options.
I am told that other IDEs such as NetBeans, Eclipse and JBuilder
have the same capabilities.
|
How can I find out the key-code seen by curses when I press
key x? |
To find out what key-code is produced by any arbitrary key, run your
CHARVA program with the "charva.script.record" system property set to a
filename, as in the following example:
java -Dcharva.script.record=scriptfile \
-classpath ../classes:../lib/charva.jar classname
This will cause CHARVA to log the hexadecimal key-code of each key (and its
equivalent symbolic name, if it is a control character or function-key) in
the file "scriptfile".
|
I'm having trouble capturing function-keys in CHARVA; when I define the
charva.script.record=scriptfile property as described above, the output in
the scriptfile indicates that a sequence of bytes such as "ESC [ [
A" is produced when I press the F1 key, instead of the KeyEvent.VK_F1 code.
|
Check that the $TERM environment variable is set correctly for your terminal
type. Then run the Linux/Unix command "infocmp" to display what the terminfo
file for your terminal-type thinks the byte-sequence for the F1 key
should be. The output of the infocmp command will contain a string such as
"kf1=\EOP" , for example; this indicates that terminfo expects the F1 key to
produce the byte-sequence "ESC O P".
There are two ways of fixing the problem. If you are using a terminal-emulator,
there is usually some way of configuring the key-mapping so that any particular
key will generate a specified byte-sequence. You should configure the terminal
emulator so that each function-key generates the same byte-sequence as specified
by the terminfo file. The same applies to the cursor keys.
If you are using a non-programmable terminal or a terminal emulator with a
hardcoded key-mapping, you will have to edit the terminfo file itself. To do
this:
- run
infocmp > /tmp/termfile to decompile the terminfo file into a
human-readable format.
- Edit the file
/tmp/termfile with an ASCII editor. It may be
advisable to rename the terminal-type in this file, thus creating a new
customized terminal-type.
- Recompile the edited terminfo file with the command
tic /tmp/termfile .
To get more information about the infocmp and tic
commands, use man infocmp and man tic
|
Can I use function keys like ALT F1 in my CHARVA program? What about SHIFT F1
or CTRL F1?
|
It depends on your terminal or terminal-emulator. If your terminal-emulator
can be configured to produce a unique escape-sequence for each function key
(with the SHIFT, CTRL or ALT modifier), then that escape-sequence can be
mapped to a function-key in the terminfo file. Note that terminfo and the
ncurses library do not know or care about the SHIFT, CTRL or ALT modifiers;
they only know about function keys kf1 to kfn, where n is some arbitrarily large
integer. The unmodified function-keys are mapped to kf1 to kf12 (on a keyboard
with 12 function-keys). Typically you would map the SHIFTed function-keys to
kf13 - kf24, and so on. To do this you would have to edit and recompile the
terminfo file as described above.
As far as your Java application code is concerned, you would have to write it
to handle key-codes such as KeyEvent.VK_F13 and above; your application would
not receive an indication that the SHIFT, CTRL or ALT modifier-key was pressed
together with the function key.
Currently CHARVA defines only F1 to F20, but the definitions
can easily be extended.
|
I'm having trouble getting the cursor control keys mapped correctly. Which
fields must I edit in the terminfo file?
|
Note that all the symbols for key strings in the terminfo file start with "k".
Symbols that don't start with "k" refer to strings that are received
by the terminal, not to strings that are sent by the terminal. For
example, cuf1 is the byte-sequence which, if sent to the terminal,
will move the cursor forward one column; whereas kcuf1 is the
byte-sequence sent by the terminal when the RIGHT CURSOR key is pressed.
Here is a list of useful key symbols in the terminfo file (i.e. in the output
of infocmp or the input to tic):
kcub1 is the left-arrow key.
kcuf1 is the right-arrow key.
kcuu1 is the up-arrow key.
kcud1 is the down-arrow key.
kend is the END key.
khome is the HOME key.
knp is the PAGE DOWN key.
kpp is the PAGE UP key.
kich1 is the INSERT key.
kdch1 is the DELETE key.
|
After running my Charva application for a while, the
screen becomes corrupted with control characters. Is there a way to programmatically force a
refresh of the screen? |
Yes, call the Toolkit.redrawWin() method (to indicate to the ncurses library
that all the lines of the screen have changed and need to be redrawn), followed
by the Toolkit.sync() method to actually redraw the screen.
The underlying cause of the screen corruption may be that your terminal or
terminal-emulator is not 100% compatible with the terminfo file corresponding
to your $TERM environment variable (see questions above). Try running your
application on a different type of terminal, with $TERM set
appropriately.
|
Can I record and play back scripts? |
Yes, you can record a script file as shown above by defining the system
property "charva.script.record" as a filename. To play the
script back, define the system property "charva.script.playback" as
in the following example:
java -Dcharva.script.playback=scriptfile \
-classpath ../classes:../lib/charva.jar classname
Charva will then play back the keystrokes that were recorded in the script
file, with the original time delays between keystrokes. Since the script file
is an ASCII file, you can edit it and modify the time delays and the
keystrokes. Each line of the script file has three fields; the first field
is the hexadecimal code for the keystroke, the second field is the time
delay in milliseconds, and the third field is the symbolic name of the
keystroke (which is ignored on playback).
While the script file is being played back, any keys that you enter via the
keyboard will also be injected into the playback stream.
You can record a script on one type of terminal and play it back on another
(incompatible) terminal, because the function-keys and cursor-keys are
interpreted by ncurses before they are recorded in the script-file.
|
How do I display colors? |
To display colors, you need four things:
|
Using the LayoutManagers provided with Charva is too
complicated. Can't I lay out my components "manually"? |
You don't have to use the layout managers; they are there for "compatibility"
with AWT and Swing, and for people who want to generate a user interface on
a WYSIWIG GUI-building tool.
For those who prefer to lay out the components manually, just use the "null"
layout manager:
Container.setLayout(null);
The container will then not attempt to lay out its children, and it is up to
the application to set their locations (using the setLocation()
method inherited from charva.awt.Component ). In the case of
child components that are instances of charva.awt.Container
subclasses, the application must also set their size using
setSize() .
Note that the setLocation() method sets the top left corner of
the component, relative to the top left corner of its parent container;
except in the case of a Window (i.e a Frame or Dialog), in which case
setLocation() sets the absolute location on screen.
Note also that if you set the size of a Window (i.e. a Frame or Dialog)
explicitly in your application, you must remember not to call
the pack() method afterwards, otherwise the window will be resized to
the smallest size that can contain all its child components.
|
When writing a Charva program, should I use the components
in the charva.awt package or the charvax.swing
package? |
Use the charvax.swing package. The components in the
charvax.swing package have a far richer API.
|
I don't like the appearance of the components (buttons,
labels, frames etc) that the Charva library provides. How can I change the
appearance of the components without losing compatibility with Charva?
|
Thanks to the power of class inheritance, you can easily create your own set of
components with a customized appearance. For each customized component, simply
subclass the appropriate Charva component and override the following methods:
getSize()
minimumSize()
getHeight()
getWidth()
draw()
You should of course create your customized widgets in a separate package.
|
How do I get mouse support working?
|
Mouse events are only generated by terminal-emulators which provide the
kmous capability. To see if your terminal-emulator generates
mouse-events, run "terminfo | grep kmous " to see whether
kmous is defined. I know that "xterm" and "putty" support
mouse-events; there may be others.
|
Is Charva capable of handling non-ASCII character sets? |
Leos Urban has kindly added support for unicode (UTF-8) characters. The changes
mainly involved linking with libncursesw instead of libncurses. To quote
Leos' email: "I send to you my changes to Charva, tested with Linux (Fedora Core 5).
With my changes I can display unicode (UTF-8) characters without problem
(see attached screenshot animal_cz.gif
- grabbed from linux with cs_CZ.UTF-8 locale)".
The English version of the same screen is
animal_en.gif
According to Leos, there are some limitations to the UTF-8 support:
"With JTextArea I cannot type any national characters, after some changes
I can type most of characters in JTextEdit (but 0x11b and 0x10d do simply
nothing and 0x161 works as backtab)."
|
In the JFileChooser and JOptionPane, having to TAB
from one button to the next is too slow; I would like to set up
"hot-keys" or "accelerator keys" that are equivalent to individual
buttons. Also, I want to be able to customize the button-labels to indicate
these hot-keys.
|
JFileChooser and JOptionPane allow you to customize the button-labels and set
up accelerator keys, by modifying static (class) variables. Look at the
javadoc-generated documentation of these classes, or at the tutorial
application (tutorial/charva/Tutorial.java) for more information on this feature.
|
After I change the terminal to 132-column mode, Charva
still clips the display to 80 columns. How can I make it show all 132 columns?
|
Call the following code after changing to 132-column mode:
Toolkit.getDefaultToolkit().resetClipRect();
|
How can I display a JFrame without the line-borders?
I need to be able to use all of the available space on the screen.
|
Just create a subclass of JFrame that has zero-width insets, as follows:
public class MyFrame extends JFrame {
public MyFrame() {
super();
super._insets = new Insets(0, 0, 0, 0);
}
}
Then just use your customized subclass instead of JFrame - it will draw itself without
borders.
|
In my CHARVA application, I have a collection of screens
that I want to display in any order, selectable at runtime. How can I do this?
|
In the CHARVA application programming model, the very first window to be
displayed must be a JFrame (in other words, this must be the "main window"
of your application). This may be a full-screen frame (as described
above) or a frame with a border. This "main" frame then creates other JFrames
and/or JDialogs (collectively known as Windows) and displays them, using
their show() method. Each window can create and show further
windows, thus building up a "stack" of windows.
Each window can hide itself by calling its own
hide() method. This effectively "pops" the window off the stack,
and causes the previous show() method to return.
Note that calling hide() does not destroy the window; it
remains in existence and can be redisplayed, in exactly the same state as
it was before, by calling its show() method again.
If your application is always going to display screens (windows) in the same
order, you can just get each window to create and show the next one in
the sequence, thus building up the "stack". On the other hand, if the
display order must be determined at
runtime, you can use the following approach. Assume you have three screen
classes A, B and C, and you want to show them in the order
A -> B -> C -> A:
A a = new A();
B b = new B();
C c = new C();
a.show(); // show() blocks until a hides itself
b.show(); // show() blocks until b hides itself
c.show(); // show() blocks until c hides itself
a.show(); // show() blocks until a hides itself
|
How do I do pass-through printing (i.e. to a printer attached to
the terminal)? |
The terminfo file for the terminal must have the "mc4" and "mc5" capabilities
defined, for turning the attached printer off and on. For more information
about these capabilities, do a "man terminfo" and look for "mc4" and "mc5". The
vt220 terminfo file, for example, does have these capabilities defined.
Use the following code to do the printing:
Toolkit toolkit = Toolkit.getDefaultToolkit();
.
.
.
try {
toolkit.print(String_to_be_printed);
} catch (TerminfoCapabilityException e) {
...
}
Thanks to Craig O'Shannessy for information about this issue.
|
How do I print the screen contents (to a printer
attached to the terminal)? |
The terminfo file for the terminal must have the "mc0" capability
defined. Do a "man terminfo" and look for "mc0". The
vt220 terminfo file, for example, does have this capability defined.
Use the following code to do the printing:
Toolkit toolkit = Toolkit.getDefaultToolkit();
String print_screen = toolkit.getStringCapability("mc0");
.
.
toolkit.putp(print_screen);
|
My terminal has an output port (activated by an escape
sequence) for opening a cash drawer. How do I activate this port
using Charva? |
You have to define a "user-defined capability string" (containing the
escape-code sequence for activating the output) in your terminfo file. Do
a "man terminfo" and look for "u0". You will notice that you can define up to
ten user-defined capabilities, named u0 to u9. After adding the user-defined
capability, compile the terminfo file using "tic". Then use the
Toolkit.putp() method to output the user-defined string to the
terminal, as follows:
Toolkit toolkit = Toolkit.getDefaultToolkit();
String open_drawer = toolkit.getStringCapability("u0");
.
.
.
toolkit.putp(open_drawer);
|
Can I use a bar-code scanner with Charva? |
Yes, the bar-code scanner is typically attached to the keyboard port of the
terminal; Charva cannot tell whether characters are entered via the barcode
scanner or manually via the keyboard.
|
Can I call the methods of the various CHARVA components from arbitrary threads
in a multi-threaded program? |
No; as in Swing, most of the methods are not synchronized (for performance reasons,
as well as to avoid deadlocks). Exceptions are:
- JTextComponent.setText
- JTextArea.insert
- JTextArea.append
- JTextArea.replaceRange
The subject is very well explained in Chapter 1 of
"Core Java 2, Volume 2 - Advanced Features" by Horstmann and Cornell.
(page 61, in the subsection titled "Threads and Swing").
Like Swing, CHARVA does all of its drawing (i.e. all of the ncurses
function calls, besides reading the keyboard) in a single "event dispatcher"
thread. If you want to modify the display from other threads, you should use
the static SwingUtilities.invokeLater(Runnable) method, as described
in the Core Java book.
|
My Charva application performs a time-consuming operation (for example,
a network operation) and the user-interface "freezes" until the operation
has completed. How can I make the user interface responsive while the
time-consuming operation is progressing?
|
Spawn a separate "worker" thread to do the time-consuming task, and use the
technique described above (the SwingUtilities.invokeLater() method)
for the worker thread to communicate with the Charva event-handling thread.
The worker thread can call SwingUtilities.invokeLater() at various stages of
its progress, causing Charva to (for example) update a JProgressBar.
The Tutorial program (tutorial/charva/Tutorial.java) included in the
distribution zipfile includes an example of how to perform a time-consuming
task in a separate worker thread.
|