Rambler's Top100

Исходный файл TextEdit.java (все изменения выделены):

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.Enumeration;
import L2List;
import ListException;
/**
 * Simple text editor.
 */
public class TextEdit extends Frame {
    Text text;              // Text storage
    EditField editField;    // Client area of frame window
    int cursorX = 0;        // Cursor position
    int cursorY = 0;
    int windowX = 0;        // Window position in text
    int windowY = 0;
    int windowWidth = 80;   // Window size in characters (dx, dy)
    int windowHeight = 24;
    int lastCommand = 0;    // The last key pressed
    Font textFont = new Font("Courier", Font.PLAIN, 14);    // Text font
    // Font metric (we use a fixed width font!)
    int dx = 0;         // Maximal character advance (width)
    int ascent = 0;     // Character ascent
    int descent = 0;    // Character descent
    int leading = 0;    // Interline skip
    int dy = 0;         // Font height = ascent + descent + leading
    int margin = 4;     // Top and left margin
    Color fgColor = Color.black;        // Foreground color
    Color bgColor = Color.lightGray;    // Background color
    String fileName = "noname.txt";
    boolean fileNameSet = false;
    boolean textChanged = false;
    String endOfText = "[* End of text *]"; // "End of text" line
    boolean inputDisabled = false;
    boolean saveText = false;
    public static void main(String[] args) {
        TextEdit editor = new TextEdit();
        if (args.length >= 1) {
            editor.fileName = args[0];
            editor.fileNameSet = true;
            editor.text.load(editor.fileName);
            editor.setTitle(editor.fileName);
        }
        editor.setVisible(true);
        editor.editField.requestFocus();
    }
    public TextEdit() {
        text = new Text();
        editField = new EditField();
        editField.setFont(textFont);
        setBackground(bgColor);
        setForeground(fgColor);
        add("Center", editField);
        WindowAdapter wa = new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                onQuit();
            }
            public void windowActivated(WindowEvent e) {
                editField.requestFocus();
            }
        };
        addWindowListener(wa);
        // Add menu bar
        final MenuBar mb = new MenuBar();
        setMenuBar(mb);
        final Menu fileMenu = new Menu("File");
//
//---------------------------------------------------------------------
        final MenuItem openItem = new MenuItem("Open...");
//---------------------------------------------------------------------
//
        final MenuItem saveItem = new MenuItem("Save");
        final MenuItem saveAsItem = new MenuItem("Save as...");
        final MenuItem quitItem = new MenuItem("Quit");
//
//---------------------------------------------------------------------
        fileMenu.add(openItem);   
//---------------------------------------------------------------------
//
        fileMenu.add(saveItem);
        fileMenu.add(saveAsItem);
        fileMenu.add(quitItem);
        mb.add(fileMenu);
        ActionListener al = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                String command = e.getActionCommand();
