OSDN Git Service

Restamp ワンパス通った
authorhaya4 <hayashi.yuu@gmail.com>
Tue, 15 Oct 2019 20:57:35 +0000 (05:57 +0900)
committerhaya4 <hayashi.yuu@gmail.com>
Tue, 15 Oct 2019 20:57:35 +0000 (05:57 +0900)
12 files changed:
src/i18n.properties
src/i18n_ja_JP.properties
src/osm/jp/gpx/Restamp.java
src/osm/jp/gpx/matchtime/gui/AdjustTime.java
src/osm/jp/gpx/matchtime/gui/Command.java
src/osm/jp/gpx/matchtime/gui/DoDialog.java
src/osm/jp/gpx/matchtime/gui/ParameterPanelGpx.java
src/osm/jp/gpx/matchtime/gui/ParameterPanelTime.java
src/osm/jp/gpx/matchtime/gui/restamp/CardGpxFile.java [new file with mode: 0644]
src/osm/jp/gpx/matchtime/gui/restamp/CardPerformFile.java [new file with mode: 0644]
src/osm/jp/gpx/matchtime/gui/restamp/DoRestamp.java [new file with mode: 0644]
src/osm/jp/gpx/matchtime/gui/restamp/RestampDialog.java

index ff22af5..bfb9d45 100644 (file)
@@ -38,6 +38,8 @@ label.410=GPX folder
 label.420=Ignore the first node of segment 'trkseg'
 label.430=Also make the generated GPX file (the one whose filename ends with '_.gpx') as the target of conversion
 
+tab.restamp.400=4. Perform RESTAMP
+
 tab.500=4. perform EXIF conversion
 label.500=Select whether to perform EXIF conversion
 label.501=When performing EXIF conversion, you also need to specify the folder to output the converted file.
index e7d3070..cebd4e8 100644 (file)
@@ -52,6 +52,8 @@ label.550=\u30dd\u30a4\u30f3\u30c8\u30de\u30fc\u30ab\u30fc<WPT>\u3092GPX\u30d5\u
 label.560=\u30bd\u30fc\u30b9GPX\u306e<MAGVAR>\u3092\u7121\u8996\u3059\u308b
 label.570=\u51fa\u529bGPX\u306b<SPEED>\u3092\u4e0a\u66f8\u304d\u3059\u308b
 
+tab.restamp.400=4. \u5909\u63db\u306e\u5b9f\u884c
+
 msg.100=GPX\u30d5\u30a1\u30a4\u30eb\u307e\u305f\u306f\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u304c\u5b58\u5728\u3057\u307e\u305b\u3093\u3002('%s')
 msg.110=\u5bfe\u8c61\u3068\u306a\u308bGPX\u30d5\u30a1\u30a4\u30eb\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093('%s')
 msg.120=\u8907\u6570\u306eGPX\u30d5\u30a1\u30a4\u30eb\u304c\u3042\u308b\u3068\u304d\u306b\u306f\u3001'IMG.OUTPUT_ALL'\u30aa\u30d7\u30b7\u30e7\u30f3\u306f\u6307\u5b9a\u3067\u304d\u307e\u305b\u3093\u3002
