Индикатор выполнения в Swing (Java) для командных инструментов - PullRequest
4 голосов
/ 12 апреля 2011

У меня есть несколько инструментов командной строки C / C ++, которые я упаковываю с помощью Java.Swing как GUI. Инструменты командной строки могут занять минуты или часы. Прогресс бар кажется хорошей идеей, чтобы держать пользователей в здравом уме. Я также думаю, что было бы неплохо обернуть графический интерфейс для индикатора выполнения, а не просто использовать систему. Но как?

Я думаю, что инструменты командной строки могут записывать проценты в stderr, и я могу как-то читать их в 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
      }
    });
    */
}

Ответы [ 3 ]

6 голосов
/ 12 апреля 2011

Это кажется очень хрупким, лучше было бы общаться через сокеты по хорошо установленному протоколу или с какой-то RCP (возможно, от Google) или даже с веб-сервисами.

Если вы все еще настаиваете, вы можете запустить процесс на Java с ProcessBuilder , который даст вам Process ссылку, из которой вы можете получить InputStream читать стандартный вывод, но опять же, это кажется мне очень хрупким.

Надеюсь, это поможет.

2 голосов
/ 13 апреля 2011

Для индикатора выполнения вашей проблемы вы можете сделать что-то вроде следующего.Обратите внимание, что это просто пример, чтобы проиллюстрировать это.

По сути, для выполнения работы создается нить.Предположительно, этот поток Runner будет взаимодействовать с вашим кодом C / C ++ для достижения прогресса.Затем он вызывает update для класса диалога Progress Bars.

   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) {
            }
        }
     }
   }
 }
1 голос
/ 13 апреля 2011
// 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");
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...