2013-04-04 5 views
5

UPDATE: I found a crucial part to why this probably isn't working! I used System.setOut(out); where out is a special PrintStream to a JTextAreaएक प्रक्रिया

से एक जावा InputStream मुद्रण इस कोड है, लेकिन इस मुद्दे को मैं आ रही हैं कि जानकारी केवल बाहर छपा है एक बार मैं इस प्रक्रिया में पहुंचते हैं।

public Constructor() { 
    main(); 
} 

private void main() { 
    btnStart.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      try { 
       ProcessBuilder builder = new ProcessBuilder("java", textFieldMemory.getText(), "-jar", myJar); 
       Process process = builder.start(); 
       InputStream inputStream = process.getInputStream(); 
       BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream), 1); 
       String line; 
       while ((line = bufferedReader.readLine()) != null) { 
        System.out.println(line); 
       } 
       inputStream.close(); 
       bufferedReader.close(); 
      } catch (IOException ioe) { 
       ioe.printStackTrace(); 
      } 
     } 
    }); 
} 

वर्तमान उत्पादन:

Line 1 
Line 2 
Line 3 
Line 4 
Line 5 

यह सही उत्पादन होता है, लेकिन जब मैं प्रक्रिया समाप्त यह केवल एक बड़ा ब्लॉक के रूप में मुद्रित किया जा रहा है।

क्या किसी को पता है कि समस्या क्या है? यदि ऐसा है तो आप मुझे समझाने में मदद कर सकते हैं कि यह क्यों हो रहा है, अग्रिम धन्यवाद।

+2

उत्पादन 'BufferedReader' में बफ़र कर दिया गया है, बस' InputStream' से सामग्री पढ़ने सीधे देखने के लिए अगर यह बनाता है की कोशिश के लिए Concurrency in Swing पर एक नजर डालें एक अंतर – MadProgrammer

+1

