如何解决从 ActionListener 调用时 JProgressbar 不显示
我有一个用于简单进度指示器的通用 Java 类。如果直接调用(例如从 main() 或从类构造函数),它可以正常工作。但是当我创建一个简单的菜单并从与菜单项关联的 ActionListener 调用它时,我无法让它工作。
这是通用的进度指示器类:
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JProgressBar;
import javax.swing.JTextField;
public class jpcProgressIndicator {
final int MAX = 100;
private JFrame frame = new JFrame("Progress Indicator");
// creates progress bar
final JProgressBar pb = new JProgressBar();
final JTextField tf = new JTextField();
public jpcProgressIndicator() {
pb.setMinimum(0);
pb.setMaximum(MAX);
pb.setStringPainted(true);
// add progress bar
frame.setLayout(new FlowLayout());
frame.getContentPane().add(pb);
// frame.getContentPane().add(tf);
frame.setDefaultCloSEOperation(JFrame.DO_nothing_ON_CLOSE);
frame.setSize(300,70);
frame.setLocationRelativeto(null);
}
public void Update( int nValue) {
pb.setValue(nValue);
}
public void Show( boolean flag) {
if(flag == true) {
this.frame.setVisible(true);
this.pb.setVisible(true);
} else {
this.pb.setVisible(false);
}
}
public int getValue() {
return this.pb.getValue();
}
public void setTitle(String strTitle) {
this.frame.setTitle(strTitle);
}
public void Close() {
frame.dispose();
}
}
我从中调用它的测试程序是:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import SurveySystem.Data.jpcProgressIndicator;
public class Main2 implements ActionListener {
final int MAX = 100;
jpcProgressIndicator pi;
JFrame frame;
JMenuBar mb;
JMenuItem myMenuItem;
Main2() {
// Process();
// create the basic frame window for a menu
frame=new JFrame("Survey System");
// Create a menu item
myMenuItem = new JMenuItem("Process");
// add an actionlistener for this menu item
myMenuItem.addActionListener(this);
// create a menu bar
mb=new JMenuBar();
// add menu item to menu bar
mb.add(myMenuItem);
// add the menu bar to the frame
frame.add(mb);
frame.setJMenuBar(mb);
// set frame size
frame.setSize(800,400);
// center the frame on the screen
frame.setLocationRelativeto(null);
// make the frame visible
frame.setVisible(true);
}
public static void main(String[] args) {
new Main2();
}
private void Process() {
pi = new jpcProgressIndicator();
pi.setTitle("Progress of Growth & Persistency");
pi.Update(0); // initialize
pi.Show(true);
int nCounter = 0;
// for (int i = 0; i <= MAX; i++) {
while (nCounter < 100 ) {
// final int currentValue = i;
final int currentValue = nCounter;
try {
SwingUtilities.invokelater(new Runnable() {
public void run() {
pi.Update(currentValue);
}
});
java.lang.Thread.sleep(100);
} catch (InterruptedException e) {
System.out.println("Error: " + e.getMessage());
}
nCounter++;
}
pi.Close();
}
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == myMenuItem)
Process();
}
}
测试方法 Process 循环并更新进度条。我已经注释掉了一个调用,如果取消注释,则表明所有代码都在工作。但是如果我从菜单项中调用它,会出现框架而不是进度条。
有人知道我做错了什么吗?
解决方法
actionPerformed实际上是由EDT执行的,所以所有的invokeLater调用都是排队,在pi.Close之后调用,这样就看不到progressbar更新了。
这是我修改您的 Process 方法以“从 EDT 中取出计数器”的方法:
private void Process() {
jpcProgressIndicator pi = new jpcProgressIndicator();
pi.setTitle("Progress of Growth & Persistency");
pi.Update(0); // initialize
pi.Show(true);
Thread t = new Thread(new Runnable(){
public void run() {
int nCounter = 0;
// for (int i = 0; i <= MAX; i++) {
while (nCounter < 100 ) {
// final int currentValue = i;
final int currentValue = nCounter;
try {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
pi.Update(currentValue);
}
});
java.lang.Thread.sleep(100);
} catch (InterruptedException e) {
System.out.println("Error: " + e.getMessage());
}
nCounter++;
}
pi.Close();
}
});
t.start();
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。