JPanel 直到代码之后才显示
JPanel does not show until after the code
我想要做的是在进程进行时显示一个带有进度条的新面板。
我的代码如下:
case "GoButton":
cards.show(this, "pp");
this.test();
cards.show(this, "panel1");
break;
那是在一个actionPerformed
方法中
但是当我 运行 程序时它只是忽略第一个 cards.show
,它执行 test
代码然后执行第二个 cards.show
我还为您提供了其余的代码,以备不时之需
public CreatePanel(JFrame frame) {
ext = new ArrayList<>();
files = new ArrayList<>();
this.mainWindow = frame;
this.setSize(256, 256);
cards = new CardLayout();
this.setLayout(cards);
panel1 = new JPanel(null);
createPanel1(panel1);
this.add(panel1, "panel1");
panel2 = new JPanel(null);
createPanel2(panel2);
this.add(panel2, "panel2");
panel3 = new JPanel(null);
createPanel3(panel3);
this.add(panel3, "pp");
cards.show(this, "panel1");
}
public class ProgressPanel {
private static JPanel panel;
private static JProgressBar progressBar;
private static int progress;
public static JPanel createProgressPanel(){
ProgressPanel.panel = new JPanel(null);
ProgressPanel.initPanel();
return ProgressPanel.panel;
}
private static void initPanel(){
panel.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
progressBar = new JProgressBar(0, 100);
progressBar.setValue(progress);
progressBar.setStringPainted(true);
panel.add(progressBar, c);
}
public static void updateProgress(int x){
ProgressPanel.progress += x;
}
public void resetProgress(){
this.progress = 0;
}
}
您的问题可能在这里:this.test();
。我敢打赌,此方法会调用长 运行 代码,并且由于它是在 Swing 事件线程上调用的,因此它会占用此线程,从而阻止您的 GUI 自行更新并实际上完全冻结 GUI。解决方案:对 long-运行 任务使用 SwingWorker 或其他后台线程。请看一下 Concurrency in Swing.
请注意,如果您确实使用了 SwingWorker,则需要使用 PropertyChangeListener 或 done()
方法,以便在后台线程完成时收到通知,并且是时候调用 cards.show(this, "panel1");
.我自己,我会向我的 SwingWorker 添加一个 PropertyChangeListener,因为这样,我既可以监听监听器的完成,也可以监听 worker 进度的变化 属性,然后使用该值来设置我的 JProgressBar 的值。
我想要做的是在进程进行时显示一个带有进度条的新面板。
我的代码如下:
case "GoButton":
cards.show(this, "pp");
this.test();
cards.show(this, "panel1");
break;
那是在一个actionPerformed
方法中
但是当我 运行 程序时它只是忽略第一个 cards.show
,它执行 test
代码然后执行第二个 cards.show
我还为您提供了其余的代码,以备不时之需
public CreatePanel(JFrame frame) {
ext = new ArrayList<>();
files = new ArrayList<>();
this.mainWindow = frame;
this.setSize(256, 256);
cards = new CardLayout();
this.setLayout(cards);
panel1 = new JPanel(null);
createPanel1(panel1);
this.add(panel1, "panel1");
panel2 = new JPanel(null);
createPanel2(panel2);
this.add(panel2, "panel2");
panel3 = new JPanel(null);
createPanel3(panel3);
this.add(panel3, "pp");
cards.show(this, "panel1");
}
public class ProgressPanel {
private static JPanel panel;
private static JProgressBar progressBar;
private static int progress;
public static JPanel createProgressPanel(){
ProgressPanel.panel = new JPanel(null);
ProgressPanel.initPanel();
return ProgressPanel.panel;
}
private static void initPanel(){
panel.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
progressBar = new JProgressBar(0, 100);
progressBar.setValue(progress);
progressBar.setStringPainted(true);
panel.add(progressBar, c);
}
public static void updateProgress(int x){
ProgressPanel.progress += x;
}
public void resetProgress(){
this.progress = 0;
}
}
您的问题可能在这里:this.test();
。我敢打赌,此方法会调用长 运行 代码,并且由于它是在 Swing 事件线程上调用的,因此它会占用此线程,从而阻止您的 GUI 自行更新并实际上完全冻结 GUI。解决方案:对 long-运行 任务使用 SwingWorker 或其他后台线程。请看一下 Concurrency in Swing.
请注意,如果您确实使用了 SwingWorker,则需要使用 PropertyChangeListener 或 done()
方法,以便在后台线程完成时收到通知,并且是时候调用 cards.show(this, "panel1");
.我自己,我会向我的 SwingWorker 添加一个 PropertyChangeListener,因为这样,我既可以监听监听器的完成,也可以监听 worker 进度的变化 属性,然后使用该值来设置我的 JProgressBar 的值。