2011-01-09 49 views
28

現在,我的主要只是調用10行gui。根據有多少行具有文本,將調用9個類中的1個(兩行必須包含文本)。被調用的類執行計算,我想要將進度條綁定到。下面是一個被調用的類的例子(每個類都是類似的,但是不同的是需要一個新的類)。我相信這個問題違反了美國東部時間的規則,但是我看到的所有例子都涉及到一個main論據。框架在代碼運行時出現,但進度條在所有計算完成前都不會更新。一個進度條可以在主要的課外使用嗎?

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

public class twoLoan extends JFrame { 

    static JFrame progressFrame; 
    static JProgressBar progressBar; 
    static Container pane; 
    double amountSaved = 0; 
    int i = 0; 

    public void runCalcs(Double MP, Double StepAmt, 
     Double L1, Double L2, Double C1, Double C2, 
     Double IM1, Double IM2, Double M1Start, Double M2Start) { 

     try { 
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
     } catch (Exception e) { 
     } 

     int iterations = (int) (MP - (M1Start * M2Start)); 

     //Create all components 
     progressFrame = new JFrame("Calculation Progress"); 
     progressFrame.setSize(300, 100); 
     pane = progressFrame.getContentPane(); 
     pane.setLayout(null); 
     progressFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     progressBar = new JProgressBar(0, iterations); 

     //Add components to pane 
     pane.add(progressBar); 

     //Position controls (X, Y, width, height) 
     progressBar.setBounds(10, 10, 280, 20); 

     //Make frame visible 
     progressFrame.setResizable(false); //No resize 
     progressFrame.setVisible(true); 

     double M1 = M1Start; 
     double M2 = M2Start; 

     // Set MinLoop as maximum to start 
     // Loan 1 
     double N1 = (Math.log10(1 - IM1 * L1/M1) * -1)/Math.log10(1 + IM1); 
     double M1Sum = M1 * N1; 
     // Loan 2 
     double N2 = (Math.log10(1 - IM2 * L2/M2) * -1)/Math.log10(1 + IM2); 
     double M2Sum = M2 * N2; 
     double minLoop = M1Sum + M2Sum; 
     double MTotal = 0; 


     // Define variables for mins 
     double MP1 = 0; 
     double MP2 = 0; 
     double NP1 = 0; 
     double NP2 = 0; 
     double MP1Sum = 0; 
     double MP2Sum = 0; 

     while (M1 <= MP - M2Start && M2 >= M2Start) { 
      N1 = (Math.log10(1 - IM1 * L1/M1) * -1)/Math.log10(1 + IM1); 
      M1Sum = N1 * M1; 
      N2 = (Math.log10(1 - IM2 * L2/M2) * -1)/Math.log10(1 + IM2); 
      M2Sum = N2 * M2; 
      MTotal = M1Sum + M2Sum; 
      if (MTotal < minLoop) { 
       minLoop = MTotal; 
       MP1 = M1; 
       MP2 = M2; 
       NP1 = N1; 
       NP2 = N2; 
       MP1Sum = M1Sum; 
       MP2Sum = M2Sum; 
      } // end if 
      M1 = M1 + StepAmt; 
      M2 = MP - M1; 
      // Reset monthly sums 
      M1Sum = 0; 
      M2Sum = 0; 
      i++; 
      progressBar.setValue(i); 
      progressBar.repaint(); 
      if (i >= iterations) { 
       progressFrame.dispose(); 
      } 
     } // end while 

     // if there's a value for current payments, calculate amount saved 
     if (C1 > 0) { 
      double CN1 = (Math.log10(1 - IM1 * L1/C1) * -1)/Math.log10(1 + IM1); 
      double CT1 = CN1 * C1; 

      double CN2 = (Math.log10(1 - IM2 * L2/C2) * -1)/Math.log10(1 + IM2); 
      double CT2 = CN2 * C2; 

      double CTotal = CT1 + CT2; 
      amountSaved = CTotal - minLoop; 
     } 

    } // end method runCalcs 

