从 ActionListener 调用时不显示 JProgressbar
JProgressbar doesn't display when invoked from an ActionListener
我有一个通用的 Java class 作为简单的进度指示器。如果直接调用(例如从 main() 或 class 构造函数),它工作正常。但是当我创建一个简单的菜单并从与菜单项关联的 ActionListener 调用它时,我无法让它工作。
这是通用进度指示器 class:
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之后排队调用的,所以你看不到进度条更新。
以下是我如何修改您的 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();
}
我有一个通用的 Java class 作为简单的进度指示器。如果直接调用(例如从 main() 或 class 构造函数),它工作正常。但是当我创建一个简单的菜单并从与菜单项关联的 ActionListener 调用它时,我无法让它工作。
这是通用进度指示器 class:
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之后排队调用的,所以你看不到进度条更新。
以下是我如何修改您的 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();
}