在计算发生时显示进度条

时间:2013-10-25 00:51:26

标签: java logic progress

我正在编写代码以计算Pi的值,有时可能需要很长时间才能计算出来。我添加了一个进度条来显示进度,但代码完全按照我的说法执行,它会在计算后打开进度条,然后立即关闭它(当值达到100时它会关闭) 我试图将进度条的代码粘贴到循环中,但很快我意识到解决了解决方案,但创建了多个进度条窗口。 如果在计算之前放置,则进度条保持为0(显然) 我在下面显示了我的代码:

import java.awt.BorderLayout;
import java.awt.Container;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JProgressBar;
import javax.swing.border.Border;
import java.util.Scanner;

public class PicCalc 
{
public static void main(String args[]) 
{
  Scanner keyboard = new Scanner(System.in);
  double i = 0;
    double stage = 1;
  int iterations = 1;
    int x = 3; //Simply a variable to calculate pi
  double y = -1.0; // Another variable for pi
    double myPi; //This is my calculation of Pi, don't eat it. 

  System.out.println("Hello! I calculate Pi and compare it to the acutal value of Pi!");
  System.out.println("How many iterations?");
  iterations = keyboard.nextInt();

  //Calculates Pi
  for (i = 1.0; i <= iterations; i++)
  {
         stage = stage + y/x;
         y = - y; //Flips Sign
         x+=2; 
  }

    myPi = 4*stage;
    System.out.println("My Pi: " + myPi);
    //STOP CALCULATING PI

    //CALCULATE PERCENT COMPLETE
  double percent = 100*(i/iterations);
  int intPercent = (int) (percent + 0.5); //Adds .5 in order to round.
  //STOP CALCULATING PERCENT COMPLETE

  //MAKES LOADING SCREEN
  JFrame f = new JFrame("Loading...");
  f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  Container content = f.getContentPane();
  JProgressBar progressBar = new JProgressBar();
  progressBar.setValue(intPercent);
  progressBar.setStringPainted(true);
  Border border = BorderFactory.createTitledBorder("Calcualating...");
  progressBar.setBorder(border);
  content.add(progressBar, BorderLayout.NORTH);
  f.setSize(300, 100);
  f.setVisible(true);
  //END OF MAKING LOADING SCREEN

 //CLOSES LOADING SCREEN WHEN 100% IS ACHIEVED
  if (percent >= 100)
  {
     f.dispose();
  }      
  //END OF CLOSING SCREEN HERE

3 个答案:

答案 0 :(得分:4)

你只有一个线程,所以GUI永远不会有机会更新(因为它正在忙于计算)。

通常的做法是将计算放在后台线程中,以便事件调度线程(EDT)[也就是GUI线程]可以自由更新GUI。

请参阅这些以获取一些指导,谷歌将会出现更多信息。

How do you use the Event Dispatch Thread?

Java Background thread

答案 1 :(得分:1)

编辑:我认为如果您从我的回答中考虑逻辑上的更改,并将其置于 John 建议的后台流程中,那么您将成为全部设置;)

我认为您可能希望将完成百分比的计算移动到for循环中,以便在进行迭代时更新进度。

//MAKES LOADING SCREEN
JFrame f = new JFrame("Loading...");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container content = f.getContentPane();
JProgressBar progressBar = new JProgressBar();
progressBar.setStringPainted(true);
Border border = BorderFactory.createTitledBorder("Calcualating...");
progressBar.setBorder(border);
content.add(progressBar, BorderLayout.NORTH);
f.setSize(300, 100);
f.setVisible(true);

double percent = 0;
int intPercent = 0;
progressBar.setValue(intPercent);
//Calculates Pi
for (i = 1.0; i <= iterations; i++)
{
    stage = stage + y/x;
    y = - y; //Flips Sign
    x+=2; 
    //CALCULATE PERCENT COMPLETE
    percent = 100*(i/iterations);
    intPercent = (int) (percent + 0.5); //Adds .5 in order to round.
    progressBar.setValue(intPercent);
    //STOP CALCULATING PERCENT COMPLETE
}

myPi = 4*stage;
System.out.println("My Pi: " + myPi);
//STOP CALCULATING PI

答案 2 :(得分:0)

你基本上有3个问题:

  1. 百分比计算不在for循环中
  2. 无效百分比计算
  3. 在计算完成后尝试显示表单
  4. 使用我的评论检查完整的工作代码:

    static private double myPi; // This is my calculation of Pi, don't eat it.
    public static void main(String[] args)
    {
        Scanner keyboard = new Scanner(System.in);
    
        System.out.println("Hello! I calculate Pi and compare it to the acutal value of Pi!");
        System.out.println("How many iterations?");
        final int iterations = keyboard.nextInt(); // me!!!: i needed to set 2000000000 to see actual window on my computer :)
    
        // MAKES LOADING SCREEN
        // me!!!: you should create frame before calculations, not after
        final JFrame f = new JFrame("Loading...");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        final Container content = f.getContentPane();
        final JProgressBar progressBar = new JProgressBar();
        progressBar.setStringPainted(true);
        Border border = BorderFactory.createTitledBorder("Calcualating...");
        progressBar.setBorder(border);
        content.add(progressBar, BorderLayout.NORTH);
        f.setSize(300, 100);
        f.setVisible(true);
        // END OF MAKING LOADING SCREEN
    
        // Calculates Pi
        Thread thread = new Thread() {
            public void run(){
                double stage = 1;
                int x = 3; // Simply a variable to calculate pi
                double y = -1.0; // Another variable for pi
    
                for (int i = 1; i <= iterations; i++)
                {
                    stage = stage + y / x;
                    y = -y; // Flips Sign
                    x += 2;
    
                    // CALCULATE PERCENT COMPLETE
                    // me!!!: you're always getting 0 with your old method here
                    double percent = 100.0 * i / iterations;
                    int intPercent = (int) (percent + 0.5); // Adds .5 in order to round.
                    progressBar.setValue(intPercent);
                    // STOP CALCULATING PERCENT COMPLETE
                }
                myPi = 4 * stage;
            }
        };
        thread.start();
        try
        {
            thread.join();
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    
        System.out.println("My Pi: " + myPi);
        // STOP CALCULATING PI
    
        // CLOSES LOADING SCREEN WHEN 100% IS ACHIEVED
        f.dispose();
        // END OF CLOSING SCREEN HERE
    }