001 // Copyright (c) 2001 Hursh Jain (http://www.mollypages.org)
002 // The Molly framework is freely distributable under the terms of an
003 // MIT-style license. For details, see the molly pages web site at:
004 // http://www.mollypages.org/. Use, modify, have fun !
005
006 package fc.io;
007
008 import java.io.*;
009
010 import fc.util.*;
011 /**
012 Prompts a user for input.
013 <p>
014 Thread safety: This class is not thread safe and higher level
015 synchronization (or multiple instances of this class) should
016 be used.
017
018 @author hursh jain
019 @version 1.0 12/15/2001
020 **/
021 public class Prompt
022 {
023 BufferedReader in;
024 PrintWriter err;
025 PrintWriter out;
026 protected String line = null; //the current input line
027
028 /**
029 Constructs the object using the specified input and output writers.
030 @param in the BufferedReader to use for input
031 @param out the PrintWriter to use for output
032 @param err the PrintWriter to use for errors
033 **/
034 public Prompt(Reader in, PrintWriter out, PrintWriter err)
035 {
036 Argcheck.notnull(in);
037 Argcheck.notnull(out);
038 Argcheck.notnull(err);
039 this.in = IOUtil.bufferReader(in);
040 this.out = out;
041 this.err = err;
042 }
043
044 /**
045 Constructs the object using the specified input and output streams.
046 @param in the BufferedReader to use for input
047 @param out the PrintWriter to use for output
048 @param err the PrintWriter to use for errors
049 **/
050 public Prompt(InputStream in, PrintStream out, PrintStream err)
051 {
052 Argcheck.notnull(in);
053 Argcheck.notnull(out);
054 Argcheck.notnull(err);
055 this.in = new BufferedReader(new InputStreamReader(in));
056 this.out = new PrintWriter(out);
057 this.err = new PrintWriter(err);
058 }
059
060
061 /**
062 Constructs a fallback object, using <tt>System.in, System.out</tt>
063 for the input, output and error streams.
064 **/
065 public Prompt()
066 {
067 this(
068 new BufferedReader(new InputStreamReader(System.in)),
069 new PrintWriter(System.out),
070 new PrintWriter(System.err)
071 );
072 }
073
074 /**
075 Shows the specified string to the user shows the input prompt
076 to the user (to indicate the user's input is expected). Keeps
077 looping and asking the same question until a non-empty response
078 has been typed by the user, then returns that response.
079
080 @param str the string to show to the user
081 @param newline whether to print a newline after the string
082 */
083 public String ask(String str, boolean newline)
084 {
085 String result = "";
086 while (result.equals(""))
087 {
088 out.print(str); //the string
089
090 if (newline)
091 out.println();
092
093 out.flush();
094 readLine();
095 result = line;
096 }
097
098 return result;
099 }
100
101 /**
102 Calls {@link ask(String, boolean)} so that a newline
103 is not shown after the question shown to the user.
104 **/
105 public String ask(String str) {
106 return ask(str, false);
107 }
108
109 /**
110 Shows the specified string to the user shows the input prompt
111 to the user (to indicate the user's input is expected). Returns
112 the fallback string if a empty response has been typed by the user,
113 else returns the user response.
114
115 @param str the string to show to the user
116 @param fallback response to return if the user types in an
117 empty response (typically by simply hitting a
118 newline)
119 @param newline whether to print a newline after showing the
120 specified string to the user
121 **/
122 public String ask(String str, String fallback, boolean newline)
123 {
124 out.print(str);
125 if (newline)
126 out.println();
127
128 out.flush();
129 readLine();
130 if (line.equals(""))
131 return fallback;
132
133 return line;
134 }
135
136 /**
137 Calls {@link ask(String, String, boolean)} so that a newline
138 is not shown after the question shown to the user.
139 **/
140 public String ask(String str, String fallback) {
141 return ask(str, fallback, false);
142 }
143
144
145 /**
146 Immediately writes a string to the output. The prompt is written
147 before the string.
148 */
149 public void write(String str)
150 {
151 out.print(str);
152 out.flush();
153 }
154
155 /**
156 Immediately writes the specified string as a new line, to the output.
157 The prompt is written before the string.
158 */
159 public void writeln(String str)
160 {
161 out.println(str);
162 out.flush();
163 }
164
165 /**
166 Gets the latest input line that has been read. Can return the
167 same line multiple times if no new lines have been read since
168 the last time this method was called. Returns <tt>null</tt>
169 if no line has been read so far.
170 **/
171 public String getLastLine() {
172 return line;
173 }
174
175 /**
176 Sets the next line of input without the trailing newline
177 character. A line of input is signalled when a newline character
178 is encountered. This method will block until the input has a
179 newline.<br>
180 Note: Unfortunately, as of JDK 1.4 there seems to be no way to
181 get the input buffer unless a newline is also entered. (Stream/Reader
182 methods like <tt>available</tt> and <tt>ready</tt> return 0/false
183 until a newline is entered). This means <tt>System.in</tt> always
184 appears to work in "cooked" mode (both on windows and an linux).
185 This sucks.
186 **/
187 protected void readLine()
188 {
189 try {
190 line = in.readLine();
191 }
192 catch(java.io.IOException e) {
193 e.printStackTrace();
194 }
195 }
196
197 //-- stream/writer sets ----
198
199 public void setInput(Reader in) {
200 this.in = IOUtil.bufferReader(in);
201 }
202
203 public void setInput(InputStream in) {
204 this.in = new BufferedReader(new InputStreamReader(in));
205 }
206
207 public void setOutput(PrintStream out) {
208 this.out = new PrintWriter(out);
209 }
210
211 public void setOutput(PrintWriter out) {
212 this.out = out;
213 }
214
215 public void setError(PrintStream err) {
216 this.err = new PrintWriter(err);
217 }
218
219 public void setError(PrintWriter err) {
220 this.err = err;
221 }
222
223
224 public static void main(String args[]) throws Exception
225 {
226 new Test();
227 }
228
229 /**
230 Unit Test History
231 <pre>
232 Class Version Tester Status Notes
233 1.0 hj passed
234 </pre>
235 */
236 static private class Test
237 {
238 Test() throws Exception
239 {
240 Prompt prompt = new Prompt();
241 String name = prompt.ask("What is your name ? ");
242 System.out.println("You entered: " + name);
243
244 name = prompt.ask("What is your age [default 1] ? ", "1");
245 System.out.println("You entered: " + name);
246 }
247 } //~Test
248
249 } //~class Prompt