0

I want my JLabel to change after 1 second but it seems that Java only displays the latest text.

Here is my code:

btnGuess.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent arg0) {
        try {
            double num = Double.parseDouble(textField.getText());
            if (num == answer) {
                lblResult.setText("CORRECT!");
            } else if (num > answer) {
                lblResult.setText("WAITING");
                Thread.sleep(1000);
                lblResult.setText("TOO LARGE");
                lblResult.setText("WAITING");
            } else {
                lblResult.setText("WAITING");
                Thread.sleep(1000);
                lblResult.setText("TOO SMALL");
            }
        } catch (Exception e) {
            lblResult.setText("Error");
        }
    }
});

What I want: display "WAITING" -> 1s -> display "TOO LARGE"

What it does: test.gif

How could I fix this?

Thank you.

Language: Java
JRE: jre1.8.0_144
IDE: Eclipse Oxygen Release (4.7.0)
USING: Swing Designer -> Application Window

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433

2 Answers2

1

Don't call Thread.sleep on the Swing event thread as this will put the entire GUI application to sleep making it useless. Instead look up the Swing Timer tutorial (check link) and use a Swing Timer. The timer uses a loop and a call to sleep in a background thread and behind the scenes, allowing the Swing event thread (known as the Event Dispatch Thread or EDT) to continue to run, allowing it to perform its important functions, including that of drawing the changes to your GUI.

Other problems: you appear to be trying to parse text to double and then compare with another double value using ==. Be careful when doing this since doubles are not like ints and == can fail due to the inexact way that digital computers hold floating point values. Use a different test of "almost" or "close-enough" equality instead.

Please see: Why can't we use '==' to compare two float or double numbers

Something like:

btnGuess.addActionListener(new ActionListener() {

    public void actionPerformed(ActionEvent e) {
        try {
            double num = Double.parseDouble(textField.getText());
            // EPSILON is a constant in the class, declared as 
            // public static final double EPSILON = 0.00001;
            if (Math.abs(num - answer) < EPSILON) {
                lblResult.setText("CORRECT!");
            } else {
                lblResult.setText("WAITING");
                final String comment = num > answer ? "TOO LARGE" : "TOO SMALL";
                int delay = 1000;
                Timer timer = new Timer(delay, new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        lblResult.setText(comment);
                    };
                });
                timer.setRepeats(false);
                timer.start();
            }
        } catch (Exception e1) {
            lblResult.setText("Error");
        }
    }
});
-2

Immediately after displaying "TOO LARGE", you change it back to "WAITING".

            lblResult.setText("WAITING");
            Thread.sleep(1000);
            lblResult.setText("TOO LARGE");
            lblResult.setText("WAITING");

Delete that last line and you're good.

            lblResult.setText("WAITING");
            Thread.sleep(1000);
            lblResult.setText("TOO LARGE");
Leo Aso
  • 11,898
  • 3
  • 25
  • 46
  • Your answer still ignores the main problem -- that of stepping on the Swing event thread, rendering it useless. – DontKnowMuchBut Getting Better Sep 24 '17 at 18:37
  • @DontKnowMuchButGettingBetter true, but the OP didn't state that sleeping on the event thread was causing problems, so I just answered the question that was asked. Plus you've already pointed it out. – Leo Aso Sep 24 '17 at 18:41
  • 1) the sleep is being called from within an ActionListener, so it's guaranteed that it's being called on the EDT, 2) if you know your Swing you already know that this is causing serious problems for the OP and will completely lock his GUI. It's a given that this is a serious problem and so shouldn't be propagated in answers, since the OP doesn't know any better -- but **you** do. Please correct this so I can remove my down-vote. – DontKnowMuchBut Getting Better Sep 24 '17 at 18:44
  • ... and no, I'm not down-voting your answer just to get mine up-voted or accepted. Note that I answered as a community wiki, meaning any up-votes that my answer gets does not improve my reputation. But I still must down-vote this answer until you improve it, at which time I'll gladly up-vote it if it's also a good answer. Please see the edits to my answer to see what is needed. – DontKnowMuchBut Getting Better Sep 24 '17 at 19:14
  • @DontKnowMuchButGettingBetter alright then. I'll probably edit the answer later or delete it altogether. Editing it right now from a mobile phone would be too tedious. – Leo Aso Sep 24 '17 at 20:12