nrubin29
nrubin29

Reputation: 1612

Thread.sleep() Not Working Sometimes

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

Answers (1)

Tim B
Tim B

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

Related Questions