Skip to content

Instantly share code, notes, and snippets.

@seronis
Created June 12, 2013 00:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save seronis/5762001 to your computer and use it in GitHub Desktop.
Save seronis/5762001 to your computer and use it in GitHub Desktop.
package seronis.testing;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.PrintStream;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
@SuppressWarnings("serial")
public class ConsoleTest extends JFrame implements WindowListener, Runnable {
TextPanel txtPanel;
TextField cmdPanel;
private boolean quit;
private Thread reader1;
private final PipedInputStream pin1 = new PipedInputStream();
private Thread reader2;
private final PipedInputStream pin2 = new PipedInputStream();
public ConsoleTest(String title) {
super(title);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension windowSize = new Dimension(
(int) (screenSize.width / 2),
(int) (screenSize.height / 2)
);
int x = (int) (windowSize.width / 2);
int y = (int) (windowSize.height / 2);
this.setBounds(x, y, windowSize.width, windowSize.height);
this.getContentPane().setLayout(new BorderLayout());
txtPanel = new TextPanel();
txtPanel.setEditable(false);
this.getContentPane().add(new JScrollPane(txtPanel),
BorderLayout.CENTER);
cmdPanel = new TextField();
cmdPanel.setEditable(true);
cmdPanel.addActionListener(cmdPanel);
this.getContentPane().add(cmdPanel,
BorderLayout.PAGE_END);
quit = false;
try { //one pipe for handling stdout
PipedOutputStream pout1 = new PipedOutputStream(this.pin1);
System.setOut(new PrintStream(pout1, true));
txtPanel.append("\nAttempting redirect of stdout...");
} catch (java.io.IOException io) {
txtPanel.append("\nRedirect to STDOUT failure\n" + io.getMessage());
} catch (SecurityException se) {
txtPanel.append("\nRedirect to STDOUT failure\n" + se.getMessage());
}
//... and one thread to capture its contents
reader1 = new Thread(this);
reader1.setDaemon(true);
reader1.start();
System.out.println("success?");
try { Thread.sleep(100);}catch(InterruptedException ie) {}
try { //now time for stderr
PipedOutputStream pout2 = new PipedOutputStream(this.pin2);
System.setErr(new PrintStream(pout2, true));
txtPanel.append("\nAttempting redirect of stderr...");
} catch (java.io.IOException io) {
txtPanel.append("\nRedirect to STDERR failure\n" + io.getMessage());
} catch (SecurityException se) {
txtPanel.append("\nRedirect to STDERR failure\n" + se.getMessage());
}
reader2 = new Thread(this);
reader2.setDaemon(true);
reader2.start();
System.err.println("success?");
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame window;
window = new ConsoleTest("Experimental Console Window");
window.setVisible(true);
}
});
}
public class TextPanel extends JTextArea {
//customize as your needs require, or dont
}
public class TextField extends JTextField implements ActionListener {
//customize further as your needs require
public TextField() {
}
@Override
public void actionPerformed(ActionEvent e) {
//TODO: this method is where your 'command parsing' would occur
String text = this.getText();
txtPanel.append(text + "\n");
this.selectAll();
//Make sure the new text is visible
txtPanel.setCaretPosition(txtPanel.getDocument().getLength());
}
}
@Override
public void run() {
//we implement 'Runnable' which means when we launched the worker threads
// in the constructor their .start() methods will each call our .run()
// method. Detect which thread is entering (both will) and start each on
// an infinite loop to grab output from the pipes.
try
{
while (Thread.currentThread()==reader1)
{
try { synchronized(this){this.wait(66);}}catch(InterruptedException ie) {}
if (pin1.available()!=0) {
String input=this.readLine(pin1);
txtPanel.append(input);
}
if (quit) return;
}
while (Thread.currentThread()==reader2)
{
try { synchronized(this){this.wait(66);}}catch(InterruptedException ie) {}
if (pin2.available()!=0) {
String input=this.readLine(pin2);
txtPanel.append(input);
}
if (quit) return;
}
} catch (Exception e)
{
txtPanel.append( "\n*** EXCEPTION CAUGHT: " + e + "\n");
}
}
public synchronized String readLine(PipedInputStream in) throws IOException
{
String input="";
do {
int length=in.available();
if (length==0) break;
byte b[]=new byte[length];
in.read(b);
input=input+new String(b,0,b.length);
}while( !input.endsWith("\n") && !quit);
return input;
}
@Override
public void windowClosed(WindowEvent arg0) {
quit=true;
this.notifyAll();
try { reader1.join(666);pin1.close(); } catch (Exception e){}
try { reader2.join(666);pin2.close(); } catch (Exception e){}
System.exit(0);
}
@Override
public void windowClosing(WindowEvent arg0) {
this.setVisible(false);
this.dispose();
}
@Override
public void windowActivated(WindowEvent arg0) {
//NOTE Auto-generated method stub
}
@Override
public void windowDeactivated(WindowEvent arg0) {
//NOTE Auto-generated method stub
}
@Override
public void windowDeiconified(WindowEvent arg0) {
//NOTE Auto-generated method stub
}
@Override
public void windowIconified(WindowEvent arg0) {
//NOTE Auto-generated method stub
}
@Override
public void windowOpened(WindowEvent arg0) {
//NOTE Auto-generated method stub
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment