Project: OMS3
/*
 * To change this template, choose Tools | Templates 
 * and open the template in the editor. 
 */
package ngmf.ui; 
 
import java.awt.Font; 
import java.awt.Rectangle; 
import java.awt.event.KeyAdapter; 
import java.awt.event.KeyEvent; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import java.io.IOException; 
import java.io.OutputStream; 
import java.io.PrintWriter; 
import java.io.Writer; 
import java.util.ArrayList; 
import java.util.List; 
 
import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTextArea; 
import javax.swing.text.Element; 
 
/**
 *  
 * @author od 
 */
 
public class JConsolePanel extends JTextArea { 
 
    private static final long serialVersionUID = 1L
 
    class DefaultCommandHandler implements CommandHandler { 
 
        @Override 
        public String handle(String cmd) { 
            if (cmd.equals("clear")) { 
                setText(""); 
            } else { 
                return "unknown command '" + cmd + "'\n"
            } 
            return null
        } 
    } 
 
    static class Prompt { 
 
        public String getPrompt() { 
            return "> "
        } 
    } 
 
    static class History { 
 
        List<String> cmds = new ArrayList<String>(); 
        int cursor; 
 
        public String () { 
            if (cmds.size() == 0) { 
                return null
            } 
            if (cursor < cmds.size() - 1) { 
                cursor++; 
            } 
            return cmds.get(cursor); 
        } 
 
        public String () { 
            if (cmds.size() == 0) { 
                return null
            } 
            if (cursor > 0) { 
                cursor--; 
            } 
            return cmds.get(cursor); 
        } 
 
        public void appendCommand(String command) { 
            cmds.add(command); 
            cursor = cmds.size(); 
        } 
    } 
// 
    private PrintWriter w = new PrintWriter(new Writer() { 
 
        @Override 
        public void flush() { 
        } 
 
        @Override 
        public void close() { 
        } 
 
        @Override 
        public void write(char[] cbuf, int off, int len) throws IOException { 
            JConsolePanel.this.append(new String(cbuf, off, len)); 
            setCaretPosition(getText().length()); 
            cp = getCaretPosition(); 
            JConsolePanel.this.scrollRectToVisible(new Rectangle(0, getHeight(), 11)); 
        } 
    }); 
// 
    CommandHandler cmd; 
    Prompt prompt; 
    History history; 
    int cp; 
 
    public JConsolePanel(Prompt p, CommandHandler cmd, History hist) { 
        setPromptProvider(p); 
        setCommandHandler(cmd); 
        setHistory(hist); 
 
        setText(prompt.getPrompt()); 
        cp = prompt.getPrompt().length(); 
 
        setEditable(true); 
        setLineWrap(true); 
//        setRows(3); 
//        setColumns(20); 
      
        addKeyListener(new KListener()); 
        setCaretPosition(getText().length()); 
        setFont(new Font("Monospaced"112)); 
        addMouseListener(new MouseListener() { 
 
            @Override 
            public void mouseClicked(MouseEvent e) { 
            } 
 
            @Override 
            public void mousePressed(MouseEvent e) { 
            } 
 
            @Override 
            public void mouseEntered(MouseEvent e) { 
            } 
 
            @Override 
            public void mouseExited(MouseEvent e) { 
            } 
             
            @Override 
            public void mouseReleased(MouseEvent e) { 
                //TODO better caret handling after selection 
                //TODO copy/paste ala shell 
//                String sel = getSelectedText(); 
                int caretPosition = getCaretPosition(); 
                Element el = getDocument().getDefaultRootElement(); 
                int msel = el.getElementIndex(caretPosition) + 1
                int last = el.getElementIndex(getText().length()) + 1
                if (msel != last) { 
                    setCaretPosition(getText().length()); 
                } 
            } 
 
        }); 
    } 
 
    public JConsolePanel() { 
        this(new Prompt(), nullnew History()); 
        setCommandHandler(new DefaultCommandHandler()); 
    } 
 
    public OutputStream getOutputStream() { 
        return new OutputStream() { 
 
            @Override 
            public void write(int b) throws IOException { 
                JConsolePanel.this.append(Character.toString((char) b)); 
                setCaretPosition(getText().length()); 
                cp = getCaretPosition(); 
                JConsolePanel.this.scrollRectToVisible(new Rectangle(0, getHeight(), 11)); 
            } 
        }; 
    } 
 
    public void prompt() { 
        JConsolePanel.this.append(prompt.getPrompt()); 
        setCaretPosition(getText().length()); 
        cp = getCaretPosition(); 
        JConsolePanel.this.scrollRectToVisible(new Rectangle(0, getHeight(), 11)); 
    } 
 
    public void clear() { 
        setText(""); 
        cp = prompt.getPrompt().length(); 
    } 
 
    //TODO cascading commandhandler (as List, processed from bottom to top) 
    public void setCommandHandler(CommandHandler h) { 
        cmd = h; 
    } 
 
    public void setPromptProvider(Prompt p) { 
        prompt = p; 
    } 
 
    public void setHistory(History h) { 
        history = h; 
    } 
 
    public PrintWriter getOut() { 
        return w; 
    } 
 
    private class KListener extends KeyAdapter { 
 
        @Override 
        public void keyPressed(KeyEvent key) { 
            switch (key.getKeyCode()) { 
                case KeyEvent.VK_C: 
                    if (key.isControlDown()) { 
                        key.consume(); 
                        append("\n"); 
                        append(prompt.getPrompt()); 
                        setCaretPosition(getText().length()); 
                        cp = getCaretPosition(); 
                    } 
                    break
                case KeyEvent.VK_UP: 
                    String prev = history.prev(); 
                    if (prev != null) { 
                        replaceRange(prev, cp, getText().length()); 
                    } 
                    key.consume(); 
                    break
                case KeyEvent.VK_DOWN: 
                    String next = history.next(); 
                    if (next != null) { 
                        replaceRange(next, cp, getText().length()); 
                    } 
                    key.consume(); 
                    break
                case KeyEvent.VK_LEFT: 
                case KeyEvent.VK_BACK_SPACE: 
                    if (cp == getCaretPosition()) { 
                        key.consume(); 
                    } 
                    break
                case KeyEvent.VK_ENTER: 
                    key.consume(); 
                    String t = getText(); 
                    append("\n"); 
                    if (cmd != null) { 
                        String c = t.substring(cp); 
                        if (!c.isEmpty()) { 
                            append(cmd.handle(c)); 
                            history.appendCommand(c); 
                        } 
                    } 
                    append(prompt.getPrompt()); 
                    setCaretPosition(getText().length()); 
                    cp = getCaretPosition(); 
            } 
        } 
    } 
 
    public static void main(String[] args) throws Exception { 
//        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
        JFrame f = new JFrame(); 
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        JConsolePanel cp = new JConsolePanel(); 
        cp.getOut().println("test hetre"); 
        cp.getOut().println("test next"); 
        cp.prompt(); 
 
        JScrollPane sp = new JScrollPane(cp); 
        sp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); 
        sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); 
 
        f.getContentPane().add(sp); 
        f.setSize(500500); 
        f.setLocation(300300); 
        f.setVisible(true); 
    } 
}