devxlogo

Reinventing the Art of Creating Command-line Java Apps

Reinventing the Art of Creating Command-line Java Apps

ith all the hype that servlets, JSPs, EJBs, and distributed J2EE applications have received, the art of creating a basic interactive command line Java application has been lost. Although fancy Swing-driven GUIs or browser-based clients are great for the end users of your company’s software development packages, they aren’t really necessary for in-house tools or utilities that you write to aid your development process. Very often, writing a Swing or browser-based interface for a maintenance or development tool is overkill in the first place and also cumbersome to maintain. What you need for these situations is something that’s quick, efficient, and easily scaled to accommodate new features. What you need is an interactive command line interface.

Although more advanced Java users will have more cause to use this technique, the material discussed in this article is fundamental in nature. Beyond having a basic understanding of the Java i/o classes, no special knowledge or background is necessary to understand this material. Two complete examples are provided at the end:one general example, and one more advanced example.



When Swing and browser-based GUIs are overkill, how can Java be used to develop a simple, efficient user interface?



The process of creating an interactive command line Java application is not a complicated one. There are three distinct steps involved in building this type of application:

  • Determining the need
  • Writing the code
  • Pulling everything together

Determine the Need
Before you write a single line of code, you need to determine exactly what the application’s needs are in terms of user input. Applications can generally be divided into two categories: computational and functional. Computational applications will take in data, feed it into a formula, and output a clearly defined result. Functional applications are slightly different. They take input from the user and perform one or more actions on behalf of the user, displaying a response when appropriate.

Determining which category your application falls into will not affect the way in which you take in the information; from a coding perspective, the syntax is the same with both types. It is, however, important to identify your application’s classification because that will help you to determine the number and type of input that is required.

For instance, a computational application generally will have one or more formulas hard-coded into the source code. The only input that must be taken from the user is that which is required by the formula. With some formulas, this will vary, but these kinds of considerations will aid you in identifying what input to request from the end user.

With a functional application, the process is slightly different. You must first identify what capabilities the application will have. Does this application only perform one specific task, or several related tasks? For example, you could create an application that performed a search and replace with a specified string on a specified file. This same application could also possess two other capabilities: the option to capitalize the first letter of every sentence, and a word count which identified the 10 most common words and the number of times they were each used.

Once the scope of your application has been determined, it is simply a matter of deciding what input is required to perform the task(s) that you have outlined above. In general, the more user-friendly and forgiving your application is with the input received, the more coding is involved to handle that input. Fortunately, tools like this are used for testing, development, and general utility, so being user-friendly is rarely a top priority.

With your application’s needs and scope clearly defined, you are ready to actually begin coding.

Write the Code
“System.out.println()” was probably the first method call you ever learned in Java (I mean, what easier way could you fulfill your need to produce the infamous “Hello World” output?). You use this call all the time, but do you understand its etymology? Here’s a quick lesson. The System class is composed entirely of public static methods. This means that you never instantiate objects of type System. Instead, System class methods are invoked directly by qualifying them with the class name and a period “( System.method() )”. So how does “out” fit into all of this? “out” is a static member of the System class. It refers to the standard output stream, which is an unbuffered Printstream sent to the console by default.

Reading input from the command line is the exact opposite of sending output to the console. Fortunately, Java has created a very consistently designed framework. The counterpart to the static class member out (which refers to the standard output stream), is the static class member in (which refers to the standard input stream). The following code will read one character from the keyboard:

char c = System.in.read();

While this may be useful for you in a few cases, it is not a very flexible solution because the standard input stream can only read one character at a time. To improve on this, you can wrap a BufferedReader object around the standard input stream like this:

BufferedReader in = new BufferedReader	( new InputStreamReader( System.in )  );

Now that you have a reference to a BufferedReader object, you are free to retrieve entire strings from the command line, using the readLine() method defined in the BufferedReader class:

String input = in.readLine();

Since you are likely to need several pieces of input from your user for a given application, it will be more efficient to put this code inside a method. Here’s an example of a method which takes a single string as a parameter and displays that string as the prompt to the user for input:

private static String getInputString ( String prompt ) throws IOException{	System.out.print( prompt );	return in.readLine();} //end getInputString()

There are many ways that you could expand upon this framework. You create several methods that returned different primitive types (char, double, int, etc.), or even create an entire class of static methods that you could reuse in all of your applications by using a simple import statement.

Pull everything together
Now that the input retrieval method(s) are written, it is time to pull everything together into a simple example. Since we’re dealing with I/O, we’ll need to import the java.io package into our class:

import java.io.*;

Then we’ll need to declare the BufferedReader object outside of the main() method, so that it can be used in the getInputString() method.

Buffered Reader in;

Then wrap everything in a try/catch block in the main() method. The two uses of the BufferedReader object (invocation and in.readLine() ) both have the potential to throw an IOException. Here’s what the main() method looks like:

public static void main( String[] args ) {	try{	in = BufferedReader( new InputStreamReader( System.in ) );	String name = getInputString( “What is your name? ” );	System.out.println( “Your name is ” + name );	  } catch ( IOException ioe )			ioe.printStackTrace();	   } //end try{}	} //end main()
And that’s it! You’ve taken input from the user and displayed it on the screen. Not very impressive, you say? Try creating a calculator, random number guessing game, or a keyword search utility.

Sample Applications
On this page are links to the source code for two interactive command line applications.

AreaCalc.java is a simple class that calculates the area of a circle, rectangle, or triangle, based on values specified by the user.

ServletClient.java is a utility that can be used to test the output produced by Java servlets. It issues a GET request against the specified URL based on the specified host and port.

devx-admin

Share the Post: