我的代码使用卡片布局向用户显示(预定义)带有JButton的JPanels,然后在继续下一个预定义的JPanel之前显示动态生成的JPanel,其中包含对其响应的反馈。但是,我无法显示动态生成的JPanels,并且使用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()可以解决我提到的问题。
答案 0 :(得分:2)
添加通话
revalidate();
repaint();
在容器中添加/删除组件后
答案 1 :(得分:1)
如果你“使用revalidate()和repaint()等命令搞砸了”,那么,如果这个
pause(500);
与Thread.sleep()有关,可能是问题所在。
它会阻止绘画,然后立即显示下一张卡片。
可以肯定的是,发布一个可编译的示例程序,如前所述。
答案 2 :(得分:0)
感谢所有回答的人,指出我正确的方向。我最终想通了,这与我对线程和同步性的不了解有关。如果其他人有类似的问题,我通过更改我的代码的最后一位来解决这个问题:
public void actionPerformed(ActionEvent e) {
if(e.getSource()==button){
nextTrial();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
pause(500);
cards.show(j,"Card1");
}
});
}
}