This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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