简体   繁体   中英

Java, JPanel not displaying in JFrame, possible concurrency issue?

I have a Vector of 4 Frames that consist of a 2D array of JButtons that is contained within a JPanel. I am trying to add these to a JFrame so that they will display an animation when looped.

I have an add method that works when I increment it manually, however when I put it in a for loop the frame stays blank as if it has not been repainted. The terminal prints the correct index numbers.

public void addNewFrame() throws InterruptedException {
    for (int i = 0; i < 10; i++) {
        if (index == 3) {
            System.out.println(index);
            remove(model.getFrame(3));
            revalidate();
            repaint();
            index = 0;
            add(model.getFrame(index), BorderLayout.CENTER);
            revalidate();
            repaint();
            Thread.sleep(300);
        } else {
            System.out.println(index);
            remove(model.getFrame(index));
            revalidate();
            repaint();
            index++;
            add(model.getFrame(index), BorderLayout.CENTER);
            revalidate();
            repaint();
            Thread.sleep(300);
        }
    }

Could this be a concurrency issue? Should I be adding the 2D array of buttons to the JPannel which is running in it's own thread?

they will display an animation when looped.

Don't use Thread.sleep() to attempt to control animation.

Animation should be done by using a Swing Timer .

Also, whenever I see code that does remove/add of a component it is almost always wrong. Instead you should be using a CardLayout . The tutorial from above also has a section on How to Use CardLayout.

You are performing identical operations in the if statements which is going to make updating that action rather difficult. If that is really the functionality you want you need to change it to something like:

for (int i = 0; i < 10; i++) {
    boolean resetIndex = false;
    remove(model.getFrame(index));
    if (index == 3) {
        index = 0;
        resetIndex = true;
    }
    System.out.println(index);
    remove(model.getFrame(index));
    revalidate();
    repaint();
    if (!resetIndex && index != 3)
        index++;
    add(model.getFrame(index), BorderLayout.CENTER);
    revalidate();
    repaint();
    Thread.sleep(300);
}

You should also look to replace your revalidate and repaint calls with updateUI which will handle the repaint calls on all children properly unlike only directing the current JComponent to paint itself.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM