5 import java.awt.event.*;
7 import java.util.IllegalFormatException;
8 import java.util.regex.Matcher;
9 import java.util.regex.Pattern;
89 return "TextIO Applet";
118 if (milliseconds <= 0)
125 catch (InterruptedException e) {
170 return java.lang.System.currentTimeMillis();
172 public void exit(
int ignored) {
173 throw new RuntimeException(
"Program ended with System.exit().");
195 JPanel bottom =
new JPanel();
199 abortButton.addActionListener(
new ActionListener() {
200 public void actionPerformed(ActionEvent evt) {
211 public void actionPerformed(ActionEvent evt) {
219 bottom.setBackground(Color.LIGHT_GRAY);
223 message.setForeground(Color.RED);
224 message.setBackground(Color.LIGHT_GRAY);
226 message.setFont(
new Font(f.getName(),Font.BOLD,(
int)(f.getSize()*1.12)));
227 JPanel top =
new JPanel();
228 top.setLayout(
new BorderLayout());
229 top.setBackground(Color.LIGHT_GRAY);
230 top.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
232 JPanel panel =
new JPanel();
233 panel.setLayout(
new BorderLayout(2,2));
234 panel.setBackground(Color.DARK_GRAY);
235 panel.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY,3));
236 panel.add(
console,BorderLayout.CENTER);
237 panel.add(
console.scroller,BorderLayout.EAST);
238 panel.add(bottom,BorderLayout.SOUTH);
239 panel.add(top,BorderLayout.NORTH);
240 setContentPane(panel);
251 catch (InterruptedException e) {
270 catch (Exception e) {
272 console.
putString(
"\n\n\n ***** PROGRAM TERMINATED BY EXCEPTION ***** \n\n\n");
314 public final char EOF = (char)0xFFFF;
334 catch (Exception e) {
350 if (inputStream ==
null)
353 readStream(
new InputStreamReader(inputStream));
363 if (inputStream ==
null)
366 if ( inputStream instanceof BufferedReader)
367 in = (BufferedReader)inputStream;
369 in =
new BufferedReader(inputStream);
387 if (fileName ==
null)
390 BufferedReader newin;
392 newin =
new BufferedReader(
new FileReader(fileName) );
394 catch (Exception e) {
395 throw new IllegalArgumentException(
"Can't open file \"" + fileName +
"\" for input.\n"
396 +
"(Error :" + e +
")");
402 catch (Exception e) {
431 fileDialog.setDialogTitle(
"Select File for Input");
433 if (option != JFileChooser.APPROVE_OPTION)
435 File selectedFile =
fileDialog.getSelectedFile();
436 BufferedReader newin;
438 newin =
new BufferedReader(
new FileReader(selectedFile) );
440 catch (Exception e) {
441 throw new IllegalArgumentException(
"Can't open file \"" + selectedFile.getName() +
"\" for input.\n"
442 +
"(Error :" + e +
")");
448 catch (Exception e) {
470 catch (Exception e) {
486 if (outputStream ==
null)
499 if (outputStream ==
null)
524 if (fileName ==
null)
529 newout =
new PrintWriter(
new FileWriter(fileName));
531 catch (Exception e) {
532 throw new IllegalArgumentException(
"Can't open file \"" + fileName +
"\" for output.\n"
533 +
"(Error :" + e +
")");
539 catch (Exception e) {
563 fileDialog.setDialogTitle(
"Select File for Output");
567 if (option != JFileChooser.APPROVE_OPTION)
570 if (selectedFile.exists()) {
571 int response = JOptionPane.showConfirmDialog(
console,
572 "The file \"" + selectedFile.getName() +
"\" already exists. Do you want to replace it?",
573 "Replace existing file?",
574 JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
575 if (response == JOptionPane.YES_OPTION)
584 newout =
new PrintWriter(
new FileWriter(selectedFile));
586 catch (Exception e) {
587 throw new IllegalArgumentException(
"Can't open file \"" + selectedFile.getName() +
"\" for output.\n"
588 +
"(Error :" + e +
")");
594 catch (Exception e) {
630 public void put(Object x) {
633 if (
out.checkError())
648 public void put(Object x,
int minChars) {
652 out.printf(
"%" + minChars +
"s", x);
655 if (
out.checkError())
665 if (
out.checkError())
672 public void putln(Object x,
int minChars) {
676 if (
out.checkError())
686 if (
out.checkError())
699 public void putf(String format, Object... items) {
701 throw new IllegalArgumentException(
"Null format string in TextIO.putf() method.");
703 out.printf(format,items);
705 catch (IllegalFormatException e) {
706 throw new IllegalArgumentException(
"Illegal format string in TextIO.putf() method.");
709 if (
out.checkError())
721 return peek() ==
'\n';
764 while (ch !=
EOF && ch !=
'\n' && Character.isWhitespace(ch)) {
778 while (ch !=
EOF && Character.isWhitespace(ch)) {
916 StringBuffer s =
new StringBuffer(100);
952 return (
int)
readInteger(Integer.MIN_VALUE, Integer.MAX_VALUE);
962 return readInteger(Long.MIN_VALUE, Long.MAX_VALUE);
988 "Real number in the range " + (-Float.MAX_VALUE) +
" to " + Float.MAX_VALUE);
992 x = Float.parseFloat(str);
994 catch (NumberFormatException e) {
995 errorMessage(
"Illegal floating point input, " + str +
".",
996 "Real number in the range " + (-Float.MAX_VALUE) +
" to " + Float.MAX_VALUE);
999 if (Float.isInfinite(x)) {
1000 errorMessage(
"Floating point input outside of legal range, " + str +
".",
1001 "Real number in the range " + (-Float.MAX_VALUE) +
" to " + Float.MAX_VALUE);
1023 "Real number in the range " + (-Double.MAX_VALUE) +
" to " + Double.MAX_VALUE);
1027 x = Double.parseDouble(str);
1029 catch (NumberFormatException e) {
1030 errorMessage(
"Illegal floating point input, " + str +
".",
1031 "Real number in the range " + (-Double.MAX_VALUE) +
" to " + Double.MAX_VALUE);
1034 if (Double.isInfinite(x)) {
1035 errorMessage(
"Floating point input outside of legal range, " + str +
".",
1036 "Real number in the range " + (-Double.MAX_VALUE) +
" to " + Double.MAX_VALUE);
1055 StringBuffer str =
new StringBuffer(50);
1057 while (ch ==
EOF || !Character.isWhitespace(ch)) {
1061 return str.toString();
1074 boolean ans =
false;
1077 if ( s.equalsIgnoreCase(
"true") || s.equalsIgnoreCase(
"t") ||
1078 s.equalsIgnoreCase(
"yes") || s.equalsIgnoreCase(
"y") ||
1083 else if ( s.equalsIgnoreCase(
"false") || s.equalsIgnoreCase(
"f") ||
1084 s.equalsIgnoreCase(
"no") || s.equalsIgnoreCase(
"n") ||
1091 "one of: true, false, t, f, yes, no, y, n, 0, or 1");
1135 "Integer in the range " + min +
" to " + max);
1138 String str = s.toString();
1140 x = Long.parseLong(str);
1142 catch (NumberFormatException e) {
1144 "Integer in the range " + min +
" to " + max);
1147 if (x < min || x > max) {
1148 errorMessage(
"Integer input outside of legal range, " + str +
".",
1149 "Integer in the range " + min +
" to " + max);
1165 out.print(
" *** Error in input: " +
message +
"\n");
1166 out.print(
" *** Expecting: " + expecting +
"\n");
1167 out.print(
" *** Discarding Input: ");
1169 out.print(
"(end-of-line)\n\n");
1175 out.print(
"Please re-enter: ");
1180 throw new IllegalArgumentException(
"Too many input consecutive input errors on standard input.");
1183 throw new IllegalArgumentException(
"Error while reading from file \"" +
inputFileName +
"\":\n"
1184 +
message +
"\nExpecting " + expecting);
1186 throw new IllegalArgumentException(
"Error while reading from inptu stream:\n"
1187 +
message +
"\nExpecting " + expecting);
1205 throw new IllegalArgumentException(
"Attempt to read past end-of-file in standard input???");
1207 throw new IllegalArgumentException(
"Attempt to read past end-of-file in file \"" +
inputFileName +
"\".");
1217 catch (Exception e) {
1221 throw new IllegalArgumentException(
"Error while reading standard input???");
1223 throw new IllegalArgumentException(
"Error while attempting to read from file \"" +
inputFileName +
"\".");
1225 throw new IllegalArgumentException(
"Errow while attempting to read form an input stream.");
1238 java.lang.System.err.println(
"Error occurred in TextIO while writing to standard output!!");
1242 throw new IllegalArgumentException(
"Too many errors while writing to standard output.");
1246 throw new IllegalArgumentException(
"Error occurred while writing to file \""
1250 throw new IllegalArgumentException(
"Error occurred while writing to output stream:\n " +
message);
1265 JScrollBar scroller;
1266 BufferedReader inputStream;
1267 PrintWriter outputStream;
1272 volatile boolean doingInput;
1273 volatile String inputBuffer;
1274 volatile boolean cursorOn =
true;
1275 volatile int inputStartLine, inputStartColumn;
1276 volatile String typeAheadBuffer =
"";
1277 FontMetrics fontMetrics;
1280 final int MARGIN = 6;
1281 final Color CURSOR_COLOR =
new Color(200,0,0);
1285 f =
new Font(
"Monospaced",Font.PLAIN,f.getSize());
1287 fontMetrics = getFontMetrics(f);
1288 lineSkip = (int)(fontMetrics.getHeight() * 1.2);
1289 charWidth = fontMetrics.charWidth(
'W');
1290 setPreferredSize(
new Dimension(2*MARGIN + 80*charWidth, 2*MARGIN + (25-1)*lineSkip + fontMetrics.getAscent() + fontMetrics.getDescent()));
1291 setBackground(Color.WHITE);
1292 setForeground(Color.BLACK);
1293 setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY, 3));
1294 addFocusListener(
new FocusListener() {
1295 public void focusLost(FocusEvent evt) {
1296 setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY,3));
1298 public void focusGained(FocusEvent evt) {
1299 setBorder(BorderFactory.createLineBorder(Color.CYAN,3));
1302 addMouseListener(
new MouseAdapter() {
1303 public void mousePressed(MouseEvent evt) {
1307 addKeyListener(
new KeyAdapter() {
1308 public void keyTyped(KeyEvent evt) {
1309 char ch = evt.getKeyChar();
1310 if (ch == KeyEvent.CHAR_UNDEFINED)
1313 typeAheadBuffer += ch;
1322 lines =
new String[2000];
1325 scroller =
new JScrollBar(JScrollBar.VERTICAL,0,80,0,80);
1326 scroller.setEnabled(
false);
1327 scroller.addAdjustmentListener(
new AdjustmentListener() {
1328 public void adjustmentValueChanged(AdjustmentEvent evt) {
1329 topLine = scroller.getValue();
1333 inputStream =
new BufferedReader(
new CIN());
1334 outputStream =
new PrintWriter(
new COUT());
1338 super.paintComponent(g);
1340 columns = (getWidth() - 2*MARGIN + 1) / charWidth;
1341 rows = 1 + (getHeight() - 2*MARGIN - fontMetrics.getAscent()) / lineSkip;
1342 scroller.setBlockIncrement(rows - 2);
1345 for (
int i = topLine; i < topLine + rows && i < lineCount; i++)
1346 g.drawString(lines[i],MARGIN,MARGIN+(i-topLine)*lineSkip + fontMetrics.getAscent());
1347 if (doingInput && cursorOn) {
1348 g.setColor(CURSOR_COLOR);
1349 int x = MARGIN + fontMetrics.stringWidth(lines[lineCount-1])+1;
1350 int y1 = MARGIN + (lineCount-1-topLine)*lineSkip + fontMetrics.getAscent() + fontMetrics.getDescent();
1351 int y2 = y1 - fontMetrics.getAscent() - fontMetrics.getDescent();
1352 g.drawLine(x,y1,x,y2);
1353 g.drawLine(x+1,y1,x+1,y2);
1357 synchronized void newLine() {
1362 catch (InterruptedException e) {
1364 if (lineCount == lines.length) {
1365 for (
int i = 0; i < lines.length-1; i++)
1366 lines[i] = lines[i+1];
1367 lines[lines.length-1] =
"";
1372 lines[lineCount] =
"";
1378 synchronized void putChar(
char ch) {
1386 if (!Character.isDefined(ch) || Character.isISOControl(ch))
1388 if (columns > 0 && lines[lineCount-1].length() >= columns)
1390 lines[lineCount-1] += ch;
1393 synchronized void deleteChar() {
1396 if (inputStartLine == lineCount-1 && inputStartColumn >= lines[lineCount-1].length())
1398 if (lines[lineCount-1].length() > 0)
1399 lines[lineCount-1] = lines[lineCount-1].substring(0,lines[lineCount-1].length()-1);
1407 for (
int i = 0; i < str.length(); i++)
1408 putChar(str.charAt(i));
1413 void scrollToEnd() {
1416 if (lineCount <= rows) {
1418 scroller.setEnabled(
false);
1421 topLine = lineCount - rows;
1422 scroller.setEnabled(
true);
1424 scroller.setValues(topLine,rows,0,rows+topLine);
1427 synchronized void doInputChar(
char ch) {
1429 if (ch == 8 || ch == 127) {
1431 if (inputBuffer.length() > 0)
1432 inputBuffer = inputBuffer.substring(0,inputBuffer.length()-1);
1434 else if (ch == 13 || ch == 10) {
1442 if (Character.isDefined(ch) && ! Character.isISOControl(ch))
1449 synchronized void clearTypeAhead() {
1450 typeAheadBuffer =
"";
1453 synchronized void clear() {
1464 throw new AbortException();
1467 class CIN
extends Reader {
1470 public void close() {
1472 public int read(
char[] b,
int offset,
int length)
throws IOException {
1477 b[offset + ct] = (char)ch;
1487 synchronized(Console.this) {
1488 inputStartLine = lineCount - 1;
1489 inputStartColumn = lines[lineCount-1].length();
1493 while (typeAheadBuffer.length() > 0) {
1494 ch = typeAheadBuffer.charAt(0);
1495 typeAheadBuffer = typeAheadBuffer.substring(1);
1496 if (ch == 13 || ch == 10)
1501 Console.this.wait(25);
1503 catch (InterruptedException e) {
1506 if (ch != 13 && ch != 10) {
1510 while (doingInput) {
1512 Console.this.wait(300);
1513 cursorOn = !cursorOn;
1516 catch (InterruptedException e) {
1525 buffer = inputBuffer + (char)10;
1532 class COUT
extends Writer {
1533 public void write(
int b) {
1534 write(
new char[] { (char)(b & 0xFFFF) }, 0, 1);
1536 public void write(
char[] b,
int offset,
int length) {
1537 for (
int i = offset; i < offset+length; i++) {
1541 public void write(
char[] b) {
1542 write(b,0,b.length);
1544 public void close() {
1546 public void flush() {
1562 private BufferedReader
in;
1574 private final Pattern
floatRegex = Pattern.compile(
"(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))((e|E)(\\+|-)?[0-9]+)?");