eric2405
asked on
Running Command Prompt within Java GUI
How do I run the Command prompt within a java GUI?(i.e. I know how to "invoke" the Dos Prompt from java, what I need is to run Dos and its commands within the GUI).
Below is the code I've been working with, it only display the first lines of the command prompt on the text field and doesn't allow me to interact with dos. What do I need to do?
Please I do need a clear answer.
THANKS ever so much experts.
import java.lang.*;
import java.io.*;
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.*;
public class Dos implements Runnable
{
private PipedOutputStream pipeout;
private PipedOutputStream pipeerr;
String command = "cmd";
public Dos ( String[] cmd )
{
pipeout = null;
pipeerr = null;
}
public void run ()
{
exec ();
}
public void exec ()
{
// Class to redirect the process input stream to a piped output stream
class OutputMonitor implements Runnable
{
InputStream is;
PipedOutputStream pout;
public OutputMonitor ( InputStream i, PipedOutputStream p )
{
is = i;
pout = p;
}
public void run ()
{
try
{
int inputChar;
for ( ;; )
{
inputChar = is.read();
if ( inputChar == -1 )
{ break; }
if ( pout == null )
{
System.out.write ( inputChar );
}
else
{
pout.write ( inputChar );
}
}
if ( pout != null )
{
pout.flush ();
pout.close ();
}
else
{
System.out.flush();
}
}
catch ( Exception e ) { e.printStackTrace (); }
}
}
try
{
Runtime r = Runtime.getRuntime ();
Process p = r.exec (command);
OutputMonitor out = new OutputMonitor ( p.getInputStream (), pipeout );
OutputMonitor err = new OutputMonitor ( p.getErrorStream (), pipeerr );
Thread t1 = new Thread ( out );
Thread t2 = new Thread ( err );
t1.start ();
t2.start ();
}
catch ( Exception e ) { e.printStackTrace (); }
}
public PipedInputStream getInputStream () throws IOException
{
pipeout = new PipedOutputStream ();
return new PipedInputStream ( pipeout );
}
public PipedInputStream getErrorStream () throws IOException
{
pipeerr = new PipedOutputStream ();
return new PipedInputStream ( pipeerr );
}
public void execInThread ()
{
Thread t = new Thread ( this );
t.start ();
}
public static JPanel getContentPane ( JTextArea ta )
{
JPanel p = new JPanel ( new BorderLayout () );
JPanel bottom = new JPanel ( new FlowLayout () );
JButton button = new JButton ( " Exit " );
button.addActionListener ( new ActionListener ( )
{
public void actionPerformed ( ActionEvent e )
{
System.exit ( 0 );
}
}
);
bottom.add ( button );
p.add ( new JScrollPane ( ta ), BorderLayout.CENTER );
p.add ( bottom, BorderLayout.SOUTH );
p.setPreferredSize ( new Dimension ( 640,480 ) );
return p;
}
public static void main ( String[] arg )
{
// Class run in a thread,listens for the process output
// and forwards it to the UI via invokeLater()
class GuiUpdate implements Runnable
{
private PipedInputStream pin;
private PipedInputStream perr;
private JTextArea outputArea;
GuiUpdate ( JTextArea textArea, PipedInputStream in )
{
pin = in;
outputArea = textArea;
}
public void run ()
{
// Class to run on the event dispatch thread to update the GUI
class UpdateSwing implements Runnable
{
String update;
JTextArea swingTextArea;
public UpdateSwing ( JTextArea a, String s )
{
update = s;
swingTextArea = a;
}
public void run ()
{
outputArea.append ( update + "\n" );
}
}
try
{
// Read file before displaying
BufferedReader r = new BufferedReader ( new InputStreamReader ( pin ) );
String line;
for ( ;; )
{
line = r.readLine ();
if ( line == null ) { break; }
SwingUtilities.invokeLater ( new UpdateSwing ( outputArea, line ) );
Thread.yield ();
}
}
catch ( Exception e ) { e.printStackTrace (); }
}
}
// Create and invoke GUI
JFrame f = new JFrame ( "GUI for Dos" );
f.setDefaultCloseOperation ( JFrame.EXIT_ON_CLOSE );
JTextArea textOutput = new JTextArea ();
f.getContentPane().add ( getContentPane ( textOutput ) );
f.pack();
f.show ();
// Start command and capture output in the scrollable text area
try
{
// Create command and setup the pipes
Dos d = new Dos ( arg );
PipedInputStream stdout_pipe = d.getInputStream ();
PipedInputStream stderr_pipe = d.getErrorStream ();
d.execInThread ( );
// Results
Thread t1 = new Thread ( new GuiUpdate ( textOutput, stdout_pipe ) );
Thread t2 = new Thread ( new GuiUpdate ( textOutput, stderr_pipe ) );
t1.start ();
t2.start ();
}
catch ( Exception e ) { e.printStackTrace (); }
}
}
Below is the code I've been working with, it only display the first lines of the command prompt on the text field and doesn't allow me to interact with dos. What do I need to do?
Please I do need a clear answer.
THANKS ever so much experts.
import java.lang.*;
import java.io.*;
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.*;
public class Dos implements Runnable
{
private PipedOutputStream pipeout;
private PipedOutputStream pipeerr;
String command = "cmd";
public Dos ( String[] cmd )
{
pipeout = null;
pipeerr = null;
}
public void run ()
{
exec ();
}
public void exec ()
{
// Class to redirect the process input stream to a piped output stream
class OutputMonitor implements Runnable
{
InputStream is;
PipedOutputStream pout;
public OutputMonitor ( InputStream i, PipedOutputStream p )
{
is = i;
pout = p;
}
public void run ()
{
try
{
int inputChar;
for ( ;; )
{
inputChar = is.read();
if ( inputChar == -1 )
{ break; }
if ( pout == null )
{
System.out.write ( inputChar );
}
else
{
pout.write ( inputChar );
}
}
if ( pout != null )
{
pout.flush ();
pout.close ();
}
else
{
System.out.flush();
}
}
catch ( Exception e ) { e.printStackTrace (); }
}
}
try
{
Runtime r = Runtime.getRuntime ();
Process p = r.exec (command);
OutputMonitor out = new OutputMonitor ( p.getInputStream (), pipeout );
OutputMonitor err = new OutputMonitor ( p.getErrorStream (), pipeerr );
Thread t1 = new Thread ( out );
Thread t2 = new Thread ( err );
t1.start ();
t2.start ();
}
catch ( Exception e ) { e.printStackTrace (); }
}
public PipedInputStream getInputStream () throws IOException
{
pipeout = new PipedOutputStream ();
return new PipedInputStream ( pipeout );
}
public PipedInputStream getErrorStream () throws IOException
{
pipeerr = new PipedOutputStream ();
return new PipedInputStream ( pipeerr );
}
public void execInThread ()
{
Thread t = new Thread ( this );
t.start ();
}
public static JPanel getContentPane ( JTextArea ta )
{
JPanel p = new JPanel ( new BorderLayout () );
JPanel bottom = new JPanel ( new FlowLayout () );
JButton button = new JButton ( " Exit " );
button.addActionListener ( new ActionListener ( )
{
public void actionPerformed ( ActionEvent e )
{
System.exit ( 0 );
}
}
);
bottom.add ( button );
p.add ( new JScrollPane ( ta ), BorderLayout.CENTER );
p.add ( bottom, BorderLayout.SOUTH );
p.setPreferredSize ( new Dimension ( 640,480 ) );
return p;
}
public static void main ( String[] arg )
{
// Class run in a thread,listens for the process output
// and forwards it to the UI via invokeLater()
class GuiUpdate implements Runnable
{
private PipedInputStream pin;
private PipedInputStream perr;
private JTextArea outputArea;
GuiUpdate ( JTextArea textArea, PipedInputStream in )
{
pin = in;
outputArea = textArea;
}
public void run ()
{
// Class to run on the event dispatch thread to update the GUI
class UpdateSwing implements Runnable
{
String update;
JTextArea swingTextArea;
public UpdateSwing ( JTextArea a, String s )
{
update = s;
swingTextArea = a;
}
public void run ()
{
outputArea.append ( update + "\n" );
}
}
try
{
// Read file before displaying
BufferedReader r = new BufferedReader ( new InputStreamReader ( pin ) );
String line;
for ( ;; )
{
line = r.readLine ();
if ( line == null ) { break; }
SwingUtilities.invokeLater
Thread.yield ();
}
}
catch ( Exception e ) { e.printStackTrace (); }
}
}
// Create and invoke GUI
JFrame f = new JFrame ( "GUI for Dos" );
f.setDefaultCloseOperation
JTextArea textOutput = new JTextArea ();
f.getContentPane().add ( getContentPane ( textOutput ) );
f.pack();
f.show ();
// Start command and capture output in the scrollable text area
try
{
// Create command and setup the pipes
Dos d = new Dos ( arg );
PipedInputStream stdout_pipe = d.getInputStream ();
PipedInputStream stderr_pipe = d.getErrorStream ();
d.execInThread ( );
// Results
Thread t1 = new Thread ( new GuiUpdate ( textOutput, stdout_pipe ) );
Thread t2 = new Thread ( new GuiUpdate ( textOutput, stderr_pipe ) );
t1.start ();
t2.start ();
}
catch ( Exception e ) { e.printStackTrace (); }
}
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
As you can see TestApplication and TestFrame simply serve GUI purposes.
ExecProcessor is an interface that includes methods needed to process INPUT/ERROR signals from the process being executed by Java code.
ExecHelper is the interesting class since it carries out the job. It first spawns the process, binds its streams and controls the threads it uses to monitor the I/O activity of the spawned process.
The way this program is designed and implemented you can substitute any other GUI instead of TestApplication and TestFrame and as long as you have an ExecProcessor responding to the process events and an ExecHelper to start the process, all will work exactly as it does in my example.
Hope this helps,
Doron
ExecProcessor is an interface that includes methods needed to process INPUT/ERROR signals from the process being executed by Java code.
ExecHelper is the interesting class since it carries out the job. It first spawns the process, binds its streams and controls the threads it uses to monitor the I/O activity of the spawned process.
The way this program is designed and implemented you can substitute any other GUI instead of TestApplication and TestFrame and as long as you have an ExecProcessor responding to the process events and an ExecHelper to start the process, all will work exactly as it does in my example.
Hope this helps,
Doron
I would like to add that I am sorry for not really fixing your code so that it would work. I felt that it would be a better approach to present you with code that is modular, documented and most importantly, works in a way that would suit more than just running the DOS command line interface.
Good luck,
Doron
Good luck,
Doron
ASKER
Thanks for the comments savalou
Thanks ever so much for your help Doron.
Now I must be doing something really stupid because I can't get the program to work.
I have put the .java programs in two different packages. This is what I get when I try to compile the programs.
ExecProcessor.java
(Compiled)
ExecHelper.java
C:\dev\exec\tester\dev\exe c\util\Exe cHelper.ja va:21: cannot resolve symbol
symbol : class ExecProcessor
location: class dev.exec.util.ExecHelper
private ExecProcessor handler;
^
C:\dev\exec\tester\dev\exe c\util\Exe cHelper.ja va:23: cannot resolve symbol
symbol : class ExecProcessor
location: class dev.exec.util.ExecHelper
private ExecHelper(ExecProcessor ep, Process p) {
^
C:\dev\exec\tester\dev\exe c\util\Exe cHelper.ja va:59: cannot resolve symbol
symbol : class ExecProcessor
location: class dev.exec.util.ExecHelper
public static ExecHelper exec(ExecProcessor handler, String command) throws IOException {
^
3 errors
Tool completed with exit code 1
TestFrame.java
(Compiled)
TestApplication.java
C:\dev\exec\tester\TestApp lication.j ava:13: cannot resolve symbol
symbol : class TestFrame
location: class dev.exec.tester.TestApplic ation
TestFrame frame = new TestFrame();
^
C:\dev\exec\tester\TestApp lication.j ava:13: cannot resolve symbol
symbol : class TestFrame
location: class dev.exec.tester.TestApplic ation
TestFrame frame = new TestFrame();
^
2 errors
Tool completed with exit code 1
I am sorry to ask again, but please where have I gone wrong?
Thanks again Doron I really appreciate your help
Eric
Thanks ever so much for your help Doron.
Now I must be doing something really stupid because I can't get the program to work.
I have put the .java programs in two different packages. This is what I get when I try to compile the programs.
ExecProcessor.java
(Compiled)
ExecHelper.java
C:\dev\exec\tester\dev\exe
symbol : class ExecProcessor
location: class dev.exec.util.ExecHelper
private ExecProcessor handler;
^
C:\dev\exec\tester\dev\exe
symbol : class ExecProcessor
location: class dev.exec.util.ExecHelper
private ExecHelper(ExecProcessor ep, Process p) {
^
C:\dev\exec\tester\dev\exe
symbol : class ExecProcessor
location: class dev.exec.util.ExecHelper
public static ExecHelper exec(ExecProcessor handler, String command) throws IOException {
^
3 errors
Tool completed with exit code 1
TestFrame.java
(Compiled)
TestApplication.java
C:\dev\exec\tester\TestApp
symbol : class TestFrame
location: class dev.exec.tester.TestApplic
TestFrame frame = new TestFrame();
^
C:\dev\exec\tester\TestApp
symbol : class TestFrame
location: class dev.exec.tester.TestApplic
TestFrame frame = new TestFrame();
^
2 errors
Tool completed with exit code 1
I am sorry to ask again, but please where have I gone wrong?
Thanks again Doron I really appreciate your help
Eric
The correct file structure of the source directory is like this:
C:.
└──γ 2;dev
└──γ 2;exec
├──γ 2;tester
│ ├──γ 2;TestAppl ication.ja va
│ └──γ 2;TestFram e.java
└──γ 2;util
├──γ 2;ExecHelp er.java
└──γ 2;ExecProc essor.java
Once you have all the sources in the correct directories according to the above layout, everything should compile without problems. You could also just remove the package decleration from the code and compile it all from one source directory, this should work as well.
Hope this helps,
Doron
C:.
└──γ
└──γ
├──γ
│ ├──γ
│ └──γ
└──γ
├──γ
└──γ
Once you have all the sources in the correct directories according to the above layout, everything should compile without problems. You could also just remove the package decleration from the code and compile it all from one source directory, this should work as well.
Hope this helps,
Doron
Ummmm, yes... Directory trees do not appear so nicely here... lets see if this works better:
C:.
+-------dev
+-------exec
+-------tester
| +---TestApplication.java
| +---TestFrame.java
|
+-------util
+---ExecHelper.java
+---ExecProcessor.java
C:.
+-------dev
+-------exec
+-------tester
| +---TestApplication.java
| +---TestFrame.java
|
+-------util
+---ExecHelper.java
+---ExecProcessor.java
Slightly better, well, the idea is that first you have the "dev" folder, within it you have the "exec" folder, with in that you have the "util" and "tester" folders. The "util" folder contains the "ExecHelper.java" and "ExecProcessor.java" files; while the "tester" folder has the "TestApplication.java" and "TestFrame.java" files.
Sorry about this mess, I wish I'd've posted all of this in one post :)
Doron
Sorry about this mess, I wish I'd've posted all of this in one post :)
Doron
ASKER
Fine it works now! That is exactly what I needed
Thank you very much indeed Doron for an excellent help
Eric
Thank you very much indeed Doron for an excellent help
Eric
You're welcome :)
1. I don't think you should be closing everything down if there is no input in the run() method of OutputMonitor.
2. Any new commands to be run should be writen to the OutputStream of your Process.
3. You could set a KeyListener on your TextArea to listen for key presses, and echo these to the OutputStream of your Process.
class MyKeyListener implements KeyListener {
public void keyTyped(KeyEvent e) {
System.out.println("key typed: " + e.getKeyChar());
}
public void keyPressed(KeyEvent e) {
System.out.println("presse
}
public void keyReleased(KeyEvent e) {
System.out.println("releas
}
}
I think you should move some of the code around and break it up into different classes for clarity (you probably had them all in one file to post here?).
Good luck.