package osm.surveyor.matchtime.gui; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.Font; import java.awt.Point; import java.awt.event.ActionEvent; import java.io.*; import javax.swing.*; /** * 処理 */ @SuppressWarnings("serial") public class DoDialog extends JDialog { public static final String TITLE = "Do Command"; // Used for addNotify check. boolean fComponentsAdjusted = false; String[] args; //{{DECLARE_CONTROLS JPanel buttonPanel; // ボタン配置パネル (下部) JButton closeButton; // [クローズ]ボタン JButton doButton; // [実行]ボタン JTextArea textArea; // 実行結果を表示するJTextArea (中央) //}} @SuppressWarnings("OverridableMethodCallInConstructor") public DoDialog(String[] args) { super(); // モーダルダイアログを基盤にする this.args = args; // INIT_CONTROLS @SuppressWarnings("OverridableMethodCallInConstructor") Container container = getContentPane(); container.setLayout(new BorderLayout()); //parentFrame.setVisible(false); setSize(getInsets().left + getInsets().right + 980, getInsets().top + getInsets().bottom + 480); setTitle(DoDialog.TITLE); // コントロールパネル buttonPanel = new JPanel(); doButton = new JButton("実行"); doButton.setToolTipText("処理を実行します."); doButton.setEnabled(true); doButton.addActionListener((ActionEvent event) -> { // 処理中であることを示すため // ボタンの文字列を変更し,使用不可にする doButton.setText("処理中..."); doButton.setEnabled(false); // SwingWorker を生成し,実行する LongTaskWorker worker = new LongTaskWorker(doButton); worker.execute(); }); buttonPanel.add(doButton); closeButton = new JButton("閉じる"); closeButton.setToolTipText("処理を終了します."); closeButton.addActionListener((ActionEvent event) -> { dispose(); }); buttonPanel.add(closeButton); this.getContentPane().add("South", buttonPanel); // 説明文 textArea = new JTextArea(); JScrollPane sc=new JScrollPane(textArea); textArea.setFont(new Font(Font.MONOSPACED,Font.PLAIN,12)); textArea.setTabSize(4); this.getContentPane().add("Center", sc); try { textArea.append("> java -cp importPicture.jar osm.jp.gpx.ImportPicture"); for (String arg : args) { textArea.append(" '" + arg + "'"); } textArea.append("\n\n"); } catch (Exception e) { System.out.println(e.toString()); } // JFrameの表示 //parentFrame.setVisible(true); } /** * Shows or hides the component depending on the boolean flag b. * @param b trueのときコンポーネントを表示; その他のとき, componentを隠す. * @see java.awt.Component#isVisible */ @Override public void setVisible(boolean b) { if(b) { setLocation(80, 80); } super.setVisible(b); } @Override public void addNotify() { // Record the size of the window prior to calling parents addNotify. Dimension d = getSize(); super.addNotify(); if (fComponentsAdjusted) { return; } // Adjust components according to the insets setSize(getInsets().left + getInsets().right + d.width, getInsets().top + getInsets().bottom + d.height); Component components[] = getComponents(); for (Component component : components) { Point p = component.getLocation(); p.translate(getInsets().left, getInsets().top); component.setLocation(p); } fComponentsAdjusted = true; } /** * JTextAreaに書き出すOutputStream */ public static class JTextAreaOutputStream extends OutputStream { private final ByteArrayOutputStream os; /** 書き出し対象 */ private final JTextArea textArea; private final String encode; public JTextAreaOutputStream(JTextArea textArea, String encode) { this.textArea = textArea; this.encode = encode; this.os = new ByteArrayOutputStream(); } /** * OutputStream#write(byte[])のオーバーライド * @param arg * @throws java.io.IOException */ @Override public void write(int arg) throws IOException { this.os.write(arg); } /** * flush()でJTextAreaに書き出す * @throws java.io.IOException */ @Override public void flush() throws IOException { // 文字列のエンコード final String str = new String(this.os.toByteArray(), this.encode); // 実際の書き出し処理 SwingUtilities.invokeLater( new Runnable(){ @Override public void run() { JTextAreaOutputStream.this.textArea.append(str); } } ); // 書き出した内容はクリアする this.os.reset(); } } // 非同期に行う処理を記述するためのクラス class LongTaskWorker extends SwingWorker<Object, Object> { private final JButton button; public LongTaskWorker(JButton button) { this.button = button; } // 非同期に行われる処理 @Override @SuppressWarnings("SleepWhileInLoop") public Object doInBackground() { // ながーい処理 PrintStream defOut = System.out; PrintStream defErr = System.err; OutputStream os = new JTextAreaOutputStream(textArea, "UTF-8"); PrintStream stdout = new PrintStream(os, true); // 自動flushをtrueにしておく // System.out にJTextAreaOutputStreamに書き出すPrintStreamを設定 System.setOut(stdout); System.setErr(stdout); try { Command command = new Command(osm.surveyor.matchtime.Restamp.class); command.setArgs(args); command.start(); // コマンドを実行 while (command.isAlive()) { try { Thread.sleep(1000); } catch (InterruptedException e) {} } } catch(Exception e) { e.printStackTrace(stdout); } finally { System.setOut(defOut); System.setErr(defErr); doButton.setEnabled(true); } return null; } // 非同期処理後に実行 @Override protected void done() { // 処理が終了したので,文字列を元に戻し // ボタンを使用可能にする button.setText("実行"); button.setEnabled(true); } } }