index 237fe6b..959a3bc 100644 (file)
@@ -18,6 +18,8 @@ import org.apache.commons.imaging.ImageReadException;
  * @author yuu\r
  */\r
 public class Restamp extends Thread {\r
+    static public final String TIME_PATTERN = "yyyy-MM-dd HH:mm:ss z";\r
+\r
     /**\r
      * 実行中に発生したExceptionを保持する場所\r
      */\r
@@ -103,9 +105,9 @@ public class Restamp extends Thread {
      * @param argv\r
      * argv[0] = 画像ファイルが格納されているディレクトリ          --> imgDir\r
      * argv[1] = 時刻補正の基準とする画像ファイル                      --> baseFile\r
-     * argv[2] = 基準画像ファイルの精確な撮影日時 "yyyy-MM-dd_HH:mm:ss" --> baseTime\r
+     * argv[2] = 基準画像ファイルの精確な撮影日時 "yyyy-MM-dd HH:mm:ss z" --> baseTime\r
      * argv[3] = 時刻補正の基準とする画像ファイル                      --> baseFile\r
-     * argv[4] = 基準画像ファイルの精確な撮影日時 "yyyy-MM-dd_HH:mm:ss" --> baseTime\r
+     * argv[4] = 基準画像ファイルの精確な撮影日時 "yyyy-MM-dd HH:mm:ss z" --> baseTime\r
      * \r
      * @throws IOException\r
      * @throws ImageReadException \r
@@ -141,7 +143,7 @@ public class Restamp extends Thread {
             return;\r
         }\r
         \r
-        DateFormat df1 = new SimpleDateFormat("yyyy-MM-dd'_'HH:mm:ss");\r
+        DateFormat df1 = new SimpleDateFormat(TIME_PATTERN);\r
        Date baseTime1 = df1.parse(argv[2]);\r
 \r
         File baseFile2 = new File(imgDir, argv[3]);\r
@@ -156,7 +158,7 @@ public class Restamp extends Thread {
             return;\r
         }\r
         \r
-        DateFormat df2 = new SimpleDateFormat("yyyy-MM-dd'_'HH:mm:ss");\r
+        DateFormat df2 = new SimpleDateFormat(TIME_PATTERN);\r
        Date baseTime2 = df2.parse(argv[4]);\r
 \r
         Restamp obj = new Restamp();\r
index 9dd5872..8f4921a 100644 (file)
@@ -305,6 +305,7 @@ public class AdjustTime extends JFrame
         // 3.GPXファイル設定画面
         cardNo++;
         {
+            // 3. GPXファイルを選択
             Card card = new Card(cardPanel, i18n.getString("tab.400"), 2, 4);
             cardPanel.addTab(card.getTitle(), card);
             cards[cardNo] = card;
@@ -750,7 +751,7 @@ public class AdjustTime extends JFrame
             e.printStackTrace();
         }
 
-        (new DoDialog(this, argv)).setVisible(true);
+        (new DoDialog(argv)).setVisible(true);
                
        doButton.setEnabled(true);
     }
index 5918db8..a1e0686 100644 (file)
@@ -3,7 +3,7 @@ package osm.jp.gpx.matchtime.gui;
 import java.lang.reflect.InvocationTargetException;
 import java.text.SimpleDateFormat;
 
-class Command extends Thread {
+public class Command extends Thread {
     String[] args;             // コマンドパラメータ
     private String commandName = "";   // コマンド名
     @SuppressWarnings({ "rawtypes" })
index bcaa10f..8c991e1 100644 (file)
@@ -21,7 +21,6 @@ public class DoDialog extends JDialog {
     String[] args;
     
     //{{DECLARE_CONTROLS
-    JFrame parentFrame;        // MatchTime.class
     JPanel buttonPanel;     // ボタン配置パネル        (下部)
     JButton closeButton;      // [クローズ]ボタン
     JButton doButton;      // [実行]ボタン
@@ -29,16 +28,15 @@ public class DoDialog extends JDialog {
     //}}
 
     @SuppressWarnings("OverridableMethodCallInConstructor")
-    public DoDialog(JFrame parentFrame, String[] args) {
-        super(parentFrame, true);   // モーダルダイアログを基盤にする
-        this.parentFrame = parentFrame;
+    public DoDialog(String[] args) {
+        super();   // モーダルダイアログを基盤にする
         this.args = args;
                 
         // INIT_CONTROLS
         @SuppressWarnings("OverridableMethodCallInConstructor")
         Container container = getContentPane();
         container.setLayout(new BorderLayout());
-        parentFrame.setVisible(false);
+        //parentFrame.setVisible(false);
         setSize(getInsets().left + getInsets().right + 980, getInsets().top + getInsets().bottom + 480);
         setTitle(DoDialog.TITLE);
         
@@ -88,7 +86,7 @@ public class DoDialog extends JDialog {
         }
 
         // JFrameの表示
-        parentFrame.setVisible(true);
+        //parentFrame.setVisible(true);
     }
     
     /**
index d160126..4fe3267 100644 (file)
@@ -18,19 +18,11 @@ public class ParameterPanelGpx extends ParameterPanel implements ActionListener
         super(label, text);
 
         // "選択..."
-        openButton = new JButton(
-            i18n.getString("button.select"), 
-            AdjustTime.createImageIcon("images/Open16.gif")
-        );
+        openButton = new JButton(i18n.getString("button.select"), AdjustTime.createImageIcon("images/Open16.gif"));
         openButton.addActionListener(this);
         this.add(openButton);
     }
 
-    public void setEnable(boolean f) {
-        super.setEnabled(f);
-        openButton.setEnabled(f);
-    }
-       
     @Override
     public void actionPerformed(ActionEvent e) {
         if (e.getSource() == openButton){
@@ -55,12 +47,34 @@ public class ParameterPanelGpx extends ParameterPanel implements ActionListener
         }
     }
 
+    public File getGpxFile() {
+        if (isEnable()) {
+            return new File(getText());
+        }
+        return null;
+    }
+    
     /**
      * このフィールドに有効な値が設定されているかどうか
      * @return 
      */
     @Override
     public boolean isEnable() {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+        String text = this.argField.getText();
+        if (text != null) {
+            File file = new File(text);
+            if (file.exists()) {
+                if (file.isFile()) {
+                    String name = file.getName().toUpperCase();
+                    if (name.endsWith(".GPX")) {
+                        return true;
+                    }
+                }
+                else if (file.isDirectory()) {
+                    return true;
+                }
+            }
+        }
+        return false;
     }
 }
index 28cbabf..e540e03 100644 (file)
@@ -7,6 +7,7 @@ import java.text.DateFormat;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 import javax.swing.JButton;
+import osm.jp.gpx.Restamp;
 import osm.jp.gpx.matchtime.gui.restamp.DialogCorectTime;
 
 /**
@@ -14,7 +15,6 @@ import osm.jp.gpx.matchtime.gui.restamp.DialogCorectTime;
  * この1インスタンスで、1パラメータをあらわす。
  */
 public class ParameterPanelTime extends ParameterPanel {
-    static final String TIME_PATTERN = "yyyy.MM.dd HH:mm:ss z";
     SimpleDateFormat sdf = (SimpleDateFormat)DateFormat.getDateTimeInstance();
     ParameterPanelImageFile imageFile;
     public JButton updateButton;
@@ -82,7 +82,7 @@ public class ParameterPanelTime extends ParameterPanel {
             if (param.imageFile.isEnable()) {
                 File file = param.imageFile.getImageFile();
                 long lastModified = file.lastModified();
-                sdf.applyPattern(TIME_PATTERN);
+                sdf.applyPattern(Restamp.TIME_PATTERN);
                 param.argField.setText(sdf.format(new Date(lastModified)));
             }
             else {
@@ -101,7 +101,7 @@ public class ParameterPanelTime extends ParameterPanel {
             String text = this.argField.getText();
             if (text != null) {
                 try {
-                    sdf.applyPattern(TIME_PATTERN);
+                    sdf.applyPattern(Restamp.TIME_PATTERN);
                     sdf.parse(text);
                     return true;
                 }
diff --git a/src/osm/jp/gpx/matchtime/gui/restamp/CardGpxFile.java b/src/osm/jp/gpx/matchtime/gui/restamp/CardGpxFile.java
new file mode 100644 (file)
index 0000000..5a84225
--- /dev/null
@@ -0,0 +1,91 @@
+package osm.jp.gpx.matchtime.gui.restamp;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import javax.swing.BoxLayout;
+import javax.swing.JCheckBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTabbedPane;
+import osm.jp.gpx.matchtime.gui.AdjustTime;
+import static osm.jp.gpx.matchtime.gui.AdjustTime.i18n;
+import osm.jp.gpx.matchtime.gui.Card;
+import osm.jp.gpx.matchtime.gui.PanelAction;
+import osm.jp.gpx.matchtime.gui.ParameterPanelGpx;
+
+/**
+ * [GPXファイル]選択パネル
+ * @author yuu
+ */
+public class CardGpxFile extends Card  implements PanelAction {
+    //JPanel argsPanel;                // パラメータ設定パネル       (上部)
+    ParameterPanelGpx arg_gpxFile;
+    JCheckBox noFirstNode;     // GPX: <trkseg>セグメントの最初の1ノードは無視する。 {ON | OFF}
+    JCheckBox gpxReuse;                // 生成されたGPXファイル(ファイル名が'_.gpx'で終わるもの)も対象にする。 {ON | OFF}
+    private final boolean gpxReuseV;
+    
+    /**
+     * コンストラクタ
+     * @param tabbe parent panel
+     * @param arg_gpxFile              // 開始画像の基準時刻:
+     * @param noFirstNodeV
+     * @param gpxReuseV
+     */
+    public CardGpxFile(
+            JTabbedPane tabbe, 
+            ParameterPanelGpx arg_gpxFile,
+            boolean noFirstNodeV,
+            boolean gpxReuseV
+    ) {
+        super(tabbe, AdjustTime.i18n.getString("tab.400"), 2, 4);
+        this.arg_gpxFile = arg_gpxFile;
+        
+        JPanel argsPanel = new JPanel();
+        argsPanel.setLayout(new BoxLayout(argsPanel, BoxLayout.PAGE_AXIS));
+        argsPanel.add(packLine(new JLabel(i18n.getString("label.400")), new JPanel()));
+        argsPanel.add(arg_gpxFile);
+        
+        // "セグメント'trkseg'の最初の1ノードは無視する。"
+        noFirstNode = new JCheckBox(
+            i18n.getString("label.420"), 
+            noFirstNodeV
+        );
+        argsPanel.add(noFirstNode);
+
+        // "生成されたGPXファイル(ファイル名が'_.gpx'で終わるもの)も変換の対象にする"
+        gpxReuse = new JCheckBox(i18n.getString("label.430"), gpxReuseV);
+        gpxReuse.setEnabled(true);
+        argsPanel.add(gpxReuse);
+        
+        JPanel space = new JPanel();
+        space.setMinimumSize(new Dimension(40, 20));
+        space.setMaximumSize(new Dimension(40, Short.MAX_VALUE));
+        argsPanel.add(space);
+        
+        this.mainPanel.add(argsPanel, BorderLayout.CENTER);
+        this.gpxReuseV = gpxReuseV;
+    }
+    
+    /**
+     * "セグメント'trkseg'の最初の1ノードは無視する。"
+     * @return 
+     */
+    public boolean getNoFirstNode() {
+        return noFirstNode.isSelected();
+    }
+    
+    /**
+     *  入力条件が満たされているかどうか
+     * @return
+     */
+    @Override
+    public boolean isEnable() {
+       return (arg_gpxFile.isEnable());
+    }
+    
+    @Override
+    @SuppressWarnings("empty-statement")
+    public void openAction() {
+       ; // 何もしない
+    }
+}
diff --git a/src/osm/jp/gpx/matchtime/gui/restamp/CardPerformFile.java b/src/osm/jp/gpx/matchtime/gui/restamp/CardPerformFile.java
new file mode 100644 (file)
index 0000000..b4011b7
--- /dev/null
@@ -0,0 +1,111 @@
+package osm.jp.gpx.matchtime.gui.restamp;
+
+import java.awt.BorderLayout;
+import java.awt.Dialog;
+import java.io.File;
+import java.util.ArrayList;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTabbedPane;
+import osm.jp.gpx.matchtime.gui.AdjustTime;
+import static osm.jp.gpx.matchtime.gui.AdjustTime.i18n;
+import osm.jp.gpx.matchtime.gui.Card;
+import osm.jp.gpx.matchtime.gui.DoDialog;
+import osm.jp.gpx.matchtime.gui.PanelAction;
+import osm.jp.gpx.matchtime.gui.ParameterPanelImageFile;
+import osm.jp.gpx.matchtime.gui.ParameterPanelTime;
+
+/**
+ * [基準画像(開始/終了)]選択パネル
+ * @author yuu
+ */
+public class CardPerformFile extends Card  implements PanelAction {
+    //JPanel argsPanel;                // パラメータ設定パネル       (上部)
+    ParameterPanelTime arg1_basetime;
+    ParameterPanelTime arg2_basetime;
+    JButton doButton;       // [処理実行]ボタン
+    
+    /**
+     * コンストラクタ
+     * @param tabbe parent panel
+     * @param arg1_basetime            // 開始画像の基準時刻:
+     * @param arg2_basetime            // 開始画像の基準時刻:
+     */
+    public CardPerformFile(
+            JTabbedPane tabbe,
+            ParameterPanelTime arg1_basetime,
+            ParameterPanelTime arg2_basetime
+    ) {
+        super(tabbe, AdjustTime.i18n.getString("tab.restamp.400"), 2, 4);
+        this.arg1_basetime = arg1_basetime;
+        this.arg2_basetime = arg2_basetime;
+        
+        JPanel argsPanel = new JPanel();
+        argsPanel.setLayout(new BoxLayout(argsPanel, BoxLayout.PAGE_AXIS));
+        argsPanel.add(packLine(new JLabel(i18n.getString("label.200")), new JPanel()));
+
+        // [処理実行]ボタン
+        doButton = new JButton(
+            i18n.getString("button.execute"),
+            AdjustTime.createImageIcon("images/media_playback_start.png")
+        );
+        argsPanel.add(doButton);
+                
+        this.mainPanel.add(argsPanel, BorderLayout.CENTER);
+
+        //{{REGISTER_LISTENERS
+        SymAction lSymAction = new SymAction();
+        doButton.addActionListener(lSymAction);
+        //}}
+    }
+    
+    class SymAction implements java.awt.event.ActionListener {
+        @Override
+        public void actionPerformed(java.awt.event.ActionEvent event) {
+            Object object = event.getSource();
+            if (object == doButton) {
+               doButton_Action(event);
+            }
+        }
+    }
+    
+    /**
+     * [実行]ボタンをクリックしたときの動作
+     * @param event
+     */
+    @SuppressWarnings("UseSpecificCatch")
+    void doButton_Action(java.awt.event.ActionEvent event) {
+       doButton.setEnabled(false);
+
+        ArrayList<String> arry = new ArrayList<>();
+        File file = arg1_basetime.getImageFile().getImageFile();
+        File dir = file.getParentFile();
+        arry.add(dir.getAbsolutePath());
+        arry.add(file.getName());
+        arry.add(arg1_basetime.argField.getText());
+        file = arg2_basetime.getImageFile().getImageFile();
+        arry.add(file.getName());
+        arry.add(arg2_basetime.argField.getText());
+       String[] argv = arry.toArray(new String[arry.size()]);
+        (new DoRestamp(argv)).setVisible(true);
+               
+       doButton.setEnabled(true);
+    }
+
+    /**
+     *  入力条件が満たされているかどうか
+     * @return
+     */
+    @Override
+    public boolean isEnable() {
+       return (arg1_basetime.isEnable() && arg2_basetime.isEnable());
+    }
+    
+    @Override
+    @SuppressWarnings("empty-statement")
+    public void openAction() {
+       ; // 何もしない
+    }
+}
diff --git a/src/osm/jp/gpx/matchtime/gui/restamp/DoRestamp.java b/src/osm/jp/gpx/matchtime/gui/restamp/DoRestamp.java
new file mode 100644 (file)
index 0000000..b8f251d
--- /dev/null
@@ -0,0 +1,231 @@
+package osm.jp.gpx.matchtime.gui.restamp;
+import osm.jp.gpx.matchtime.gui.Command;
+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 DoRestamp 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 DoRestamp(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(DoRestamp.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 import.jar osm.jp.gpx.Restamp");
+            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.jp.gpx.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);
+        }
+    }
+}
index 3b19e8a..665e27d 100644 (file)
@@ -97,7 +97,7 @@ public class RestampDialog extends Dialog implements Observer
         
         //---------------------------------------------------------------------
         params = new AppParameters();
-        cards = new Card[3];
+        cards = new Card[4];
         cardPanel = new JTabbedPane(JTabbedPane.LEFT);
         mainPanel.add(cardPanel, BorderLayout.CENTER);
         int cardNo = 0;
@@ -191,6 +191,20 @@ public class RestampDialog extends Dialog implements Observer
             cardNo++;
         }
         
+        //---------------------------------------------------------------------
+        // 4. 実行画面
+        {
+            CardPerformFile card = new CardPerformFile(
+                    cardPanel, 
+                    arg2_basetime,
+                    arg3_basetime
+            );
+            cardPanel.addTab(card.getTitle(), card);
+            cardPanel.setEnabledAt(cardNo, false);
+            cards[cardNo] = card;
+            cardNo++;
+        }
+        
         //{{REGISTER_LISTENERS
         SymWindow aSymWindow = new SymWindow();
         this.addWindowListener(aSymWindow);