This is a follow on question from Display and interact with an HTML form in a Swing application. I’ve copied the code and run it successfully while in Eclipse (Indigo) but for some mysterious reason it’s stopped working. I was able to run it several times in a row, but now I’m lucky if I can get it to work at all.
Running it with JUnit under debug, it I’ve single stepped up to thejavax.swing.SwingUtilities.invokeLater(new Runnable() { line; The next step jumps straight to the System.in.read() line effectively skipping the display logic.
I suspect its got something to the invokeLater method. From my research, invokeLater puts its Runnable() on the dispatch queue and the Runnable will be run whenever the VM gets around to it. There’s some mention that if a Runnable() experiences and exception it won’t “unwind”, which I assume means that it won’t close and will end up blocking the queue. I suspect that one of my invocations has stopped and is clogging the queue but have no idea why or how to clear the queue.
Questions:
Is there any way to clear the queue? I’ve stopped and restarted Eclipse several times thinking that would clear the dispatch queue, but no luck.
Is it possible that as far as Java is concerned the JFrame is displaying, but it’s not actually showing up on the screen so I can hit the submit button? What would cause this? Why would it work several times in a row, then suddenly stop?
Below is the relavant code.
JUnit stub:
@Test
public final void testTestForms() {
// https://stackoverflow.com/questions/6145405/display-and-interact-with-an-html-form-in-a-swing-application
Navigate n = new Navigate();
try {
n.testForms();
n= null; // in desperate attempt to garbage collect
} catch (IOException e) {
System.out.println("Error invoking n.testForms()");
e.printStackTrace();
n= null;
}
n = null;
}
The subject under study:
public class Navigate {
@Test
public void testForms() throws IOException {
System.out.println("in testForms()");
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
System.out.println("in run()");
javax.swing.JFrame jf = new javax.swing.JFrame();
jf.setSize(300, 300);
jf.setVisible(true);
jf.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
JTextPane textPane = new JTextPane();
textPane.setContentType("text/html");
textPane.setEditable(false);
textPane.setText("<html>" + "<body>" + "<form action=\"#\">"
+ "<input name=\"input1\" type=\"text\" />"
+ "<input name=\"input2\" type=\"text\" /><br/>"
+ "<input name=\"cb1\" type=\"checkbox\" /><br/>"
+ "<input name=\"rb1\" type=\"radio\" /><br/>"
+ "<input type=\"submit\" value=\"go\" />" + "</form>"
+ "</body>" + "</html>");
jf.getContentPane().setLayout(
new BoxLayout(jf.getContentPane(), BoxLayout.Y_AXIS));
jf.getContentPane().add(textPane);
HTMLEditorKit kit = (HTMLEditorKit) textPane.getEditorKit();
kit.setAutoFormSubmission(false);
textPane.addHyperlinkListener(new HyperlinkListener() {
public void hyperlinkUpdate(HyperlinkEvent e) {
if (e instanceof FormSubmitEvent) {
System.out.println(((FormSubmitEvent) e).getData());
}
}
});
}
}
);
// try to catch exceptions that could plug the queue?
try {
System.in.read();
} catch (IOException e) {
System.out.println("Error with System.in.read()");
e.printStackTrace();
throw new IOException(e);
}
try {
finalize(); // another desperate attempt
} catch (Throwable e) {
e.printStackTrace();
}
}
}
Yes because you call
setVisible(true)onJFrameinstance before all components have been added.There are also other anomalies in your code which could cause problems:
JFrame#setVisible(true)before all components have been added toJFrameJFrame#setSize(..)rather callJFrame#pack()just before settingJFramevisibleSwingUtilities.invokeLater(..)should not be nested in theJFrameclass itself rather make it so that you surround the creation of theJFrameinstance inSwingUtilitites.invokeLater(...)System.in.read()this will block the EDT thread and your UI will freezeJFrameinstance (testForms()), make sure theJFrameinstance is created within the classes constructor.Here is an exmple I made: