J
jrobinss
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.
public class DialogTest {
[ ... main and other stuff...]
private Thread dialogThread_ = null;
private Frame myFrame_ = buildFrame();
private Frame buildFrame() {
// builds a kind of GUI, its correctness is not important here
JFrame frame = new JFrame("my frame");
JTextField myTxtField = new JTextField(10);
Object[] messageElements = {"Some question", myTxtField};
JOptionPane optionPane = new JOptionPane(messageElements,
JOptionPane.QUESTION_MESSAGE,
JOptionPane.YES_NO_OPTION);
frame.setContentPane(optionPane);
return frame;
}
private void onInput(String input) { // some callback
System.out.println("input=" + input);
}
/**
* this implementation doesn't provide any means for the user to
* stop the GUI using CLI, because it waits for a GUI answer.
*/
public void processCommandBasic(CliCommand cmd) {
if (cmd == CliCommand.start) {
String answer = JOptionPane.showInputDialog(myFrame_,
"What?");
onInput(answer);
} else {
myFrame_.setVisible(false);
}
}
/**
* this implementation hands back the hand to the CLI,
* but freezes the first time the user tries to input.
*/
public void processCommandWithMyFrame(CliCommand cmd) {
if (cmd == CliCommand.start) {
myFrame_.pack();
myFrame_.setVisible(true); // input to be handled by frame
} else {
myFrame_.setVisible(false);
}
}
/**
* this freezes and hangs the first time it's called.
*/
public void processCommandUsingJOptionPane(CliCommand cmd) {
if (cmd == CliCommand.start) {
dialogThread_ = new Thread() {
@Override
public void run() {
String answer =
JOptionPane.showInputDialog(myFrame_, "What?");
onInput(answer);
}
};
SwingUtilities.invokeLater(dialogThread_);
} else {
myFrame_.setVisible(false);
}
}
/**
* this works the same as the previous one, but with a frame.
*/
public void processCommandUsingFrame(CliCommand cmd) {
if (cmd == CliCommand.start) {
Runnable showDialog = new Runnable() {
public void run() {
myFrame_.pack();
myFrame_.setVisible(true);
}
};
SwingUtilities.invokeLater(showDialog);
} else {
myFrame_.setVisible(false);
}
}
}
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.
public class DialogTest {
[ ... main and other stuff...]
private Thread dialogThread_ = null;
private Frame myFrame_ = buildFrame();
private Frame buildFrame() {
// builds a kind of GUI, its correctness is not important here
JFrame frame = new JFrame("my frame");
JTextField myTxtField = new JTextField(10);
Object[] messageElements = {"Some question", myTxtField};
JOptionPane optionPane = new JOptionPane(messageElements,
JOptionPane.QUESTION_MESSAGE,
JOptionPane.YES_NO_OPTION);
frame.setContentPane(optionPane);
return frame;
}
private void onInput(String input) { // some callback
System.out.println("input=" + input);
}
/**
* this implementation doesn't provide any means for the user to
* stop the GUI using CLI, because it waits for a GUI answer.
*/
public void processCommandBasic(CliCommand cmd) {
if (cmd == CliCommand.start) {
String answer = JOptionPane.showInputDialog(myFrame_,
"What?");
onInput(answer);
} else {
myFrame_.setVisible(false);
}
}
/**
* this implementation hands back the hand to the CLI,
* but freezes the first time the user tries to input.
*/
public void processCommandWithMyFrame(CliCommand cmd) {
if (cmd == CliCommand.start) {
myFrame_.pack();
myFrame_.setVisible(true); // input to be handled by frame
} else {
myFrame_.setVisible(false);
}
}
/**
* this freezes and hangs the first time it's called.
*/
public void processCommandUsingJOptionPane(CliCommand cmd) {
if (cmd == CliCommand.start) {
dialogThread_ = new Thread() {
@Override
public void run() {
String answer =
JOptionPane.showInputDialog(myFrame_, "What?");
onInput(answer);
}
};
SwingUtilities.invokeLater(dialogThread_);
} else {
myFrame_.setVisible(false);
}
}
/**
* this works the same as the previous one, but with a frame.
*/
public void processCommandUsingFrame(CliCommand cmd) {
if (cmd == CliCommand.start) {
Runnable showDialog = new Runnable() {
public void run() {
myFrame_.pack();
myFrame_.setVisible(true);
}
};
SwingUtilities.invokeLater(showDialog);
} else {
myFrame_.setVisible(false);
}
}
}