我最近在做一个文件处理软件,设置了一个进度条来显示大文件处理的进度。目前遇到以下问题向各位请教:
1.JProgressBar如何动态显示。我想达到这样的效果:处理文件前进度条不可见,点击处理文件的按钮时显示进度条,处理结束后进度条消失。我是这样写的://进度条所在窗体的构造方法里
JProgressBar jProgressBar=new JProgressBar();
jpb.setVisible(false);//按钮所对应的接口方法里
jProgressBar.setStringPainted(true);
jProgressBar.setString("处理中,请稍候...");
jProgressBar.setIndeterminate(true);//使用未知进度条
jProgressBar.setVisible(true);
.......//若干部其它操作(这些操作都是正确的)
jProgressBar.setVisible(false);上面代码的实际执行情况在点击按钮后根本不显示进度条,我尝试在点击按钮前就显示进度条,其它条件不变,但是在处理过程中并不显示未知进度条的动画。要达到我上面的效果应该怎样做呢?2.如何得到一个处理过程的总进度,JDK里提供了一个直接针对数据输入输出流的百分比进度条,但是那个只能用于一个流,我现在有多个流和其他操作,我想把这几个流的处理过程连同其他操作作为这个进度条所表示的一个事件,我想的是把每个操作当做一个单元,因为总的操作个数我是知道的,每完成一个操作就把对应的一个标志标量+1,当标志的值达到总操作个数的值时就不显示进度条,这钟想法合理吗?

