2013-02-18 83 views
-1

我需要在的JFrame添加一個進度條,但我想不會產生一個新的線程(例如SwingWorker的的背景下,更新吧)更新此欄。有沒有辦法更新當前線程(主JFrame的當前線程)進度條?建立一個進度條,而無需啓動一個新的線程

在細節

我有一流的( 「ChooseGUI」)延伸的JFrame和調用第二類。第二類(「ProgressFrame」)是JFrame的另一個擴展:當我在ChooseGUI中按下按鈕時,ChooseGUI變得不可見,ProgressFrame(顯示進度條)變得可見,並調用SwingWorker來更新欄。問題是,ChooseGUI繼續執行,而我想的是ChooseGUI等待進度條的 '完成'

類ChooseGUI(一張)

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的'完成'!

+4

*」 ..但我要更新這個酒吧而不會生成新的線程。「*爲什麼? – 2013-02-18 12:46:09

+1

當然,您可以在主線程中更新進度條,但這可能會阻止您的用戶界面。 – 2013-02-18 12:48:10

+0

並在哪個線程ChooseGUI運行?在主線程中?我認爲如果你發佈一些代碼可能會更好。 – 2013-02-18 13:02:35

回答

2

您將最終阻止您的EDT主題。 你需要在後臺完成你的任務,並且你會從那裏更新你的進度條。

通過更新您的進度條我的意思是,設置它的值。當你這樣做時,GUI會自動在EDT Thread中更新它的視圖。

2

您應該使用模態對話框阻止:

編輯:在美國東部時間進度可視化 - 這也可以做你的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); 
     } 

    } 

} 
+0

我知道'WinOS上金屬或Nimbus L&F的作品,請將'progress.setValue(current + 1);'包裹在'invokeLater'中 – mKorbel 2013-02-18 13:26:17

+0

當然是: ) – oliholz 2013-02-18 13:34:15

+1

這是不是創建第二個線程?使用javax.swing.Timer不是更好嗎? – MadProgrammer 2013-02-18 19:09:03

相關問題