Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I'm writing a rock paper scissors GUI application and in one of my JPanels, I have a JLabel. This JLabel is supposed to say Rock for one second, then Paper for one second and then Scissors for one second. It's so far only showing the JLabel text for Shoot at the end. I can't seem to figure out why. Can anyone help?

Code:

import javax.swing.*;
import java.awt.*;

class RockPaperScissorsShoot {
    public JFrame shootFrame;
    JPanel shootPanel;
    JLabel shootLabel;
    int flagThing = 0;

    public RockPaperScissorsShoot(Window gameWindow) {
        shootFrame = new JFrame();
        shootFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        shootFrame.setSize(250, 150);

        shootPanel = new JPanel(new GridLayout(1, 1));
        shootFrame.add(shootPanel);

        shootLabel = new JLabel();
        shootPanel.add(shootLabel);

        shootFrame.setVisible(true);

        shootFrame.setTitle("Rock!"); // the title changes
        shootLabel.setText("Rock!"); // but the JLabel text does not

        waitForMilSecs(1000);

        shootFrame.setTitle("Paper!");
        shootLabel.setText("Paper!");

        waitForMilSecs(1000);

        shootFrame.setTitle("Scissors!");
        shootLabel.setText("Scissors!");

        waitForMilSecs(1000);

        shootFrame.setTitle("Shoot!");
        shootLabel.setText("Shoot!"); //Except here, right here, the text shows up
    }

    public static void waitForMilSecs(long ms) {
        long checkMS = System.currentTimeMillis() + ms;
        while (System.currentTimeMillis() <= checkMS) {
            System.out.println("Not yet!");
        }
        System.out.println("NOW!");
    }
}

Edit: I've tried adding a SwingWorker to handle the waiting in a separate thread. I still get a frozen GUI. Code:

import java.awt.*;
import java.util.concurrent.ExecutionException;
import javax.swing.*;
//import javax.swing.event.ChangeEvent;
import javax.swing.SwingWorker.StateValue;

class RockPaperScissorsShoot {
    public JFrame shootFrame;
    JPanel shootPanel;
    JLabel shootLabel;
    int flagThing = 0;

    public RockPaperScissorsShoot(Window gameWindow) {
        shootFrame = new JFrame();
        shootFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        shootFrame.setSize(250, 150);

        shootPanel = new JPanel(new GridLayout(1, 1));
        shootFrame.add(shootPanel);

        shootLabel = new JLabel();
        shootPanel.add(shootLabel);

        shootFrame.setVisible(true);

        changeText(false, "Rock!", shootLabel, shootFrame, 1);
        changeText(true, "Paper!", shootLabel, shootFrame, 1);
        changeText(true, "Scissors", shootLabel, shootFrame, 1);
        changeText(true, "Shoot!", shootLabel, shootFrame, 1);
    }

    public static void changeText(boolean wait, String text, JLabel shootLabel, JFrame shootFrame, long secondsToWait) {
        while (wait) {
            wait = waiter(secondsToWait * 1000);
        }
        shootFrame.setTitle(text);
        shootLabel.setText(text);
    }

    private static boolean waiter(long ms) {
        boolean keepGoing = false;
        SwingWorker sw1 = new SwingWorker() {

            @Override
            protected Boolean doInBackground() throws Exception {
                Thread.sleep(ms);
                // String res = "Finished Execution";
                return true;
            }

            @Override
            protected void done() {
                try {
                    System.out.println(get().toString());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    // Auto-generated catch block
                    e.printStackTrace();
                }
            }
        };

        // executes the swingworker on worker thread
        sw1.execute();

        while (sw1.getState() != StateValue.DONE) {
            System.out.println("Not done (debug)");
        }
        System.out.println("Done!");
        return false;
    }

    public static void waitForMilSecs(long ms) {
        long checkMS = System.currentTimeMillis() + ms;
        while (System.currentTimeMillis() <= checkMS) {
            System.out.println("Not yet!");
        }
        System.out.println("NOW!");
    }

    public static void wait(int ms) {
        try {
            Thread.sleep(ms);
        } catch (InterruptedException e) {
            System.out.println("Error waiting, cannot wait lol");
        }
    }
}

Can anyone explain to me why my GUI is freezing still?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
244 views
Welcome To Ask or Share your Answers For Others

1 Answer

Use a [Swing] Timer.
Try the following.

import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;

public class RockPaperScissorsShoot implements ActionListener {
    private JFrame shootFrame;
    private JPanel shootPanel;
    private JLabel shootLabel;
    private int flagThing = 0;
    private Timer timer;

    public RockPaperScissorsShoot() {
        shootFrame = new JFrame();
        shootFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        shootFrame.setSize(250, 150);
        shootPanel = new JPanel(new GridLayout(1, 1));
        shootFrame.add(shootPanel);
        shootLabel = new JLabel();
        shootPanel.add(shootLabel);
        shootFrame.setVisible(true);
        timer = new Timer(1000, this);
        timer.start();
    }

    public void actionPerformed(ActionEvent event) {
        String text;
        switch (flagThing) {
            case 0:
                text = "Rock!";
                break;
            case 1:
                text = "Paper!";
                break;
            case 2:
                text = "Scissors!";
                break;
            case 3:
                text = "Shoot!";
                break;
            default:
                text = null;
        }
        if (text != null) {
            shootFrame.setTitle(text);
            shootLabel.setText(text);
        }
        flagThing++;
        if (flagThing > 3) {
            timer.stop();
        }
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> new RockPaperScissorsShoot());
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...