View Javadoc
1   package org.opentrafficsim.remotecontrol;
2   
3   import java.io.OutputStream;
4   import java.lang.reflect.InvocationTargetException;
5   
6   import javax.swing.JTextArea;
7   import javax.swing.SwingUtilities;
8   
9   /**
10   * Output stream that writes to a Swing component. Derived from
11   * https://www.codejava.net/java-se/swing/redirect-standard-output-streams-to-jtextarea
12   * <p>
13   * Copyright (c) 2020-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
14   * BSD-style license. See <a href="https://opentrafficsim.org/docs/current/license.html">OpenTrafficSim License</a>.
15   * </p>
16   * @author <a href="https://www.tudelft.nl/averbraeck">Alexander Verbraeck</a>
17   * @author <a href="https://www.tudelft.nl/pknoppers">Peter Knoppers</a>
18   * @author <a href="https://www.transport.citg.tudelft.nl">Wouter Schakel</a>
19   */
20  public class TextAreaOutputStream extends OutputStream
21  {
22      /** Swing output object to append all output to. */
23      private final JTextArea textArea;
24  
25      /**
26       * Construct a new TextAreaOutputStream object.
27       * @param textArea JTextArea; the text area to append the output onto
28       */
29      TextAreaOutputStream(final JTextArea textArea)
30      {
31          this.textArea = textArea;
32      }
33  
34      /**
35       * Write to the textArea. May only be called from within the AWT thread!
36       * @param bytes byte[]; bytes to write
37       * @param offset int; offset within bytes of the first byte to write
38       * @param length int; number of bytes to write
39       */
40      public void awtWrite(final byte[] bytes, final int offset, final int length)
41      {
42          synchronized (this.textArea)
43          {
44              for (int index = offset; index < offset + length; index++)
45              {
46                  // redirects data to the text area
47                  this.textArea.append(String.valueOf((char) (bytes[index])));
48              }
49              // scrolls the text area to the end of data
50              this.textArea.setCaretPosition(this.textArea.getDocument().getLength());
51          }
52      }
53  
54      /**
55       * Write to the textArea. May only be called from within the AWT thread!
56       * @param b int; byte to write
57       */
58      public void awtWrite(final int b)
59      {
60          synchronized (this.textArea)
61          {
62              // redirects data to the text area
63              this.textArea.append(String.valueOf((char) b));
64              // scrolls the text area to the end of data
65              this.textArea.setCaretPosition(this.textArea.getDocument().getLength());
66          }
67      }
68  
69      /** {@inheritDoc} */
70      @Override
71      public void write(final byte[] bytes, final int offset, final int length)
72      {
73          if (SwingUtilities.isEventDispatchThread())
74          {
75              awtWrite(bytes, offset, length);
76          }
77          else
78          {
79              try
80              {
81                  SwingUtilities.invokeAndWait(new Runnable()
82                  {
83                      /** {@inheritDoc} */
84                      @Override
85                      public void run()
86                      {
87                          awtWrite(bytes, offset, length);
88                      }
89                  });
90              }
91              catch (InvocationTargetException | InterruptedException e)
92              {
93                  e.printStackTrace();
94              }
95          }
96      }
97  
98      /** {@inheritDoc} */
99      @Override
100     public void write(final byte[] bytes)
101     {
102         write(bytes, 0, bytes.length);
103     }
104 
105     /** {@inheritDoc} */
106     @Override
107     public void write(final int b)
108     {
109         try
110         {
111             SwingUtilities.invokeAndWait(new Runnable()
112             {
113                 /** {@inheritDoc} */
114                 @Override
115                 public void run()
116                 {
117                     awtWrite(b);
118                 }
119             });
120         }
121         catch (InvocationTargetException | InterruptedException e)
122         {
123             e.printStackTrace();
124         }
125     }
126 
127 }