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) { this(title, 200); } public JTAConsole(String title, int win_height) { // pb = prob; frame = new JFrame(title); frame.getContentPane().add(new JScrollPane(this)); frame.setSize(500, win_height); 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+"); System.out.println(KeyEvent.getKeyText(e.getKeyCode())); } if (e.isAltDown()) { System.out.print("ALT+"); System.out.println(KeyEvent.getKeyText(e.getKeyCode())); } if (e.isAltGraphDown()) { System.out.print("AltGraph+"); System.out.println(KeyEvent.getKeyText(e.getKeyCode())); } 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; } }