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;
}
}