【问题标题】:Progress bar in Swing (Java) for command toolsSwing (Java) 中用于命令工具的进度条
【发布时间】:2011-04-12 19:39:35
【问题描述】:

我有几个 C/C++ 命令行工具,我用 Java.Swing 作为 GUI 进行了包装。命令行工具可能需要几分钟到几小时。进度条似乎是让用户保持理智的好主意。我还认为为进度条包装一个 GUI 可能会很好,而不是仅仅使用系统输出。但是怎么做?

我认为命令行工具可以将百分比写入标准错误,并且我可以以某种方式在 java 中读取它。不完全确定这样做的机制是什么。我也不清楚异步显示(了解了一些关于 invokeLater() )。 Java 新手,也希望得到一般性建议。谢谢。

---更新---

感谢大家的建议。这是生成的代码。

private void redirectSystemStreams() {
    OutputStream out_stderr = new OutputStream() {
      @Override
      public void write(final int b) throws IOException {
        update(String.valueOf((char) b));
      }
      @Override
      public void write(byte[] b, int off, int len) throws IOException {
        update(new String(b, off, len));
      }
      @Override
      public void write(byte[] b) throws IOException {
        write(b, 0, b.length);
      }
    };
    System.setErr(new PrintStream(out_stderr, true));
}

private void update(final String inputText) {
    int value = 20; //parse inputText; make sure your executable calls fflush(stderr) after each fprintf().
    jProgressBar.setValue(value);

    /* Also one can redirect to a textpane
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        //update jTextPane with inputText
      }
    });
    */
}

【问题讨论】:

    标签: java swing progress-bar


    【解决方案1】:

    这似乎很脆弱,最好是通过套接字以完善的协议或某种 RCP(可能是 Google 的 protobuf)甚至网络服务进行通信。

    如果您仍然坚持可以使用 ProcessBuilder 在 Java 中启动一个进程,它将为您提供一个 Process 引用,您可以获取 InputStream 以读取标准输出,但同样,这似乎非常脆弱我。

    我希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      对于问题的进度条部分,您可以执行以下操作。请注意,这只是说明这一点的示例。

      基本上,创建一个线程来完成这项工作。大概这个 Runner 线程将与您的 C/C++ 代码交互以获取其进度。然后它在进度条对话框类上调用更新。

         import java.awt.BorderLayout;
         import java.awt.Dimension;
         import javax.swing.JDialog;
         import javax.swing.JFrame;
         import javax.swing.JLabel;
         import javax.swing.JPanel;
         import javax.swing.JProgressBar;
      
        public class Main {
      
         private int value;
         private Progress pbar;
      
         public static void main(String args[]) {
            new Main();
         }
      
         public Main() {        
      
           pbar = new Progress();
           Thread t = new Thread(new Runner());
           t.start();
      
        }
      
        class Progress extends JDialog {
      
          JProgressBar pb;
          JLabel label;
      
          public Progress() {
              super((JFrame) null, "Task In Progress");
              pb = new JProgressBar(0, 100);
              pb.setPreferredSize(new Dimension(175, 20));
              pb.setString("Working");
              pb.setStringPainted(true);
              pb.setValue(0);
      
      
              label = new JLabel("Progress: ");
      
              JPanel panel = new JPanel();
              panel.add(label);
              panel.add(pb);
              add(panel, BorderLayout.CENTER);
              pack();
              setVisible(true);
          }
      
          public void update(){
              pb.setValue(value);
      
              if(value >= 100){
                  this.setVisible(false);
                  this.dispose();
              }
          }
      }
      
      class Runner implements Runnable {
      
          public void run() {
              for (int i = 0; i <= 100; i++) {
                  value++;
                  pbar.update();
                  try {
                      Thread.sleep(50);
                  } catch (InterruptedException e) {
                  }
              }
           }
         }
       }
      

      【讨论】:

        【解决方案3】:
        // Create a window
        JFrame frame = new JFrame("Progress");
        // Creates a progress bar and add it to the window
        JProgressBar prog = new JProgressBar();
        frame.add(prog);
        // Run C/C++ application
        try {
           Process p = Runtime.getRuntime().exec(new String[]{"filename","arg1","arg2","..."});
           // Get InputStream
           BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
           // Update the progress when recieving output from C/C++
           new java.util.Timer().schedule(new TimerTask(){
               public void run(){
                  String str = "";
                  while ((str=br.readLine()!=null) {
                     prog.setValue(new Integer(str)); // Set Value of Progress Bar
                     prog.setString(str+"%"); // Set Value to display (in text) on Progress Bar
                  }
               }
           },0,100); // Check every 100 milliseconds
           // Fit the window to its contents and display it
           frame.pack();
           frame.setVisible(true);
         } catch (Exception e) {
            System.out.println("Failed To Launch Program or Failed To Get Input Stream");
         }
        

        【讨论】:

        • 感谢您的所有建议。我决定采用以下方法。 int 10
        猜你喜欢
        • 2010-10-25
        • 1970-01-01
        • 1970-01-01
        • 2014-06-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多