Build a progress bar without launching a new Threa

2019-03-06 17:10发布

I need to add a progress bar in a JFrame but I want to update this bar without generating a new Thread (for example SwingWorker that update bar in background). Is there a way to update progress bar in current thread (the current thread of the main JFrame)?

In details

I have first class ("ChooseGUI") that extends JFrame and that calls second class. This second class ("ProgressFrame") is another extension of JFrame: when I press a button in ChooseGUI, ChooseGUI becomes not visible, ProgressFrame (that show a progress bar) becomes visible and calls a SwingWorker to update bar. The problem is that ChooseGUI continue its execution, while I want that ChooseGUI waits for ProgressBar's 'DONE'

Class ChooseGUI (a piece)

  public class ChooseGUI extends JFrame{
            public ChooseGUI(IJavaProject project){
            super(project.getElementName());

            this.project = project;
            this.classi = new HashMap<ICompilationUnit,Boolean>();


            inizializeMap();




    JPanel p = createPanel();

                    if(p != null){

                        JScrollPane pane = new JScrollPane(p);
                        pane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);// disabilito la scrollbar orizzontale
                        pane.setSize(1000, 5000);
                    add(pane);

                    setLocationRelativeTo(null);
                    setResizable(true);
                    setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                    pack();
                    setVisible(true); 

                    }
                    else{


setVisible(false);
                    JOptionPane.showMessageDialog(null, "Classi not found!");
                }
    }


    private void inizializeMap(){
        ArrayList<ICompilationUnit> className = getClassNames();
        for(ICompilationUnit a : className){
            classi.put(a,false);
        }
    }



    private JPanel createPanel(){
        JPanel result = new JPanel(new GridLayout(0, 1));

        ArrayList<ICompilationUnit> className = getClassNames();


        int size = className.size();
        if(size > 0){       

            Collections.sort(className, new Comparator<ICompilationUnit>(){

                @Override
                public int compare(ICompilationUnit o1, ICompilationUnit o2) {
                     return o1.getElementName().compareTo(o2.getElementName());
                     }});

        for(int i = 0; i < size ; ++i){
            String name = className.get(i).getElementName();
            JCheckBox box = new JCheckBox(name);
            box.setActionCommand(name);

            box.addItemListener(this);
            result.add(box);

        }

        JButton confirm = new JButton(new ImageIcon(pathIconChoose));
        confirm.setSize(500, 1000);
        result.add(confirm);

        confirm.addActionListener(new ActionListener(){


            @SuppressWarnings("deprecation")
            @Override
            public void actionPerformed(ActionEvent arg0) {

                setVisible(false);


                int size = classi.size();

                if(size > 0){

                        BuildDB a = null;
                        try {
                            a = new BuildDB();
                        } catch (ClassNotFoundException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }

                    Set<ICompilationUnit> keySet2 = classi.keySet();
                    ArrayList<ICompilationUnit> units = new ArrayList<ICompilationUnit>();
                    for(ICompilationUnit unit: keySet2){
                        if(classi.get(unit) == true){
                                        units.add(unit);
                        }}



                            QueryAndManipulateDB t = new QueryAndManipulateDB(a);


                            ProgressFrame guiFrame = new ProgressFrame(units,t);


                           guiFrame.generateGUIAndUpdateDB();




                            //// quering
                            for(ICompilationUnit unit : units){         
                            ArrayList<Coppia> lista = new ArrayList<Coppia>();


                             ASTParser parser = ASTParser.newParser(AST.JLS3);
                             parser.setSource(unit);
                             CompilationUnit astRoot = (CompilationUnit) parser.createAST(null);
                             astRoot.recordModifications();
                             TypeDeclaration typeDeclaration = (TypeDeclaration)astRoot.types().get(0);


                             int length = typeDeclaration.getMethods().length;
                             if(length > 0){
                             for(int j = 0; j < length; ++j){
                             MethodDeclaration methodDecl = typeDeclaration.getMethods()[j];





                             Coppia c = t.getComment(unit.getElementName(), getSignature(methodDecl));

                             if(c.getCommenti().size() > 0){
                             lista.add(c);}
                             }


                             if(lista.size() > 0){
                             CommentoFrame f = new CommentoFrame(("Select Comment for " + unit.getElementName()),lista, unit);
                             f.setResizable(true);
                             f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                                f.pack();
                                f.setVisible(true);
                             }

                             else{
                                 JOptionPane.showMessageDialog(null, "Commenti non trovati per " + unit.getElementName());
                             }


                                dispose();
                             }



                }


                      a.closeConnection();//}
            }


            }


        });

        return result;}
        else
        {
            return null;
        }
    }

Progress Frame

