简体   繁体   English

从 ActionListener 调用时,JProgressbar 不显示

[英]JProgressbar doesn't display when invoked from an ActionListener

I have a generic Java class for a simple progress indicator.我有一个通用的 Java class 用于简单的进度指示器。 It works fine if invoked directly (eg from main() or from a class constructor).如果直接调用(例如从 main() 或从 class 构造函数),它工作正常。 But I can't get it to work when I create a simple menu and invoke it from an ActionListener associated with a menu item.但是当我创建一个简单的菜单并从与菜单项关联的 ActionListener 调用它时,我无法让它工作。

Here's the generic progress indicator class:这是通用进度指示器 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(); 
    }
}

The test program from which I'm invoking this is:我从中调用它的测试程序是:

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();      
    }
}

The test method Process loops and updates the progress bar.测试方法 Process 循环并更新进度条。 I have commented out an invocation that, if uncommented, shows that all the code is working.我已经注释掉了一个调用,如果未注释,则表明所有代码都在工作。 But if I invoke it from the menu item, the frame appears but not the progress bar.但是,如果我从菜单项调用它,则会出现框架,但不会出现进度条。

Anyone know what I'm doing wrong?有人知道我在做什么错吗?

actionPerformed is actually executed by EDT, so all invokeLater calls are queued and called after the pi.Close so that you can't see the progressbar update. actionPerformed 实际上是由 EDT 执行的,所以所有的 invokeLater 调用都会排队并在 pi.Close 之后调用,这样就看不到进度条更新了。

Here is how I modified your Process method to "take the counter out of EDT":以下是我如何修改您的 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();

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM