Reputation: 1612
Apologies for the bad title. I am working on a game that uses a JTextPane as the main text view. I use the following code to print to the pane:
public void write(String txt, MessageType t) {
try {
for (char c : txt.toCharArray()) {
text.getDocument().insertString(text.getDocument().getLength(), String.valueOf(c), t.getAttributes());
Utils.pause(30);
}
text.getDocument().insertString(text.getDocument().getLength(), "\n", t.getAttributes());
}
catch (Exception e) { e.printStackTrace(); }
}
That code writes each character one at a time, sleeping for 30 milliseconds between each writing. It then writes a new line character. Here's the pause() method if you're interested:
public static void pause(int millis) {
try { Thread.sleep(millis); }
catch (InterruptedException e) { e.printStackTrace(); }
}
Most of the time, this works fine. It writes each character with some space in between, giving the impression of typing. However, there is one instance where it does not work.
I have a JTextField that handles input. I added this KeyListener to it:
input.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
CommandParser.getInstance().parse(input.getText());
input.setText("");
}
}
});
At the end of the parse() method of CommandParser, if a command isn't found, this line runs:
Game.getInstance().getGUI().write("Invalid command.", GUI.MessageType.BAD);
However, for that line only, the program waits a second, then prints everything at once, instead of printing one character every 30 milliseconds. Why is this? Does this have to do with inner classes?
Upvotes: 0
Views: 323
Reputation: 41188
This is because your action is happening on the EDT thread. The GUI will not update at all until you return from that method. You need to use something like SwingWorker
or SwingTimer
to farm the updates out to another thread.
Upvotes: 5