    //Workbook wb = new HSSFWorkbook(); 
    public double savedReturn() { 
     return amountSaved; 
    } 
} // end class twoLoans 

回答

28

SwingWorker對此非常理想。下面的示例在後臺執行簡單的迭代,同時在窗口中報告進度和中間結果。您可以在合適的構造函數中傳遞所需的任何參數。

import java.awt.EventQueue; 
import java.awt.GridLayout; 
import java.beans.PropertyChangeEvent; 
import java.beans.PropertyChangeListener; 
import java.text.DecimalFormat; 
import java.util.List; 
import javax.swing.*; 

/** @see http://stackoverflow.com/questions/4637215 */ 
public class TwoRoot extends JFrame { 

    private static final String s = "0.000000000000000"; 
    private JProgressBar progressBar = new JProgressBar(0, 100); 
    private JLabel label = new JLabel(s, JLabel.CENTER); 

    public TwoRoot() { 
     this.setLayout(new GridLayout(0, 1)); 
     this.setTitle("√2"); 
     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     this.add(progressBar); 
     this.add(label); 
     this.setSize(161, 100); 
     this.setLocationRelativeTo(null); 
     this.setVisible(true); 
    } 

    public void runCalc() { 
     progressBar.setIndeterminate(true); 
     TwoWorker task = new TwoWorker(); 
     task.addPropertyChangeListener(new PropertyChangeListener() { 

      @Override 
      public void propertyChange(PropertyChangeEvent e) { 
       if ("progress".equals(e.getPropertyName())) { 
        progressBar.setIndeterminate(false); 
        progressBar.setValue((Integer) e.getNewValue()); 
       } 
      } 
     }); 
     task.execute(); 
    } 

    private class TwoWorker extends SwingWorker<Double, Double> { 

     private static final int N = 5; 
     private final DecimalFormat df = new DecimalFormat(s); 
     double x = 1; 

     @Override 
     protected Double doInBackground() throws Exception { 
      for (int i = 1; i <= N; i++) { 
       x = x - (((x * x - 2)/(2 * x))); 
       setProgress(i * (100/N)); 
       publish(Double.valueOf(x)); 
       Thread.sleep(1000); // simulate latency 
      } 
      return Double.valueOf(x); 
     } 

     @Override 
     protected void process(List<Double> chunks) { 
      for (double d : chunks) { 
       label.setText(df.format(d)); 
      } 
     } 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       TwoRoot t = new TwoRoot(); 
       t.runCalc(); 
      } 
     }); 
    } 
} 
+0

順便說一下,`main()`只是一個將`Runnable`傳遞給事件派發線程的方法。然後`Runnable`構造GUI並在`TwoWorker`的一個實例上調用`execute()`。 – trashgod 2011-01-09 19:49:16

4

我覺得你的預感是對的,你需要堅持Swing線程規則。

那該怎麼辦?

首先,我不確定您的應用程序是如何精確設計的。你說你有一大堆行的主框架,並且可能每個都可能調用9個類中的一個,並且它們都看起來像上面那個。看起來這些課程將自己生成JFrame。我想這個新框架僅用於進度條。我會認爲這是設計,並會相應提出建議。

我建議您在Runnable的實例中執行一些操作,然後將這些Runnable實例放入SwingUtilities.invokeLater以使它們在EDT上運行。與此同時,如果閱讀,我會花時間重新組織您的代碼。

  1. 此舉創造你的GUI位到一個方法:
