我需要在 JFrame 中添加进度条,但我想在不生成新线程的情况下更新此栏(例如 SwingWorker 在后台更新栏)。有没有办法更新当前线程(主JFrame的当前线程)中的进度条?
详情
我有第一个类(“ChooseGUI”),它扩展了JFrame并调用了第二个类。第二个类(“ProgressFrame”)是JFrame的另一个扩展:当我在ChooseGUI中按下一个按钮时,ChooseGUI变得不可见,ProgressFrame(显示进度条)变得可见,并调用SwingWorker来更新条形。问题是ChooseGUI继续执行,而我希望ChooseGUI等待ProgressBar的'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;
}
}
进度框架
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(); }}}
ClassEvaluating类是一个更新进度条的SwingWorker。
会发生什么?当我在测试程序中启动ChooseGUI时,会在进度条之前显示JOptionPane消息“Commenti non trovati per ..”。我希望ChooseGUI等待ProgressBar的'DONE'!!!
答案 0 :(得分:2)
你的EDT线程最终会被阻止。 您需要在后台执行任务,然后您将从那里更新进度条。
通过更新进度条我的意思是设置其值。当您这样做时,GUI会自动在EDT线程中更新其视图。
答案 1 :(得分:2)
您应该使用模态对话框来阻止:
编辑:EDT中的进度可视化 - 也可以使用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 );
}
}
}