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' !!!
You should use Modal Dialog for blocking:
EDIT: progress visualization in EDT - that can also be done with your
PropertyChangeEvent
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.