//
//----------------------------------------------------------------------
                if (command.equals("Open...")) {
                    onOpen();
//----------------------------------------------------------------------
//
                } else if (command.equals("Save")) {
                    onSave();
                } else if (command.equals("Save as...")) {
                    onSaveAs();
                } else if (command.equals("Quit")) {
                    onQuit();
                }
                editField.requestFocus();
            }
        };
        fileMenu.addActionListener(al);
        //... pack();
        setSize(
            600,
            400
        );
        setTitle(fileName);
        setBackground(bgColor);
        setForeground(fgColor);
        KeyAdapter ka = new KeyAdapter() {
            public void keyPressed(KeyEvent e) {
                onKeyPressed(e);
            }
        };
        addKeyListener(ka);
        editField.addKeyListener(ka);
        // Processing of resize events
        ComponentAdapter ca = new ComponentAdapter() {
            public void componentResized(ComponentEvent e) {
                onResize();
                editField.requestFocus();
            }
            public void componentShown(ComponentEvent e) {
                editField.requestFocus();
            }
        };
        editField.addComponentListener(ca);
    }
    void onKeyPressed(KeyEvent e) {
        if (inputDisabled) return;
        //... System.out.println("KeyPressed: " + e);
        int keyCode = e.getKeyCode();
        char keyChar = e.getKeyChar();
        // Remove old cursor.
        drawCursor(cursorX, cursorY, false);
        if (e.isActionKey()) {
            // Action key
            //... System.out.println("Action key: " + e.getKeyText(e.getKeyCode()));
            if (keyCode == KeyEvent.VK_DOWN) {
                onDown();
            } else if (keyCode == KeyEvent.VK_UP) {
                onUp();
            } else if (keyCode == KeyEvent.VK_LEFT) {
                onLeft();
            } else if (keyCode == KeyEvent.VK_RIGHT) {
                onRight();
            } else if (keyCode == KeyEvent.VK_HOME) {
                onHome();
            } else if (keyCode == KeyEvent.VK_END) {
                onEnd();
            }
        } else if ((e.getModifiers() & InputEvent.CTRL_MASK) != 0) {
            // Ctrl-key
            //... System.out.println("Ctrl+" + e.getKeyText(e.getKeyCode()));
            if (keyCode == KeyEvent.VK_K) { // Ctrl+K
                onDeleteLine();
            } else if (keyCode == KeyEvent.VK_L) { // Ctrl+K
                onInsertLine();
            } else if (keyCode == KeyEvent.VK_S) { // Ctrl+S
                onSave();
            } else if (keyCode == KeyEvent.VK_Q) { // Ctrl+Q
                onQuit();
            }
        } else if (keyCode == KeyEvent.VK_ENTER) {
            //... System.out.println(e.getKeyText(e.getKeyCode()));
            onEnter();
        } else if (keyCode == KeyEvent.VK_BACK_SPACE) {
            //... System.out.println(e.getKeyText(e.getKeyCode()));
            onBackSpace();
        } else if (keyChar != KeyEvent.CHAR_UNDEFINED) {
            onCharTyped(keyChar);
        }
        if (cursorX < 0) cursorX = 0;
        if (cursorY < 0) cursorY = 0;
        // Scroll a window, if necessary
        if (
            cursorX < windowX || cursorX > windowX + windowWidth - 1 ||
            cursorY < windowY || cursorY > windowY + windowHeight - 1
        ) {
            // Cursor is removed at the moment!
            // scrollToCursor() will draw it again.
            scrollToCursor();
        }
        drawCursor(cursorX, cursorY, true);
        editField.requestFocus();
    }
    void scrollToCursor() {
        // Remove cursor for a moment
        drawCursor(cursorX, cursorY, false);
        if (cursorX < windowX) {
            scrollLeft(windowX - cursorX);
        } else if (cursorX > windowX + windowWidth - 1) {
            scrollRight(cursorX - (windowX + windowWidth - 1));
        }
        if (cursorY < windowY) {
            scrollUp(windowY - cursorY);
        } else if (cursorY > windowY + windowHeight - 1) {
            scrollDown(cursorY - (windowY + windowHeight - 1));
        }
        // Restore cursor
        drawCursor(cursorX, cursorY, true);
    }
    void scrollLeft(int n) {
        inputDisabled = true;
        if (n > windowX) n = windowX;
        windowX -= n;
        if (n > windowWidth / 2) editField.repaint();
        else {
            Graphics g = editField.getGraphics();
            Rectangle r = editField.getBounds();
            if (g != null) {
                int shift = dx * n;
                g.copyArea(
                    margin, margin,
                    windowWidth * dx - shift, (windowHeight + 1) * dy,
                    shift, 0
                );
                inputDisabled = true;
                editField.repaint(
                    0, margin,
                    shift + margin, (windowHeight + 1) * dy
                );
            } else {
                editField.repaint();
            }
        }
    }
    void scrollRight(int n) {
        if (n == 0) return;
        inputDisabled = true;
        windowX += n;
        if (n > windowWidth / 2) editField.repaint();
        else {
            Graphics g = editField.getGraphics();
            if (g != null) {
                int shift = dx * n;
                g.copyArea(
                    margin + shift, margin,
                    windowWidth * dx - shift, windowHeight * dy,
                    -shift, 0
                );
                inputDisabled = true;
                editField.repaint(
                    margin + windowWidth * dx - shift, 0,
                    shift, windowHeight * dy
                );
            } else {
                editField.repaint();
            }
        }
    }
    void scrollUp(int n) {
        if (n == 0) return;
        inputDisabled = true;
        if (n > windowY) n = windowY;
        windowY -= n;
        if (n > windowHeight / 2) editField.repaint();
        else {
            Graphics g = editField.getGraphics();
            Rectangle r = editField.getBounds();
            if (g != null) {
                int shift = dy * n;
                g.copyArea(
                    margin, margin,
                    windowWidth * dx, windowHeight * dy - shift,
                    0, shift
                );
                inputDisabled = true;
                editField.repaint(
                    margin, margin,
                    margin + windowWidth * dx, shift
                );
            } else {
                editField.repaint();
            }
        }
    }
    void scrollDown(int n) {
        inputDisabled = true;
        windowY += n;
        if (n > windowHeight / 2) editField.repaint();
        else {
            Graphics g = editField.getGraphics();
            if (g != null) {
                int shift = dy * n;
                g.copyArea(
                    margin, margin + shift,
                    windowWidth * dx, windowHeight * dy - shift,
                    0, -shift
                );
                inputDisabled = true;
                editField.repaint(
                    margin, margin + windowHeight * dy - shift,
                    windowWidth * dx, shift
                );
            } else {
                editField.repaint();
            }
        }
    }
    void drawCursor(Graphics g, int cx, int cy, boolean on) {
        if (cx >= windowX + windowWidth || cy >= windowY + windowHeight)
            return;
        if (g != null) {
            if (on) g.setColor(fgColor);
            else    g.setColor(bgColor);
            int x = margin + (cx - windowX) * dx;
            int y = margin + (cy - windowY) * dy;
            g.fillRect(
                x, y,
                dx, ascent + descent
            );
            if (on) g.setColor(bgColor);
            else    g.setColor(fgColor);
            if (cy <= text.size()) {
                String line;
                if (cy == text.size()) {
                    line = endOfText;
                } else {
                    text.setPointer(cy);
                    line = (String) text.elementAfter();
                }
                if (cx < line.length()) {
                    g.drawString(
                        line.substring(cx, cx + 1),
                        x, y + ascent
                    );
                }
            }
            g.setColor(fgColor);
        }
    }
    void drawCursor(int cx, int cy, boolean on) {
        drawCursor(editField.getGraphics(), cx, cy, on);
    }
    void onDown(){
        if (cursorY < text.size())
            cursorY++;
    }
    void onUp(){
        if (cursorY > 0) cursorY--;
    }
    void onLeft(){
        if (cursorX > 0) cursorX--;
    }
    void onRight(){
        cursorX++;
    }
    void onHome(){
        cursorX = 0;
    }
    void onEnd(){
        if (cursorY < text.size()) {
            String line = text.getLine(cursorY);
            cursorX = line.length();
        } else {
            cursorX = 0;
        }
    }
    void onDeleteLine(){
        if (cursorY < text.size()) {
            text.setPointer(cursorY);
            text.removeAfter();
            redraw(0, cursorY, Integer.MAX_VALUE, Integer.MAX_VALUE);
            textChanged = true;
        }
    }
    void onInsertLine(){
        text.setPointer(cursorY);
        text.addAfter("");
        redraw(0, cursorY, Integer.MAX_VALUE, Integer.MAX_VALUE);
        textChanged = true;
    }
    void onEnter(){
        text.setPointer(cursorY);
        if (cursorY >= text.size()) {
            text.addAfter("");
        } else {
            String line = (String) text.elementAfter();
            if (cursorX >= line.length()) {
                text.moveForward();
                text.addAfter("");
            } else {
                // Cut line into 2 pieces
                text.setElementAfter(line.substring(0, cursorX));
                text.moveForward();
                text.addAfter(line.substring(cursorX));
            }
        }
        cursorX = 0;
        cursorY++;
        scrollToCursor();
        redraw(0, cursorY - 1, Integer.MAX_VALUE, Integer.MAX_VALUE);
        textChanged = true;
    }
    void onBackSpace(){
        if (cursorX <= 0 || cursorY >= text.size()) return;
        text.setPointer(cursorY);
        String line = (String) text.elementAfter();
        if (cursorX <= line.length()) {
            String l = line.substring(0, cursorX - 1) +
                       line.substring(cursorX);
            text.setElementAfter(l);
        }
        cursorX--;
        redraw(cursorX, cursorY, Integer.MAX_VALUE, 1);
        textChanged = true;
    }
    void onDelete(){
        if (cursorX < 0 || cursorY >= text.size()) return;
        text.setPointer(cursorY);
        String line = (String) text.elementAfter();
        if (cursorX < line.length()) {
            String l = line.substring(0, cursorX) +
                       line.substring(cursorX + 1);
            text.setElementAfter(l);
        }
        redraw(cursorX, cursorY, Integer.MAX_VALUE, 1);
        textChanged = true;
    }
    void onCharTyped(char c) {
        //... System.out.println("Char typed: " + c + " code: " + (int)c);
        if ((int)c == 0x7f) {
            onDelete(); return;
        }
        if (cursorY == text.size()) onInsertLine();
               text.setPointer(cursorY);
               String line = (String) text.elementAfter();
        String l;
        if (cursorX < line.length()) {
            l = line.substring(0, cursorX);
            l += c;
            l += line.substring(cursorX);
        } else if (cursorX == line.length()) {
            l = line;
            l += c;
        } else {
            int n = cursorX - line.length();
            l = line;
            while (n > 0) {
                l += ' '; n--;
            }
            l += c;
        }
        text.setElementAfter(l);
        cursorX++;
        scrollToCursor();
        redraw(cursorX - 1, cursorY, Integer.MAX_VALUE, 1);
        textChanged = true;
    }
