Newer
Older
KisoJikkenNWP / src / main / java / istlab / KisoJikken / JTAConsole.java
package istlab.KisoJikken;

import java.awt.Dimension;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.List;
import java.util.Stack;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.text.BadLocationException;

import com.github.difflib.text.DiffRow;
import com.github.difflib.text.DiffRowGenerator;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class JTAConsole extends MyRSJTextArea
        implements Runnable, WindowListener, KeyListener, MouseListener, ActionListener {
    // static JTAConsole lastWindow;
    // static Point lastActivePoint;
    static Stack<JTAConsole> winStack = new Stack<JTAConsole>();
    JFrame frame;
    Process process;
    Thread thread;
    InputStream instream;
    InputStreamReader isreader;
    BufferedReader reader;
    OutputStream outstream;

    StringBuilder originalContent;
    String mainSrc;
    // ProcessBuilder pb;

    // public JTAConsole(ProcessBuilder prob) {
    public JTAConsole(String title) {
        // pb = prob;

        frame = new JFrame(title);
        frame.getContentPane().add(new JScrollPane(this));
        frame.setSize(500, 200);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
        frame.addWindowListener(this);
        if (winStack.size() > 0) {
            JTAConsole last = winStack.peek();
            if (last.isVisible()) {
                Point lastFrameP = last.frame.getLocationOnScreen();
                frame.setLocation(lastFrameP.x + 470, lastFrameP.y);
            }
        } else {
            if (Editor.lastOpened != null) {
                Point lastEditorP = Editor.lastOpened.getLocationOnScreen();
                Dimension lastEditorD = Editor.lastOpened.getSize();
                frame.setLocation(lastEditorP.x, lastEditorP.y + lastEditorD.height);
            }

        }
        addKeyListener(this);
        addMouseListener(this);

        // if (lastActivePoint != null){
        // frame.setLocation(lastActivePoint.x+500, lastActivePoint.y);
        // } else if (lastWindow != null && lastWindow.isVisible()){
        // Point lastFrameP = lastWindow.frame.getLocationOnScreen();
        // frame.setLocation(lastFrameP.x+500, lastFrameP.y);
        // }
        // lastWindow = this;
        winStack.push(this);
        originalContent = new StringBuilder();
    }

    public void Systemoutprintln(String s) {
        append(s + "\n");
        originalContent.append(s + "\n");
        int len = getDocument().getLength();
        if (getSelectedText() == null)
            setCaretPosition(len);
    }

    public void startBR(Process proc) {
        process = proc;
        try {
            reader = new BufferedReader(new InputStreamReader(proc.getInputStream(), "UTF-8"));
        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
        }
        // isreader = new InputStreamReader(proc.getInputStream());
        outstream = process.getOutputStream();
        String line;
        try {
            // while(true){
            // if (isreader.ready()){
            // char[] buf = new char[1000];
            // isreader.read(buf);
            // }
            // }
            while ((line = reader.readLine()) != null) {
                Systemoutprintln(line);
            }
            process.waitFor();

        } catch (IOException | InterruptedException e) {
            // e.printStackTrace();
            System.out.print(e.getClass().getCanonicalName() + " : ");
            System.out.println(e.getLocalizedMessage());
        }

        Systemoutprintln("=== end ===");

        // thread = new Thread(this);
        // thread.start();
    }

    @Override
    public void run() {
        String line;
        try {
            while ((line = reader.readLine()) != null) {
                Systemoutprintln(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        Systemoutprintln("=== end ===");
    }

    // public static void main(String[] arg) {
    // ProcessBuilder processBuilder = new ProcessBuilder("ping", "localhost");
    // Process process = null;
    // try {
    // process = processBuilder.start();
    // } catch (IOException e) {
    // e.printStackTrace();
    // }
    // JTAConsole con = new JTAConsole("Demo");
    // con.startBR(process);

    // }

    @Override
    public void windowOpened(WindowEvent e) {

    }

    private void destroyProcess() {
        try {
            if (outstream != null)
                outstream.close();
            if (instream != null)
                instream.close();
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        process.destroyForcibly();
    }

    @Override
    public void windowClosing(WindowEvent e) {
        destroyProcess();

        winStack.remove(this);
        setVisible(false);
        if (!process.isAlive()) {
            Launcher.allProcs.remove(process);
        }
    }

    @Override
    public void windowClosed(WindowEvent e) {

    }

    @Override
    public void windowIconified(WindowEvent e) {

    }

    @Override
    public void windowDeiconified(WindowEvent e) {

    }

    @Override
    public void windowActivated(WindowEvent e) {
        // JTAConsole.lastActivePoint = frame.getLocationOnScreen();
    }

    @Override
    public void windowDeactivated(WindowEvent e) {

    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == 10) {
            sendLastLine();
        }
        if (e.getKeyCode() > 64 && e.getKeyCode() < 64 + 32) {
            if (e.isControlDown()) {
                System.out.print("CTRL+");
            }
            if (e.isAltDown()) {
                System.out.print("ALT+");
            }
            if (e.isAltGraphDown()) {
                System.out.print("AltGraph+");
            }
            if (e.isMetaDown()) {
                System.out.print("META+");
            }
            System.out.println(KeyEvent.getKeyText(e.getKeyCode()));
        }

        if (e.isControlDown() || e.isAltDown() || e.isAltGraphDown() || e.isMetaDown()) {
            if (e.getKeyCode() == 67) { // CTRL+C 
                if (getSelectedText() != null) {
                    // 文字列をクリップボードにコピーする
                    Toolkit kit = Toolkit.getDefaultToolkit();
                    Clipboard clip = kit.getSystemClipboard();
                    StringSelection ss = new StringSelection(getSelectedText());
                    clip.setContents(ss, ss);
                    System.out.println("選択範囲をコピーしました");
                } else {
                    // プロセスのみ終了
                    destroyProcess();
                }
            }
            if (e.getKeyCode() == 68 || e.getKeyCode() == 87) { // CTRL+D or Alt-W
                windowClosing(null);
                frame.dispose();
            }
        }
    }

    private void sendLastLine() {
        int start;
        try {
            start = getLineStartOffset(getLineCount() - 1);
            int end = getLineEndOffset(getLineCount() - 1);
            String lastLineText = getText(start, end - start) + "\n";
            // System.out.println(lastLineText);

            byte[] sbyte = lastLineText.getBytes();
            outstream.write(sbyte);
            outstream.flush();
            // originalContent.append("")

        } catch (BadLocationException | IOException e) {
            System.out.println(e.getLocalizedMessage());
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {

    }

    @Override
    public void mouseClicked(MouseEvent e) {
        if (e.getButton() == MouseEvent.BUTTON3) {
            JTAConsolePopup popupMenu = new JTAConsolePopup(this);
            popupMenu.show(this, e.getX(), e.getY());
        }
    }

    @Override
    public void mousePressed(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseReleased(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseEntered(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseExited(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    /**
     * PopupMenuの選択によるコマンド実行
     * 
     * @param e
     */
    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getActionCommand().equals("Copy")) {
            Toolkit kit = Toolkit.getDefaultToolkit();
            Clipboard clip = kit.getSystemClipboard();
            StringSelection ss = new StringSelection(getSelectedText());
            clip.setContents(ss, ss);
        } else if (e.getActionCommand().equals("Show Diff")) {
            String orig = originalContent.toString(); // 出力情報のみ
            String buffer = getText(); // JTAの内容(入力と、コメント含む) ここでの入力とは、擬似ターミナル経由でプロセスに送信した内容を指す
            List<String> origList = Arrays.asList(orig.split("\n"));
            List<String> bufList = Arrays.asList(buffer.split("\n"));
            DiffRowGenerator generator = DiffRowGenerator.create()
                    .showInlineDiffs(true)
                    .inlineDiffByWord(true)
                    .oldTag(f -> "~") // introduce markdown style for strikethrough
                    .newTag(f -> "**") // introduce markdown style for bold
                    .build();
            List<DiffRow> rows = generator.generateDiffRows(origList, bufList);

            System.out.println("|original|new|");
            System.out.println("|--------|---|");
            for (DiffRow row : rows) {
                System.out.println("|" + row.getOldLine() + "|" + row.getNewLine() + "|");
            }

        } else if (e.getActionCommand().equals("Submit")) {
            if (SendJsonData.studentID == null) {
                String s = JOptionPane.showInputDialog(this, "お手数ですが、学生番号を入力してください(例:21A5999)");
                if (s != null) {
                    SendJsonData.studentID = s.trim();
                }
            }

            String orig = originalContent.toString(); // 出力情報のみ
            String buffer = getText(); // JTAの内容(入力と、コメント含む) ここでの入力とは、擬似ターミナル経由でプロセスに送信した内容を指す
            SendJsonData sjd = new SendJsonData(orig, buffer);
            if (mainSrc != null)
                sjd.setMainSrc(mainSrc);

            Gson gson = new GsonBuilder().setPrettyPrinting().create();
            String json = gson.toJson(sjd);
            PostHTTP postHttp = new PostHTTP(json);
            try {
                JOptionPane.showMessageDialog(this, postHttp.execute());
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            // System.out.println(json);
        }
    }

    public void setMainSrcByFileName(String absolutePath) {
        File f = new File(absolutePath);
        mainSrc = Editor.loadFile(f);
    }
}

class SendJsonData {
    public static String studentID = null;
    public String orig, buffer;
    public String markdown;
    public String mainsrc;
    public String stuid;

    SendJsonData(String o, String b) {
        orig = o;
        buffer = b;
        List<String> origList = Arrays.asList(orig.split("\n"));
        List<String> bufList = Arrays.asList(buffer.split("\n"));
        DiffRowGenerator generator = DiffRowGenerator.create()
                .showInlineDiffs(true)
                .inlineDiffByWord(true)
                .oldTag(f -> "~") // introduce markdown style for strikethrough
                .newTag(f -> "**") // introduce markdown style for bold
                .build();
        List<DiffRow> rows = generator.generateDiffRows(origList, bufList);
        StringBuilder sb = new StringBuilder();

        sb.append("|original|new|");
        sb.append("|--------|---|");
        for (DiffRow row : rows) {
            sb.append("|" + row.getOldLine() + "|" + row.getNewLine() + "|");
        }
        markdown = sb.toString();
        stuid = studentID;
    }

    public void setMainSrc(String s) {
        mainsrc = s;
    }
}