📄 textio.java
字号:
integerMatcher = null; } private static void emptyBuffer() { // discard the rest of the current line of input buffer = null; } private static void outputError(String message) { // Report an error on output. if (writingStandardOutput) { System.err.println("Error occurred in TextIO while writing to standard output!!"); outputErrorCount++; if (outputErrorCount >= 10) { outputErrorCount = 0; throw new IllegalArgumentException("Too many errors while writing to standard output."); } } else if (outputFileName != null){ throw new IllegalArgumentException("Error occurred while writing to file \"" + outputFileName+ "\":\n " + message); } else { throw new IllegalArgumentException("Error occurred while writing to output stream:\n " + message); } } // ******************************* Defining the GUI *************************************** /** * A "Console" is a panel which simulates standard input/output. When this GUI TextIO class is used, * a frame will be opened that displays a Console. When the output destination for TextIO is standard * output, the output will appear in the window. When TextIO wants to fill its buffer with a line of input * from standard input, the user will type a line of input in the Console, which will go into the buffer. * There is also a scroll bar that can be used to browse lines that have scorlled off the top (up to 2000 lines). */ private static class Console extends JPanel { JScrollBar scroller; BufferedReader inputStream; PrintWriter outputStream; String[] lines; int topLine; int lineCount; int rows, columns; volatile boolean doingInput; volatile String inputBuffer; volatile boolean cursorOn = true; volatile int inputStartLine, inputStartColumn; volatile String typeAheadBuffer = ""; FontMetrics fontMetrics; int lineSkip; int charWidth; final static int MARGIN = 6; final static Color CURSOR_COLOR = new Color(200,0,0); Console() { int screenResolution = Toolkit.getDefaultToolkit().getScreenResolution(); Font f = getFont(); int points = f.getSize(); int newpoints = Math.max(points, (int)(0.5 + screenResolution / 6)); f = new Font("Monospaced", Font.PLAIN, newpoints); fontMetrics = getFontMetrics(f); if (points != newpoints && fontMetrics.getHeight() * 1.2 * 5 > screenResolution) { f = new Font("Monospaced", Font.PLAIN, points); fontMetrics = getFontMetrics(f); } lineSkip = (int)(fontMetrics.getHeight() * 1.2); charWidth = fontMetrics.charWidth('W'); setFont(f); setPreferredSize(new Dimension(2*MARGIN + 80*charWidth, 2*MARGIN + (25-1)*lineSkip + fontMetrics.getAscent() + fontMetrics.getDescent())); setBackground(Color.WHITE); setForeground(Color.BLACK); setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY, 3)); addFocusListener( new FocusListener() { public void focusLost(FocusEvent evt) { setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY,3)); } public void focusGained(FocusEvent evt) { setBorder(BorderFactory.createLineBorder(Color.CYAN,3)); } } ); addMouseListener( new MouseAdapter() { public void mousePressed(MouseEvent evt) { requestFocus(); } } ); addKeyListener( new KeyAdapter() { public void keyTyped(KeyEvent evt) { char ch = evt.getKeyChar(); if (ch == KeyEvent.CHAR_UNDEFINED) return; if (!doingInput) { typeAheadBuffer += ch; return; } synchronized(Console.this) { doInputChar(ch); Console.this.notify(); } } } ); lines = new String[2000]; lineCount = 1; lines[0] = ""; scroller = new JScrollBar(JScrollBar.VERTICAL,0,80,0,80); scroller.setEnabled(false); scroller.addAdjustmentListener( new AdjustmentListener() { public void adjustmentValueChanged(AdjustmentEvent evt) { topLine = scroller.getValue(); repaint(); } }); inputStream = new BufferedReader(new CIN()); outputStream = new PrintWriter(new COUT()); } public void paintComponent(Graphics g) { super.paintComponent(g); if (rows == 0) { columns = (getWidth() - 2*MARGIN + 1) / charWidth; rows = 1 + (getHeight() - 2*MARGIN - fontMetrics.getAscent()) / lineSkip; scroller.setBlockIncrement(rows - 2); scrollToEnd(); } for (int i = topLine; i < topLine + rows && i < lineCount; i++) g.drawString(lines[i],MARGIN,MARGIN+(i-topLine)*lineSkip + fontMetrics.getAscent()); if (doingInput && cursorOn) { g.setColor(CURSOR_COLOR); int x = MARGIN + fontMetrics.stringWidth(lines[lineCount-1])+1; int y1 = MARGIN + (lineCount-1-topLine)*lineSkip + fontMetrics.getAscent() + fontMetrics.getDescent(); int y2 = y1 - fontMetrics.getAscent() - fontMetrics.getDescent(); g.drawLine(x,y1,x,y2); g.drawLine(x+1,y1,x+1,y2); } } synchronized void newLine() { try { Thread.sleep(20); } catch (InterruptedException e) { } if (lineCount == lines.length) { for (int i = 0; i < lines.length-1; i++) lines[i] = lines[i+1]; lines[lines.length-1] = ""; if (doingInput) inputStartLine--; } else { lines[lineCount] = ""; lineCount++; } scrollToEnd(); repaint(); } synchronized void putChar(char ch) { if (ch == '\n') { newLine(); return; } if (ch == '\t') ch = ' '; if (!Character.isDefined(ch) || Character.isISOControl(ch)) return; if (columns > 0 && lines[lineCount-1].length() >= columns) newLine(); lines[lineCount-1] += ch; } synchronized void deleteChar() { if (lineCount == 0) return; if (inputStartLine == lineCount-1 && inputStartColumn >= lines[lineCount-1].length()) return; if (lines[lineCount-1].length() > 0) lines[lineCount-1] = lines[lineCount-1].substring(0,lines[lineCount-1].length()-1); else { lineCount--; scrollToEnd(); } } void scrollToEnd() { if (rows == 0) return; if (lineCount <= rows) { topLine = 0; scroller.setEnabled(false); } else { topLine = lineCount - rows; scroller.setEnabled(true); } scroller.setValues(topLine,rows,0,rows+topLine); } synchronized void doInputChar(char ch) { if (ch == 8 || ch == 127) { deleteChar(); if (inputBuffer.length() > 0) inputBuffer = inputBuffer.substring(0,inputBuffer.length()-1); } else if (ch == 13 || ch == 10) { newLine(); doingInput = false; } else { putChar(ch); if (ch == '\t') ch = ' '; if (Character.isDefined(ch) && ! Character.isISOControl(ch)) inputBuffer += ch; } scrollToEnd(); repaint(); } synchronized void clearTypeAhead() { typeAheadBuffer = ""; } class CIN extends Reader { // "Standard input" is replaced in TextIO with an object of this type. String buffer; int pos; public void close() { } public int read(char[] b, int offset, int length) throws IOException { int ct = 0; int ch; do { ch = read(); b[offset + ct] = (char)ch; ct++; } while (ch != 10); return ct; } public int read() { if (buffer != null && pos < buffer.length()) { pos++; return buffer.charAt(pos-1); } synchronized(Console.this) { inputStartLine = lineCount - 1; inputStartColumn = lines[lineCount-1].length(); char ch = 0; scrollToEnd(); inputBuffer = ""; while (typeAheadBuffer.length() > 0) { ch = typeAheadBuffer.charAt(0); typeAheadBuffer = typeAheadBuffer.substring(1); if (ch == 13 || ch == 10) break; doInputChar(ch); repaint(); try { Console.this.wait(25); } catch (InterruptedException e) { } } if (ch != 13 && ch != 10) { doingInput = true; cursorOn = true; requestFocus(); while (doingInput) { try { Console.this.wait(300); cursorOn = !cursorOn; repaint(); } catch (InterruptedException e) { cursorOn = true; repaint(); } } cursorOn = false; repaint(); } buffer = inputBuffer + (char)10; pos = 1; return buffer.charAt(0); } } } class COUT extends Writer { // "Standard output" is replaced in TextIO with an object of this type. public void write(int b) { write(new char[] { (char)(b & 0xFFFF) }, 0, 1); } public void write(char[] b, int offset, int length) { for (int i = offset; i < offset+length; i++) { putChar(b[i]); } } public void write(char[] b) { write(b,0,b.length); } public void close() { } public void flush() { } } } // end nested class Console static { // static initializer opens the GUI TextIO window. JFrame frame = new JFrame("TextIO Console"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); console = new Console(); in = standardInput = console.inputStream; out = standardOutput = console.outputStream; JPanel panel = new JPanel(); panel.setLayout(new BorderLayout(2,2)); panel.setBackground(Color.GRAY); panel.setBorder(BorderFactory.createLineBorder(Color.GRAY,2)); panel.add(console,BorderLayout.CENTER); panel.add(console.scroller,BorderLayout.EAST); frame.setContentPane(panel); frame.pack(); frame.setResizable(false); Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); frame.setLocation( (screenSize.width - frame.getWidth())/2, (screenSize.height - frame.getHeight())/2 ); frame.setVisible(true); console.requestFocus(); }} // end of class TextIO
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -