0

我的代码使用卡片布局向用户显示(预定义的)带有 JButton 的 JPanel,然后显示一个动态生成的 JPanel 及其响应的反馈,然后再继续下一个预定义的 JPanel。但是,我无法显示动态生成的 JPanel,并且在使用 revalidate() 和 repaint() 之类的命令时有些混乱,我不知道接下来要尝试什么。我可能犯了一个相当简单的错误,但是在尝试了很多组合之后,我有点卡住了!

编辑:对不起,那是我之前发布的一段相当无用的代码!我花时间编写了一个更好的 SSCCE,它看起来确实与使用 Thread.sleep 有关,但我对此并不满意,所以不太确定我需要做什么才能使其正常工作。这是我的例子:

public class ExampleClass implements ActionListener{

public void doStuff(){
    ExampleClass ec = new ExampleClass();
    startExperiment();

}

public static void main(String[] args){

    ExampleClass e = new ExampleClass();
    e.doStuff();
}


JPanel j;
int count = 0;
CardLayout cards = new CardLayout();
JButton button;

public void startExperiment(){

    // Create frame and JFrames
    JFrame trial = new JFrame();

    trial.setSize(800,600);

    JPanel j1 = new JPanel();
    JPanel j2 = new JPanel();
    j1.setSize(800,600);
    button = new JButton("Click me!");
    button.addActionListener(this);

    j2.setSize(800,600);
    j1.add(new JLabel("A Panel"));
    j1.add(button);
    j2.add(new JLabel("Another Panel"));
    JPanel[] pans = {j1,j2};


    j = new JPanel();
    j.setLayout(cards);

    for(int i=0;i<pans.length;i++){
        j.add(pans[i], "Card"+i);
    }

    JPanel end = new JPanel();
    end.add(new JLabel("The end!"));
    j.add(end,"End");
    trial.add(j);
    trial.setVisible(true);
}



public void nextTrial(){

    JPanel ps = new JPanel();
    ps.add(new JLabel("This panel won't display!"));
    j.add(ps,"Pause"+count);
    cards.show(j,"Pause"+count);

}

class aThread extends Thread {
    public aThread(int duration){
        dur=duration;
    }
    int dur;
    public void run() {
        try {
            Thread.sleep(dur);
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public void pause(int dur){
    aThread myThread = new aThread(dur);
    myThread.start();
    try {
        myThread.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }


}

@Override
public void actionPerformed(ActionEvent e) {
    if(e.getSource()==button){
        System.out.println("Ow!");
        nextTrial();
        pause(500);
        cards.show(j,"Card1");
    }

}

}

我意识到这与我大约 12 个月前在这里问过的问题类似(http://stackoverflow.com/questions/9200072/jpanel-not-updating-cardlayout-properly-when-i-use-sleep?rq= 1),但我错误地认为使用 Thread.join() 可以解决我提到的问题。

4

3 回答 3

2

添加通话

revalidate();
repaint();

在容器中添加/删除组件之后

于 2013-01-08T16:36:15.533 回答
1

如果您“对 revalidate() 和 repaint() 之类的命令有点混乱”,那么,如果

pause(500);

与 Thread.sleep() 有什么关系,很可能是问题所在。

它会阻止绘画,然后立即显示下一张卡片。

可以肯定的是,发布一个示例可编译程序,如前所述。

于 2013-01-08T22:52:48.960 回答
0

感谢所有回答的人,为我指明了正确的方向。我最后想通了,这与我对线程和同步性的理解不足有关。如果其他人有类似的问题,我通过将代码的最后一位更改为:

public void actionPerformed(ActionEvent e) {
    if(e.getSource()==button){

         nextTrial();

        SwingUtilities.invokeLater(new Runnable() {
              public void run() {
                  pause(500);
                  cards.show(j,"Card1");

                }
              });
    }
}
于 2013-01-09T01:55:52.583 回答