मैं @MadProgrammer से सहमत हूं कि समस्या शायद बफर के साथ है। हालांकि, मैं सुझाव देता हूं कि 'BufferedReader' बफर आकार को 1 [इसके दो पैरामीटर कन्स्ट्रक्टर] के साथ सेट करें (http://docs.oracle.com/javase/6/docs/api/java/io/BufferedReader.html# BufferedReader% 28java.io.Reader,% 20int% 2 9): 'नया BufferedReader (नया इनपुटस्ट्रीम रीडर (इनपुटस्ट्रीम), 1) ' – DaoWen

+0

एक बाइटएरे ऑटपुटस्ट्रीम का उपयोग करना बेहतर होगा? मैं धाराओं के लिए पूरी तरह से नया हूं, और यह मुझे एक्सडी – Ciphor

उत्तर

8

प्रक्रिया के आउटपुट स्ट्रीम को एक अलग थ्रेड में प्रोसेसिंग करने से यहां मदद मिल सकती है।

ProcessBuilder builder = new ProcessBuilder("java", 
     textFieldMemory.getText(), "-jar", myJar); 
final Process process = builder.start(); 
final Thread ioThread = new Thread() { 
    @Override 
    public void run() { 
     try { 
      final BufferedReader reader = new BufferedReader(
        new InputStreamReader(process.getInputStream())); 
      String line = null; 
      while ((line = reader.readLine()) != null) { 
       System.out.println(line); 
      } 
      reader.close(); 
     } catch (final Exception e) { 
      e.printStackTrace(); 
     } 
    } 
}; 
ioThread.start(); 

process.waitFor(); 
+0

मेरे लिए काम नहीं किया, जैसा कि मैंने कहा, मुझे लगता है कि इसे इसके साथ करना है, मैंने कंसोल आउटपुट को JTextArea पर रीडायरेक्ट किया है। – Ciphor

+0

हाँ, यह एक बहुत ही महत्वपूर्ण जानकारी है। आउटपुट को रीयल टाइम में दिखाने के लिए, आपको प्रत्येक लिखने पर स्ट्रीम को स्पष्ट रूप से फ़्लश करना होगा, फिर JTextArea की एक पेंट ट्रिगर करना होगा। – Perception

+0

यदि आप प्रश्न में मेरे मूल कोड को देखते हैं तो मुझे कुछ दिलचस्प लगता है और 'इनपुटस्ट्रीम.क्लोज़();' थोड़ी देर लूप में स्थानांतरित हो गया है, मैं सफलतापूर्वक अपने 'JTextArea' में मुद्रित पहली पंक्ति प्राप्त करता हूं और फिर स्ट्रीम स्पष्ट रूप से बंद हो जाती है। – Ciphor

4

असल में, क्या कम जानकारी होती है, यह आपके घटना भेजने थ्रेड के भीतर से प्रक्रिया को क्रियान्वित करने और पढ़ने InputStream की तरह लगता है से: आप भी इस प्रक्रिया अपने तर्क के साथ जारी रखने से पहले समाप्त करने के लिए के लिए स्पष्ट रूप से प्रतीक्षा करने के लिए चाहते हैं ।

ईडीटी को अवरुद्ध करने के लिए कुछ भी इसे पुनर्भुगतान अनुरोधों को संसाधित करने से रोक देगा, इसके बजाय आपको SwingWorker जैसे कुछ का उपयोग करना चाहिए जिसमें आपको UI को ईडीटी से अपडेट करने की अनुमति मिलती है।

अधिक जानकारी के

enter image description here

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.io.File; 
import java.io.IOException; 
import java.io.InputStream; 
import java.util.List; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTextArea; 
import javax.swing.SwingWorker; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class PBDemo { 

    public static void main(String[] args) throws Exception { 
     new PBDemo(); 
    } 

    public PBDemo() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     public TestPane() { 
      setLayout(new BorderLayout()); 
      JTextArea ta = new JTextArea(); 
      add(new JScrollPane(ta)); 

      new ProcessWorker(ta).execute(); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 
    } 

    public interface Consumer { 
     public void consume(String value);    
    } 

    public class ProcessWorker extends SwingWorker<Integer, String> implements Consumer { 

     private JTextArea textArea; 

     public ProcessWorker(JTextArea textArea) { 
      this.textArea = textArea; 
     } 

     @Override 
     protected void process(List<String> chunks) { 
      for (String value : chunks) { 
       textArea.append(value); 
      } 
     } 

     @Override 
     protected Integer doInBackground() throws Exception { 
      // Forced delay to allow the screen to update 
      Thread.sleep(5000); 
      publish("Starting...\n"); 
      int exitCode = 0; 
      ProcessBuilder pb = new ProcessBuilder("java.exe", "-jar", "HelloWorld.jar"); 
      pb.directory(new File("C:\\DevWork\\personal\\java\\projects\\wip\\StackOverflow\\HelloWorld\\dist")); 
      pb.redirectError(); 
      try { 
       Process pro = pb.start(); 
       InputConsumer ic = new InputConsumer(pro.getInputStream(), this); 
       System.out.println("...Waiting"); 
       exitCode = pro.waitFor(); 

       ic.join(); 

       System.out.println("Process exited with " + exitCode + "\n"); 

      } catch (Exception e) { 
       System.out.println("sorry" + e); 
      } 
      publish("Process exited with " + exitCode); 
      return exitCode; 
     } 

     @Override 
     public void consume(String value) { 
      publish(value); 
     } 
    } 

    public static class InputConsumer extends Thread { 

     private InputStream is; 
     private Consumer consumer; 

     public InputConsumer(InputStream is, Consumer consumer) { 
      this.is = is; 
      this.consumer = consumer; 
      start(); 
     } 

     @Override 
     public void run() { 
      try { 
       int in = -1; 
       while ((in = is.read()) != -1) { 
//     System.out.print((char) in); 
        consumer.consume(Character.toString((char)in)); 
       } 
      } catch (IOException exp) { 
       exp.printStackTrace(); 
      } 
     } 
    } 
} 
+0

मेरे लिए काम नहीं किया, जैसा कि मैंने कहा, मुझे लगता है कि इसे इसके साथ करना है, मैंने कंसोल आउटपुट को JTextArea पर रीडायरेक्ट किया है। – Ciphor

+0

'JTextArea' का कोई उल्लेख नहीं था? क्या आप ईडीटी में प्रक्रिया को निष्पादित कर रहे हैं? – MadProgrammer

+0

क्षमा करें, हाँ मुझे एहसास है कि इस मुद्दे के कारण यह महत्वपूर्ण हिस्सा था जैसा मैंने पहले टिप्पणी की थी। और हमने अभी तक अपने पाठ्यक्रम पर धागे को कवर नहीं किया है><" – Ciphor

संबंधित मुद्दे