OSDN Git Service

Java11 - AdjustTime2
[importpicture/importpicture.git] / src / osm / jp / gpx / matchtime / gui / DoDialog.java
1 package osm.jp.gpx.matchtime.gui;
2 import java.awt.BorderLayout;
3 import java.awt.Component;
4 import java.awt.Container;
5 import java.awt.Dimension;
6 import java.awt.Font;
7 import java.awt.Point;
8 import java.awt.event.ActionEvent;
9 import java.io.*;
10 import javax.swing.*;
11
12 /**
13  *      処理 
14  */
15 @SuppressWarnings("serial")
16 public class DoDialog extends JDialog {
17     public static final String TITLE = "Do Command";
18         
19     // Used for addNotify check.
20     boolean fComponentsAdjusted = false;
21     String[] args;
22     
23     //{{DECLARE_CONTROLS
24     JFrame parentFrame;         // MatchTime.class
25     JPanel buttonPanel;     // ボタン配置パネル (下部)
26     JButton closeButton;      // [クローズ]ボタン
27     JButton doButton;      // [実行]ボタン
28     JTextArea textArea;      // 実行結果を表示するJTextArea    (中央)
29     //}}
30
31     @SuppressWarnings("OverridableMethodCallInConstructor")
32     public DoDialog(JFrame parentFrame, String[] args) {
33         super(parentFrame, true);   // モーダルダイアログを基盤にする
34         this.parentFrame = parentFrame;
35         this.args = args;
36                 
37         // INIT_CONTROLS
38         @SuppressWarnings("OverridableMethodCallInConstructor")
39         Container container = getContentPane();
40         container.setLayout(new BorderLayout());
41         parentFrame.setVisible(false);
42         setSize(getInsets().left + getInsets().right + 980, getInsets().top + getInsets().bottom + 480);
43         setTitle(DoDialog.TITLE);
44         
45         // コントロールパネル
46         buttonPanel = new JPanel();
47
48         doButton = new JButton("実行");
49         doButton.setToolTipText("処理を実行します.");
50         doButton.setEnabled(true);
51         doButton.addActionListener((ActionEvent event) -> {
52             // 処理中であることを示すため
53             // ボタンの文字列を変更し,使用不可にする
54             doButton.setText("処理中...");
55             doButton.setEnabled(false);
56             
57             // SwingWorker を生成し,実行する
58             LongTaskWorker worker = new LongTaskWorker(doButton);
59             worker.execute();
60         });
61         buttonPanel.add(doButton);
62
63         closeButton = new JButton("閉じる");
64         closeButton.setToolTipText("処理を終了します.");
65         closeButton.addActionListener((ActionEvent event) -> {
66             dispose();
67         });
68         buttonPanel.add(closeButton);
69         
70         this.getContentPane().add("South", buttonPanel);
71         
72         // 説明文
73         textArea = new JTextArea();
74         JScrollPane sc=new JScrollPane(textArea);
75         textArea.setFont(new Font(Font.MONOSPACED,Font.PLAIN,12));
76         textArea.setTabSize(4);
77         this.getContentPane().add("Center", sc);
78         
79         try {
80             textArea.append("> java -cp importPicture.jar osm.jp.gpx.ImportPicture");
81             for (String arg : args) {
82                 textArea.append(" '" + arg + "'");
83             }
84             textArea.append("\n\n");
85         }
86         catch (Exception e) {
87             System.out.println(e.toString());
88         }
89
90         // JFrameの表示
91         parentFrame.setVisible(true);
92     }
93     
94     /**
95     * Shows or hides the component depending on the boolean flag b.
96     * @param b  trueのときコンポーネントを表示; その他のとき, componentを隠す.
97     * @see java.awt.Component#isVisible
98     */
99     @Override
100     public void setVisible(boolean b) {
101         if(b) {
102             setLocation(80, 80);
103         }
104         super.setVisible(b);
105     }
106
107     @Override
108     public void addNotify()     {
109         // Record the size of the window prior to calling parents addNotify.
110         Dimension d = getSize();
111
112         super.addNotify();
113
114         if (fComponentsAdjusted) {
115             return;
116         }
117
118         // Adjust components according to the insets
119         setSize(getInsets().left + getInsets().right + d.width, getInsets().top + getInsets().bottom + d.height);
120         Component components[] = getComponents();
121         for (Component component : components) {
122             Point p = component.getLocation();
123             p.translate(getInsets().left, getInsets().top);
124             component.setLocation(p);
125         }
126         fComponentsAdjusted = true;
127     }
128
129     
130     /**
131      * JTextAreaに書き出すOutputStream
132      */
133     public static class JTextAreaOutputStream extends OutputStream {
134         private final ByteArrayOutputStream os;
135         
136         /** 書き出し対象 */
137         private final JTextArea textArea;
138         private final String encode;
139
140         public JTextAreaOutputStream(JTextArea textArea, String encode) {
141             this.textArea = textArea;
142             this.encode = encode;
143             this.os = new ByteArrayOutputStream();
144         }
145         
146         /** 
147          * OutputStream#write(byte[])のオーバーライド
148          * @param arg
149          * @throws java.io.IOException
150          */
151         @Override
152         public void write(int arg) throws IOException {
153             this.os.write(arg);
154         }
155         
156         /**
157          * flush()でJTextAreaに書き出す
158          * @throws java.io.IOException
159          */
160         @Override
161         public void flush() throws IOException {
162             // 文字列のエンコード
163             final String str = new String(this.os.toByteArray(), this.encode);
164             // 実際の書き出し処理
165             SwingUtilities.invokeLater(
166                 new Runnable(){
167                     @Override
168                     public void run() {
169                         JTextAreaOutputStream.this.textArea.append(str);
170                     }
171                 }
172             );
173             // 書き出した内容はクリアする
174             this.os.reset();
175         }
176     }
177     
178     // 非同期に行う処理を記述するためのクラス
179     class LongTaskWorker extends SwingWorker<Object, Object> {
180         private final JButton button;
181
182         public LongTaskWorker(JButton button) {
183             this.button = button;
184         }
185
186         // 非同期に行われる処理
187         @Override
188         @SuppressWarnings("SleepWhileInLoop")
189         public Object doInBackground() {
190             // ながーい処理
191             PrintStream defOut = System.out;
192             PrintStream defErr = System.err;
193
194             OutputStream os = new JTextAreaOutputStream(textArea, "UTF-8");
195             PrintStream stdout = new PrintStream(os, true);      // 自動flushをtrueにしておく
196
197             // System.out にJTextAreaOutputStreamに書き出すPrintStreamを設定
198             System.setOut(stdout);
199             System.setErr(stdout);
200
201             try {
202                 Command command = new Command(osm.jp.gpx.ImportPicture.class);
203                 command.setArgs(args);
204                 command.start();                // コマンドを実行
205                 while (command.isAlive()) {
206                     try {
207                         Thread.sleep(1000);
208                     } catch (InterruptedException e) {}
209                 }
210             }
211             catch(Exception e) {
212                 e.printStackTrace(stdout);
213             }
214             finally {
215                 System.setOut(defOut);
216                 System.setErr(defErr);
217                 doButton.setEnabled(true);
218             }
219
220             return null;
221         }
222
223         // 非同期処理後に実行
224         @Override
225         protected void done() {
226             // 処理が終了したので,文字列を元に戻し
227             // ボタンを使用可能にする
228             button.setText("実行");
229             button.setEnabled(true);
230         }
231     }
232 }