2011-01-09 17 views
28

Ngay bây giờ, chính của tôi chỉ gọi một gui với 10 hàng. Dựa trên số lượng các hàng có văn bản, 1 trong số 9 lớp được gọi (hai hàng phải có văn bản). Lớp được gọi thực hiện các phép tính mà tôi muốn có thanh tiến trình gắn với. Đây là một ví dụ về một trong các lớp được gọi (mỗi lớp là tương tự nhau, nhưng đủ khác nhau để đảm bảo một lớp mới.) Tôi tin rằng vấn đề là vi phạm các quy tắc EDT, nhưng tất cả các ví dụ tôi đã thấy trên chúng liên quan đến một chính tranh luận. Khung xuất hiện khi mã được chạy, nhưng thanh tiến trình không cập nhật cho đến khi tất cả các tính toán được hoàn thành.Thanh tiến trình có thể được sử dụng trong lớp ngoài chính không?

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 

Trả lời

28

SwingWorker lý tưởng cho việc này. Ví dụ dưới đây thực hiện một phép lặp đơn giản trong nền, trong khi báo cáo tiến độ và kết quả trung gian trong một cửa sổ. Bạn có thể chuyển bất kỳ thông số nào bạn cần trong một hàm tạo phù hợp 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

BTW, 'main()' chỉ là một phương thức để gửi một 'Runnable' đến chuỗi gửi sự kiện. 'Runnable' đó sẽ xây dựng GUI và gọi' execute() 'trên một thể hiện của' TwoWorker'. – trashgod

+0

Làm cách nào để chạy điều này nếu trong actionPerformed? Liệu một invokeLater vẫn cần thiết hay tôi có thể khởi tạo SwingWorker và thực hiện nó trực tiếp? –

+0

Cách thứ hai, như được hiển thị ở đây (https://sites.google.com/site/drjohnbmatthews/randomdata). – trashgod

4

Tôi nghĩ rằng bạn có linh cảm đúng, bạn cần phải tuân thủ các quy tắc luồng xoay.

Vậy phải làm gì?

Trước tiên, tôi không chắc chắn cách ứng dụng của bạn được thiết kế chính xác. Bạn nói rằng bạn có một khung chính với một loạt các hàng, và tiềm năng mỗi có khả năng có thể gọi một trong 9 lớp học, và tất cả họ trông giống như một ở trên. Dường như các lớp này sẽ tự tạo ra JFrame của riêng chúng. Tôi đoán rằng khung mới này chỉ được sử dụng cho thanh tiến trình. Tôi sẽ giả định rằng đây là thiết kế và sẽ đề xuất cho phù hợp.

Tôi khuyên bạn nên thực hiện một vài hành động trong các trường hợp Runnable và bạn thả các trường hợp Runnable đó vào SwingUtilities.invokeLater để chúng chạy trên EDT. Đồng thời, tôi sẽ dành thời gian để tổ chức lại mã của bạn một cách dễ dàng nếu đọc.

  1. di chuyển tạo ra các giao diện đồ họa bit của bạn thành một phương pháp:
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. Sau đó, tôi sẽ làm việc theo phương pháp hai hành động GUI mà bạn có trong calc của bạn:
 
    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. Cuối cùng, thay thế vị trí của c ode chứa trong các phương thức mới này với các cuộc gọi đến các phương thức.
+0

Cảm ơn rất nhiều sự giúp đỡ của bạn, tôi đã bị mắc kẹt trên cái này một lúc.Tôi đã làm việc trên nó, nhưng tôi không thể tìm ra cách để gọi các phương pháp mới trong thời gian thực. Với mã được cập nhật của tôi, GUI được tạo và thanh tiến trình được cập nhật sau khi tính toán được thực hiện. Bạn có phiền khi giúp tôi với các phương pháp không? Tôi đã tất cả mọi thứ được gọi là tương tự như trong "runCalcs" như sau: SwingUtilities.invokeLater (new Runnable() { public void run() { createComponents (lặp lại); } }); – user568422

3

Cảm ơn sự trợ giúp. Tôi bắt đầu với cố gắng sử dụng phản ứng đầu tiên, nhưng tôi không thể có được thanh để chạy đồng thời, và nó chạy khi chương trình kết thúc. Tôi chắc chắn nó sẽ làm việc, nhưng tôi đã không thể tìm ra nó. Sử dụng phản ứng của trashgod và một số ví dụ khác, tôi đã có thể làm cho nó hoạt động bằng cách sử dụng SwingWorker. Thật không may, tôi không hoàn toàn hiểu cách nó hoạt động, nhưng tôi sẽ lấy nó ngay bây giờ.

Các gui và phương pháp để chạy các phép tính được gọi là trong lớp khác đầu tiên:

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

Sau đó, nó chạy như sau:

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 
Các vấn đề liên quan