解决方案 »

  1.   

    1、你要设计一个算法,随时能得到一个进度百分比;
    2、关于界面的显示,建议楼主看看 SwingWorker 相关文章。
      

  2.   

     开始页面:start.jsp<%@ page contentType="text/html; charset=GBK" %>
    <% session.removeAttribute("task"); %><jsp:useBean id="task" scope="session"  class="progress.TaskBean"/><% task.setRunning(true); %><% new Thread(task).start(); %><jsp:forward page="status.jsp"/>状态页面:status.jsp<%@ page contentType="text/html; charset=GBK" %>
    <jsp:useBean id="task" scope="session" class="progress.TaskBean"/>
    <HTML>
      <HEAD>  <TITLE>JSP进度条</TITLE>  <% if (task.isRunning()) { %>    <script type="" LANGUAGE="JavaScript">      setTimeout("location='status.jsp'", 1000);    </script>  <% } %></HEAD><bODY bgcolor=""><H1 ALIGN="CENTER">JSP进度条</H1>  <H2 ALIGN="CENTER">    结果: <%= task.getResult() %><BR>    <% int percent = task.getPercent(); %>    <%= percent %>%  </H2>  <TABLE WIDTH="60%" ALIGN="CENTER"       CELLPADDING=0 CELLSPACING=2>    <TR>      <% for (int i = 10; i <= percent; i += 10) { %>        <TD WIDTH="10%" height="10" BGCOLOR="red"> </TD>      <% } %>      <% for (int i = 100; i > percent; i -= 10) { %>        <TD WIDTH="10%"> </TD>      <% } %>    </TR>  </TABLE><TABLE WIDTH="100%" BORDER=0 CELLPADDING=0 CELLSPACING=0>    <TR>      <TD ALIGN="CENTER">        <% if (task.isRunning()) { %>          正在执行        <% } else { %>          <% if (task.isCompleted()) { %>            完成          <% } else if (!task.isStarted()) { %>            尚未开始          <% } else { %>            已停止          <% } %>        <% } %>      </TD>    </TR>
    <TR>      <TD ALIGN="CENTER">        <BR>        <% if (task.isRunning()) { %>          <FORM METHOD="GET" ACTION="stop.jsp">            <INPUT TYPE="SUBMIT" ="停止">          </FORM>        <% } else { %>          <FORM METHOD="GET" ACTION="start.jsp">            <INPUT TYPE="SUBMIT" ="开始">          </FORM>        <% } %>      </TD>    </TR>  </TABLE></BODY></HTML>停止页面:stop.jsp<%@ page contentType="text/html; charset=GBK" %>
    <jsp:useBean id="task" scope="session" class="progress.TaskBean"/><% task.setRunning(false); %><jsp:forward page="status.jsp"/>业务逻辑bean:TaskBean.javapackage progress;import java.io.Serializable;/**
     * 首先我们设计一个TaskBean类,它实现java.lang.Runnable接口,
     * 其run()方法在一个由JSP页面(start.jsp)启动的独立线程中运行。
     * 终止run()方法执行由另一个JSP页面stop.jsp负责。
     * TaskBean类还实现了java.io.Serializable接口,
     * 这样JSP页面就可以将它作为JavaBean调用
     * */
    public class TaskBean
        implements Runnable, Serializable {  private int counter;  private int sum;  private boolean started;  private boolean running;  private int sleep;  public TaskBean() {    counter = 0;    sum = 0;    started = false;    running = false;    sleep = 100;  }
      /**
       * TaskBean包含的“繁重任务”是计算1+2+3…+100的值,
       * 不过它不通过100*(100+1)/2=5050公式计算,而是由run()方法
       * 调用work()方法100次完成计算。work()方法的代码如下所示,
       * 其中调用Thread.sleep()是为了确保任务总耗时约10秒。
       * */
      protected void work() {    try {      Thread.sleep(sleep);      counter++;      sum += counter;    }
        catch (InterruptedException e) {
          setRunning(false);    }  }
      //status.jsp页面通过调用下面的getPercent()方法获得任务的完成状况:
      public synchronized int getPercent() {    return counter;  }
      //如果任务已经启动,isStarted()方法将返回true:
      public synchronized boolean isStarted() {    return started;  }
      //如果任务已经完成,isCompleted()方法将返回true
      public synchronized boolean isCompleted() {    return counter == 100;  }
      //如果任务正在运行,isRunning()方法将返回true:
      public synchronized boolean isRunning() {    return running;  }
      /**
       * SetRunning()方法由start.jsp或stop.jsp调用,
       * 当running参数是true时。SetRunning()方法还要将任务标记为“已经启动”。
       * 调用setRunning(false)表示要求run()方法停止执行。
       * */
      public synchronized void setRunning(boolean running) {    this.running = running;    if (running) {      started = true;
        }  }
      //任务执行完毕后,调用getResult()方法返回计算结果;如果任务尚未执行完毕,它返回null:
      public synchronized Object getResult() {    if (isCompleted()) {      return new Integer(sum);
        }    else {      return null;
        }  }
      /**
       * 当running标记为true、completed标记为false时,
       * run()方法调用work()。在实际应用中,run()方法也许要
       * 执行复杂的SQL查询、解析大型XML文档,或者调用消耗大量
       * CPU时间的EJB方法。注意“繁重的任务”可能要在远程服务器
       * 上执行。报告结果的JSP页面有两种选择:或者等待任务结束,或者使用一个进度条。
       * */
      public void run() {    try {      setRunning(true);      while (isRunning() && !isCompleted()) {        work();
          }    }
        finally {      setRunning(false);    }  }}
      

  3.   

    老兄,我问的是关于桌面程序的开发而不是网页方面的,我想了一个退一步的方法就是用一个带进度条动画的JLabel来做,处理文件前先隐藏JLabel,处理文件时调用setVisible(true)显示JLabel,处理完毕后调用setVisible(false)来隐藏,不过实际操作后发现这个方法根本行不同,一旦在开始隐藏了后面就算调用setVisible(true)也不能显示,我推测在JAVA里IO处理事件的优先级大于GUI显示,所以只能通过多线程和重写paint方法来实现我想要的效果
      

  4.   

    进度条需要提供另外的Thread来处理,
      

  5.   

    一点经验:如果用Thread来做,需要设置显示进度条线程优先级高于IO线程,因为JAVA里默认IO线程的优先级高于GUI