//
//-----------------------------------------------------------------
    void onOpen() {
        FileDialog fd = new FileDialog((Frame) this, "Open File", FileDialog.LOAD);
        if (textChanged) {
            SaveDialog sd = new SaveDialog(this);
            sd.setVisible(true);    // Modal dialog
            if (saveText) onSave();
            saveText = false;
        }
        fd.setVisible(true);
        editField.requestFocus();
        String file = fd.getFile();
        String directory = fd.getDirectory();
        if (file == null || directory == null) return;
        if (directory.length() > 0) {
            char lastChar = directory.charAt(directory.length() - 1);
            if (lastChar != '/' && lastChar != '\\') directory += '/';
        }
        fileName = directory + file;
        fileNameSet = true;
        textChanged = false;
        text.load(fileName);
        setTitle(fileName);
        cursorX = 0;
        cursorY = 0;
        redraw(0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE);
    }
//------------------------------------------------------------------
//
    // Redraw a rectangle in a text
    void redraw(int x, int y, int w, int h) {
        int x1 = x + w;
        if (w == Integer.MAX_VALUE) x1 = Integer.MAX_VALUE;
        int y1 = y + h;
        if (h == Integer.MAX_VALUE) y1 = Integer.MAX_VALUE;
        int x0 = x;
        if (x0 < windowX) x0 = windowX;
        int y0 = y;
        if (y0 < windowY) y0 = windowY;
        if (x1 > windowX + windowWidth) x1 = windowX + windowWidth;
        if (y1 > windowY + windowHeight) y1 = windowY + windowHeight;
        if (x1 <= x || y1 <= y) return;
        int left = margin + (x0 - windowX) * dx;
        int top = margin + (y0 - windowY) * dy;
        int width = (x1 - x0) * dx;
        int height = (y1 - y0) * dy;
        Rectangle r = editField.getBounds();
        if (left + width > r.width) width -= (left + width - r.width);
        if (top + height > r.height) height -= (top + height - r.height);
        editField.repaint(left, top, width, height);
    }
    void onSave() {
        if (fileNameSet) {
            if (text.save(fileName)) textChanged = false;
        } else {
            onSaveAs();
        }
    }
    void onSaveAs() {
        FileDialog fd = new FileDialog(
            (Frame) this, "Save File", FileDialog.SAVE
        );
        if (fileNameSet)
            fd.setFile(fileName);
        fd.setVisible(true);
        String file = fd.getFile();
        String directory = fd.getDirectory();
        if (file == null || directory == null) return;
        //... System.out.println("Selected file = " + file + ", directory = " + directory);
        String oldFileName = fileName;
        if (directory.length() > 0) {
            char lastChar = directory.charAt(directory.length() - 1);
            if (lastChar != '/' && lastChar != '\\') directory += '/';
        }
        fileName = directory + file;
        if (text.save(fileName) &&
            (!fileNameSet || oldFileName.equals(fileName))) {
            textChanged = false;
        }
        if (!fileNameSet) {
            fileNameSet = true;
            setTitle(fileName);
        }
        else fileName = oldFileName;
    }
    void onQuit() {
        if (textChanged) {
            SaveDialog sd = new SaveDialog(this);
            sd.setVisible(true);    // Modal dialog
            if (saveText) {
                onSave();
            }
            saveText = false;
        }
        setVisible(false);
        dispose();
        System.exit(0);
    }
    void initFontMetric(Graphics g) {
        FontMetrics fm = g.getFontMetrics();
        //... dx = fm.getMaxAdvance();  // Maximal character advance (width)
        dx = fm.charWidth('W');         // Maximal character advance (width)
        dy = fm.getHeight();
        ascent = fm.getAscent();
        descent = fm.getDescent();
        leading = fm.getLeading();
    }
    class EditField extends Canvas {
        public void paint(Graphics g) {
            if (dx == 0) {
                initFontMetric(g);
            }
            Rectangle r = getBounds();
            g.setPaintMode();
            // Clear window
            g.setColor(bgColor);
            g.fillRect(0, 0, r.width, r.height);
            // Define window size
            windowWidth = (r.width - 2 * margin) / dx;
            windowHeight = (r.height - 2 * margin) / dy;
            g.setColor(fgColor);
            int numLines = (r.height - 2 * margin) / dy;
            for (int screenY = 0; screenY < numLines; screenY++) {
                // Draw a line
                int textY = windowY + screenY;
                String line = null;
                if (textY <= text.size()) {
                    String str;
                    if (textY == text.size()) {
                        str = endOfText;
                    } else {
                        str = text.getLine(textY);
                    }
                    if (windowX < str.length()) {
                        int endIndex = str.length();
                        if (endIndex > windowX + windowWidth)
                            endIndex = windowX + windowWidth;
                        line = str.substring(windowX, endIndex);
                    }
                }
                if (line != null) {
                    g.drawString(
                        line,
                        margin,
                        margin + ascent + dy * screenY
                    );
                }
            }
            drawCursor(g, cursorX, cursorY, true);
            inputDisabled = false;
        }
        public void update(Graphics g) { paint(g); }
    } // End of class EditField
    void onResize() {
        Rectangle r = editField.getBounds();
        if (dx != 0 && dy != 0) {
            // Define window size
            windowWidth = (r.width - margin) / dx;
            windowHeight = (r.height - margin) / dy;
            scrollToCursor();
        }
        editField.requestFocus();
    }
}
class Text extends L2List {
    static final int tabWidth = 8;
    public Text() {
        super();
    }
    public boolean load(String fileName) {
        removeAll();
        try {
            BufferedReader input = new BufferedReader(
                new FileReader(fileName)
            );
            String line;
            while ((line = input.readLine()) != null) {
                String str = convertTabs(line); // Replace tabulations by spaces
                addBefore(str);
            }
        } catch (FileNotFoundException e) {
            //... System.out.println("Cannot open a file: " + e);
            return false;
        } catch (IOException e) {
            System.out.println("Read error: " + e);
            return false;
        }
        return true;
    }
    public boolean save(String fileName) {
        try {
            BufferedWriter output = new BufferedWriter(
                new FileWriter(fileName)
            );
            Enumeration lines = elements();
            while (lines.hasMoreElements()) {
                String str = (String) lines.nextElement();
                //... System.out.println(str);
                output.write(str);
                output.newLine();
            }
            output.flush();
        } catch (Exception e) {
            System.out.println("Cannot write to file " + fileName + " " + e);
            return false;
        }
        return true;
    }
    public String getLine(int i) {
        String line = null;
        if (i < size()) {
            setPointer(i);
            line = (String) elementAfter();
        }
        return line;
    }
    private String convertTabs(String line) {
        StringBuffer str = new StringBuffer(256);
        int x = 0;
        int len = line.length();
        int i = 0;
        while (i < len) {
            char c = line.charAt(i);
            if (c == '\t') {    // Tabulation
                int spacesToAdd = tabWidth - (x % tabWidth);
                while (spacesToAdd > 0) {
                    str.append(' ');
                    x++;
                    spacesToAdd--;
                }
            } else {            // Other character
                str.append(c);
                x++;
            }
            i++;
        }
        return str.toString();
    }
}
class SaveDialog extends Dialog implements ActionListener {
    Button yes;
    Button no;
    TextEdit editor;
    public SaveDialog(Frame f) {
        super(f, true);
        editor = (TextEdit) f;
        setLayout(null);
        setFont(new Font("Helvetica", Font.BOLD, 14));
        setTitle("Save text?");
        Label l = new Label("Text was changed, save it?");
        int y = 30;
        l.setBounds(10, y, 240, 30);
        y += 40;
        add(l);
        yes = new Button("Yes");
        no  = new Button("No");
        yes.setBounds(10, y, 80, 30);
        no.setBounds(100, y, 80, 30);
        add(yes); add(no);
        yes.addActionListener(this);
        no.addActionListener(this);
        yes.requestFocus();
        setSize(250, 130);
    }
    public void actionPerformed(ActionEvent e) {
        Object source = e.getSource();
        if (source == yes) editor.saveText = true;
        else if (source == no) editor.saveText = false;
        setVisible(false);
    }
}
Хостинг от uCoz