Re: basic GUI question
jrobinss schrieb:
Hi all, I'm very sorry about the simplicity of this question, but I
don't seem to get around it.
First, this is what I want:
a command-line interface (CLI) program that displays a dialog asking
something from the user. The user has the choice, either answer the
graphic dialog or else type in "stop" in the CLI (which hides or
destroys the GUI).
Seems simple enough. The principle is to launch the CLI, upon
receiving command "start" launch the GUI in a separate thread, and
wait both for user input in the dialog and in CLI.
My problems, of course, stem from the famous EDT. I've taken the
opportunity to read up on it (not enough I suppose), but I still can't
get it right. Either my dialog is ok, but the CLI hangs, or the CLI
responds, but the dialog is erratic, with freezes (an behavior
described on several web sites and attributes to bad thread
management).
Question: who can give me the code? :-)
More detailed question: here are some code samples that obviously
don't work, otherwise I wouldn't be here; Any comments welcome.
Note: I've suppressed some code building the CLI, so it's not an
SSCCE. I suspect that there are enough wrongs in what I'm posting to
start correcting. If not, I'll post an SSCCE.
I'm a bit confused about your code because I don't see the part where
the CLI input is read. I believe however, that this (Thread?) is where
your problem is.
Anyway, does the attached code work for you? It creates the dialog in
one thread (the EDT) and creates a separate thread for the CLI. Both
threads notify each other when they have a result. I don't have an
elegant solution to avoid the Thread.stop() in the end, except maybe
making this thread a daemon thread. I am not aware of any more elegant
method to stop a thread while it is reading input (Closing the stream?
Rather not.).
Some remarks regarding your version:
- At least in one place you are creating a Thread where you only need a
Runnable.
- For most people it is easier to follow your code if it follows Java
code conventions. E.g. is CliCommand.start a constant (=static final)?
Then use UPPERCASE names etc.
Cheers,
Simon
import java.util.Scanner;
import javax.swing.JDialog;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class Test {
private static Object lock = new Object();
private static String answer = null;
private static JDialog dialog;
public static void main(String[] argv) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
dialog = new JDialog();
JTextField field = new JTextField(10);
dialog.getContentPane().add(field);
dialog.setModal(true);
dialog.pack();
dialog.setVisible(true);
synchronized (lock) {
if (answer == null) {
Test.answer = field.getText();
} else {
System.err.println("CLI has set answer. "+
"Ignoring answer from GUI.");
}
lock.notify();
}
}
});
Thread cliThread = new Thread("CLI-Thread") {
@Override
public void run() {
System.out.println("Please type your answer: ");
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
synchronized (lock) {
Test.answer = input;
lock.notify();
}
}
};
cliThread.start();
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (dialog.isVisible()) {
dialog.setVisible(false);
}
if (cliThread.isAlive()) {
// don't do this, only for demo
cliThread.stop();
}
System.out.println("Answer = " + answer);
}
System.exit(0);
}
}