一个进度条可以在主要的课外使用吗?

现在,我的主要只是调用10行gui。 根据这些行中有多less行具有文本,将调用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 

SwingWorker是这个理想的select。 下面的示例在后台执行简单的迭代,同时在窗口中报告进度和中间结果。 您可以在适当的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(); } }); } } 

我想你的预感是对的,你需要坚持Swing的线程规则。

那么该怎么办?

首先,我不确定你的应用程序是如何devise的。 你说你有一大堆行的主框架,可能每个都有可能调用9个类中的一个,它们看起来都像上面那样。 看来这些类将会生成自己的JFrame 。 我想这个新的框架是完全用于进度条。 我会认为这是devise,并会相应地提出build议。

我build议您在Runnable实例中执行一些操作,然后将这些Runnable实例放到SwingUtilities.invokeLater ,让它们在EDT上运行。 同时,如果阅读,我会花时间重新组织您的代码。

  1. 将您的GUI位的创build移动到一个方法中:
  public void createComponents(){
       SwingUtilities.invokeLater(new Runnable(){
         public void run(){
           //创build所有组件
           progressFrame =新的JFrame(“计算进度”);
           progressFrame.setSize(300,100);
           pane = progressFrame.getContentPane();
           pane.setLayout(NULL);
           progressFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
           progressBar = new JProgressBar(0,iterations);
           //添加组件到窗格
           pane.add(进度条);

           //位置控件(X,Y,宽度,高度)
           progressBar.setBounds(10,10,280,20);

           //使框架可见
           progressFrame.setResizable(假);  //没有resize
           progressFrame.setVisible(真);
        }
       });

     }
  1. 然后,我将使用calc中的两个GUI操作进行方法化:
     私人无效updateProgressBar(最终诠释我){
            SwingUtilities.invokeLater(new Runnable(){
                 public void run(){
                    progressBar.setValue(ⅰ);
                    //不需要以下内容
                    //progressBar.repaint(); 

                 }
            });
     }

    私人无效killDialog(){
            SwingUtilities.invokeLater(new Runnable(){
                 public void run(){
                     progressFrame.setVisible(假);
                 }
             });
     } 
  1. 最后,用这些方法的调用来replace这些新方法中包含的代码。

谢谢您的帮助。 我开始尝试使用第一个响应,但是我无法同时运行它,并且在程序结束时运行。 我敢肯定,它会工作,但我无法弄清楚。 使用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