public class ProgressFrame extends JFrame{

/**
 * 
 */
private static final long serialVersionUID = 1L;
private ArrayList<ICompilationUnit> units;
private QueryAndManipulateDB q;



public ProgressFrame(ArrayList<ICompilationUnit> units, QueryAndManipulateDB q){
    setLayout(new GridLayout(0,1));
    this.units = units;
    this.q = q;
}

public void generateGUIAndUpdateDB(){

    ArrayList<JPanel> panels = new ArrayList<JPanel>();
    for(int i = 0; i < units.size(); ++i){
        final String simpleClassName = units.get(i).getElementName();
        String fullClassName = units.get(i).getParent().getElementName() + "." + simpleClassName.substring(0, simpleClassName.length() - 5);


        JPanel pan = new JPanel();
        pan.setName(fullClassName);


        Introspection intro = new Introspection(fullClassName);
        //create progress bar        
        int size = intro.getMethodSignatures().size();
        JProgressBar progressBar = new JProgressBar(0,size);
        progressBar.setValue(0);

        JLabel label = new JLabel("Search for class " +  simpleClassName.substring(0, simpleClassName.length() - 5));
        label.setName(simpleClassName);

        pan.setLayout(new BorderLayout());
        pan.add(label, BorderLayout.NORTH);
        pan.add(progressBar, BorderLayout.CENTER);

        panels.add(pan);
        add(pan);



        final ClassEvaluating ce = new ClassEvaluating(pan);

        ce.addPropertyChangeListener(new PropertyChangeListener(){

            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                 if (evt.getPropertyName().equals("state") && evt.getNewValue().equals(SwingWorker.StateValue.DONE)) {


                    HashMap<String, ParagraphsList> paragraphsForMethods = ce.getResult();


                    for(String metodo : paragraphsForMethods.keySet()){
                        ParagraphsList par = paragraphsForMethods.get(metodo);
                        ArrayList<Comment> commenti = new ArrayList<Comment>();

                        List<Paragraph> list = par.getRankList();
                        for(Paragraph p: list){
                        double score = p.getScore();
                        if(score > 0)
                        commenti.add(new Comment(p.getText(),score));
                        }

                        Association ass = new Association(simpleClassName,metodo,commenti);
                        q.updateDB(ass);
                    }

                            }


            }

        });

        ce.execute(); }}}

The class ClassEvaluating is a SwingWorker that update progressbar.

What happens? When I launch ChooseGUI in a Tester, JOptionPane message "Commenti non trovati per.." is dispayed before progressbar. I want that ChooseGUI waits for ProgressBar's 'DONE' !!!

2条回答
做个烂人
2楼-- · 2019-03-06 17:49

You should use Modal Dialog for blocking:

EDIT: progress visualization in EDT - that can also be done with your PropertyChangeEvent

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class Test {

    public Test() {
        createAndShowGUI();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Test();
            }
        });
    }

    private void createAndShowGUI() {
        JFrame frame = new JFrame();
        frame.setSize( 500, 500 );
        frame.setLocationRelativeTo( null );
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout( new BorderLayout() );
        frame.getContentPane().add(new JButton( openChooseGUI() ), BorderLayout.SOUTH);      
        frame.setVisible(true);
    }

    private Action openChooseGUI() {
        return new AbstractAction("ChooseGUI") {
            @Override
            public void actionPerformed( ActionEvent e ) {
                new ChooseGUI().setVisible( true );
            }
        };
    }

    public class ChooseGUI extends JFrame {

        public ChooseGUI() {
            setSize( 200, 200 );
            setLocationRelativeTo( null );
            setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
            getContentPane().setLayout( new BorderLayout() );
            getContentPane().add( new JLabel( "This is ChooseGUI" ), BorderLayout.CENTER );
            init();
        }

        private void init() {
            final JDialog progressDialog = new JDialog( this, true );
            final JProgressBar progress = new JProgressBar( JProgressBar.HORIZONTAL );
            progress.addChangeListener( new ChangeListener() {
                @Override
                public void stateChanged( ChangeEvent e ) {
                    // TODO Auto-generated method stub
                    int current = ((JProgressBar)e.getSource()).getValue();
                    if(current >= 100) {
                        progressDialog.dispose();
                    }
                }
            } );

            progressDialog.setSize( 400, 100 );
            progressDialog.setLocationRelativeTo( this );
            progressDialog.getContentPane().setLayout( new BorderLayout() );
            progressDialog.getContentPane().add( progress, BorderLayout.NORTH );
            progressDialog.getContentPane().add(  new JLabel( "This is Progress Dialog" ), BorderLayout.CENTER );
            progressDialog.getContentPane().add(  new JButton(new AbstractAction("click to progress") {
                @Override
                public void actionPerformed( ActionEvent e ) {
                    progress.setValue( progress.getValue()+25 );
                }
            }), BorderLayout.SOUTH );
            progressDialog.setVisible( true );
        }

    }

}
查看更多
何必那么认真
3楼-- · 2019-03-06 18:12

You will end up with your EDT Thread blocked. You need to do your task in background, and you will update your progress bar from there.

By updating your progress bar I mean, setting its value. When you do that the GUI updates its view in EDT Thread automatically.

查看更多
登录 后发表回答