public void createComponents() { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      //Create all components 
      progressFrame = new JFrame("Calculation Progress"); 
      progressFrame.setSize(300, 100); 
      pane = progressFrame.getContentPane(); 
      pane.setLayout(null); 
      progressFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      progressBar = new JProgressBar(0, iterations); 
      //Add components to pane 
      pane.add(progressBar); 

      //Position controls (X, Y, width, height) 
      progressBar.setBounds(10, 10, 280, 20); 

      //Make frame visible 
      progressFrame.setResizable(false); //No resize 
      progressFrame.setVisible(true); 
     } 
     }); 

    } 
  1. 那我就methodize,你有你的鈣兩個GUI操作:
 
    private void updateProgressBar(final int i) { 
      SwingUtilities.invokeLater(new Runnable() { 
       public void run() { 
        progressBar.setValue(i); 
        //no need for the following 
        //progressBar.repaint(); 

       } 
      }); 
    } 

    private void killDialog() { 
      SwingUtilities.invokeLater(new Runnable() { 
       public void run() { 
        progressFrame.setVisible(false); 
       } 
      }); 
    } 
  1. 最後,替換c包含在這些新方法中的調用方法。
+0

非常感謝你的幫助,我一直停留在這一段時間。我一直在努力,但我無法弄清楚如何實時調用新方法。使用我的更新代碼創建GUI,並在執行計算後更新進度欄。你介意幫我調用這些方法嗎?我所擁有的一切稱爲類似 「runCalcs」 的範圍內: SwingUtilities.invokeLater(Runnable的新(){ 公共無效的run(){ 的createComponents(重複);} }); – user568422 2011-01-09 21:33:54

3

感謝您的幫助。我開始嘗試使用第一個響應,但我無法同時運行它,並在程序結束時運行。我確信它會起作用,但我無法弄清楚。使用trashgod的回覆和其他一些例子,我能夠使用SwingWorker來使它工作。不幸的是,我並不完全理解它是如何工作的,但我現在就採用它。

GUI和方法來運行計算被稱爲在另一個類第一:

iterations = (int) (MPay - (M1Start + M2Start)); 
     twoLoan myLoan = new twoLoan(); 
     myLoan.createGui(iterations); 
     myLoan.runCalcs(MPay, Step, L1, L2, C1, C2, IM1, IM2, M1Start, M2Start); 

然後運行如下:

public class twoLoan extends JFrame { 

    JFrame progressFrame; 
    JProgressBar progressBar; 
    JLabel label = new JLabel("Calculating...");; 
    Container pane; 

    double amountSaved = 0; 
    int i = 0; 
    int iterations; 

    public void createGui(int iterations) { 
      //Create all components 
      progressFrame = new JFrame("Calculation Progress"); 
      progressFrame.setSize(300, 100); 
      pane = progressFrame.getContentPane(); 
      pane.setLayout(null); 
      label = new JLabel("Calculating..."); 
      label.setBounds(115, 35, 200, 25); 
      progressBar = new JProgressBar(0, iterations); 
      progressBar.setBounds(10, 10, 280, 20); 
      progressBar.setStringPainted(true); 
      //Add components to pane 
      pane.add(progressBar); 
      pane.add(label); 
      //Make frame visible 
      progressFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      progressFrame.setResizable(false); //No resize 
      progressFrame.setLocationRelativeTo(null); 
      progressFrame.setVisible(true); 
    } 

    public void runCalcs (double MP, double StepAmt, double L1, double L2, 
      double C1, double C2, double IM1, double IM2, double M1Start, double M2Start) { 

     progressBar.setIndeterminate(false); 
     TwoWorker task = new TwoWorker(MP, StepAmt, L1, L2, C1, C2, IM1, IM2, M1Start, M2Start); 
     task.addPropertyChangeListener(new PropertyChangeListener() { 

      @Override 
      public void propertyChange(PropertyChangeEvent e) { 
       if ("progress".equals(e.getPropertyName())) { 
        progressBar.setIndeterminate(false); 
        progressBar.setValue((Integer) e.getNewValue()); 
       } 
      } 
     }); 
     task.execute(); 
    } //end method runCalcs 

    public class TwoWorker extends SwingWorker<Double, Double> { 

     private final double MP, StepAmt,L1, L2, 
      C1, C2, IM1, IM2, M1Start, M2Start; 

     public TwoWorker(double MPa, double StepAmta, double L1a, double L2a, 
      double C1a, double C2a, double IM1a, double IM2a, double M1Starta, double M2Starta) { 

      MP = MPa; 
      StepAmt = StepAmta; 
      L1 = L1a; 
      L2 = L2a; 
      C1 = C1a; 
      C2 = C2a; 
      IM1 = IM1a; 
      IM2 = IM2a; 
      M1Start = M1Starta; 
      M2Start = M2Starta; 
      } 
     @Override 
     protected Double doInBackground() { 

      double M1 = M1Start; 
      double M2 = M2Start; 

     // Set MinLoop as maximum to start 
     // Loan 1 
     double N1 = (Math.log10(1 - IM1 * L1/M1) * -1)/Math.log10(1 + IM1); 
    double M1Sum = M1 * N1; 
    // Loan 2 
    double N2 = (Math.log10(1 - IM2 * L2/M2) * -1)/Math.log10(1 + IM2); 
    double M2Sum = M2 * N2; 
    double minLoop = M1Sum + M2Sum; 
    double MTotal = 0; 

     // Define variables for mins 
    double MP1 = 0; 
    double MP2 = 0; 
    double NP1 = 0; 
    double NP2 = 0; 
    double MP1Sum = 0; 
    double MP2Sum = 0; 

     while (M1 <= MP - M2Start && M2 >= M2Start) { 
      N1 = (Math.log10(1 - IM1 * L1/M1) * -1)/Math.log10(1 + IM1); 
      M1Sum = N1 * M1; 
      N2 = (Math.log10(1 - IM2 * L2/M2) * -1)/Math.log10(1 + IM2); 
      M2Sum = N2 * M2; 
      MTotal = M1Sum + M2Sum; 
      if (MTotal < minLoop) { 
       minLoop = MTotal; 
       MP1 = M1; 
       MP2 = M2; 
       NP1 = N1; 
       NP2 = N2; 
       MP1Sum = M1Sum; 
       MP2Sum = M2Sum; 
      } // end if 
         i++; 
         progressBar.setValue(i); 
        M1 = M1 + StepAmt; 
      M2 = MP - M1; 
      // Reset monthly sums 
      M1Sum = 0; 
      M2Sum = 0; 
     } // end while 

     System.out.printf("MP1 = %.2f\n", MP1); 
     System.out.printf("MP2 = %.2f\n", MP2); 
     System.out.printf("NP1 = %.2f\n", NP1); 
     System.out.printf("NP2 = %.2f\n", NP2); 
     System.out.printf("MP1Sum = %.2f\n", MP1Sum); 
     System.out.printf("MP2Sum = %.2f\n", MP2Sum); 
       System.out.printf("MTotal = %.2f\n", minLoop); 
       System.out.printf("i = %d\n",i); 
       System.out.printf("M1Start = %.2f\n", M1Start); 
     System.out.printf("M2Start = %.2f\n", M2Start); 
       System.out.printf("MP= %.2f\n",MP); 

    // if there's a value for current payments, calculate amount saved 
    if(C1 > 0) { 
     double CN1 = (Math.log10(1 - IM1 * L1/C1) * -1)/Math.log10(1 + IM1); 
     double CT1 = CN1 * C1; 

     double CN2 = (Math.log10(1 - IM2 * L2/C2) * -1)/Math.log10(1 + IM2); 
     double CT2 = CN2 * C2; 

     double CTotal = CT1 + CT2; 
     amountSaved = CTotal - minLoop; 
     } // end if 

     return null; 

    } // end doInBackGround 

     @Override 
     protected void done() { 
      label.setBounds(133, 35, 200, 25); 
      label.setText("Done!"); 
     } 
    } // end TwoWorker 


    public double savedReturn() { 
     return amountSaved; 
    } 

} // end class twoLoans 
相關問題