From a2a710a13d01deb52111b88d3f82520c97cdf5b6 Mon Sep 17 00:00:00 2001 From: haya4 Date: Wed, 16 Oct 2019 05:57:35 +0900 Subject: [PATCH] =?utf8?q?Restamp=20=E3=83=AF=E3=83=B3=E3=83=91=E3=82=B9?= =?utf8?q?=E9=80=9A=E3=81=A3=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- src/i18n.properties | 2 + src/i18n_ja_JP.properties | 2 + src/osm/jp/gpx/Restamp.java | 10 +- src/osm/jp/gpx/matchtime/gui/AdjustTime.java | 3 +- src/osm/jp/gpx/matchtime/gui/Command.java | 2 +- src/osm/jp/gpx/matchtime/gui/DoDialog.java | 10 +- .../jp/gpx/matchtime/gui/ParameterPanelGpx.java | 34 ++- .../jp/gpx/matchtime/gui/ParameterPanelTime.java | 6 +- .../jp/gpx/matchtime/gui/restamp/CardGpxFile.java | 91 ++++++++ .../gpx/matchtime/gui/restamp/CardPerformFile.java | 111 ++++++++++ .../jp/gpx/matchtime/gui/restamp/DoRestamp.java | 231 +++++++++++++++++++++ .../gpx/matchtime/gui/restamp/RestampDialog.java | 16 +- 12 files changed, 492 insertions(+), 26 deletions(-) create mode 100644 src/osm/jp/gpx/matchtime/gui/restamp/CardGpxFile.java create mode 100644 src/osm/jp/gpx/matchtime/gui/restamp/CardPerformFile.java create mode 100644 src/osm/jp/gpx/matchtime/gui/restamp/DoRestamp.java diff --git a/src/i18n.properties b/src/i18n.properties index ff22af5..bfb9d45 100644 --- a/src/i18n.properties +++ b/src/i18n.properties @@ -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. diff --git a/src/i18n_ja_JP.properties b/src/i18n_ja_JP.properties index e7d3070..cebd4e8 100644 --- a/src/i18n_ja_JP.properties +++ b/src/i18n_ja_JP.properties @@ -52,6 +52,8 @@ label.550=\u30dd\u30a4\u30f3\u30c8\u30de\u30fc\u30ab\u30fc\u3092GPX\u30d5\u label.560=\u30bd\u30fc\u30b9GPX\u306e\u3092\u7121\u8996\u3059\u308b label.570=\u51fa\u529bGPX\u306b\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 diff --git a/src/osm/jp/gpx/Restamp.java b/src/osm/jp/gpx/Restamp.java index 237fe6b..959a3bc 100644 --- a/src/osm/jp/gpx/Restamp.java +++ b/src/osm/jp/gpx/Restamp.java @@ -18,6 +18,8 @@ import org.apache.commons.imaging.ImageReadException; * @author yuu */ public class Restamp extends Thread { + static public final String TIME_PATTERN = "yyyy-MM-dd HH:mm:ss z"; + /** * 実行中に発生したExceptionを保持する場所 */ @@ -103,9 +105,9 @@ public class Restamp extends Thread { * @param argv * argv[0] = 画像ファイルが格納されているディレクトリ --> imgDir * argv[1] = 時刻補正の基準とする画像ファイル --> baseFile - * argv[2] = 基準画像ファイルの精確な撮影日時 "yyyy-MM-dd_HH:mm:ss" --> baseTime + * argv[2] = 基準画像ファイルの精確な撮影日時 "yyyy-MM-dd HH:mm:ss z" --> baseTime * argv[3] = 時刻補正の基準とする画像ファイル --> baseFile - * argv[4] = 基準画像ファイルの精確な撮影日時 "yyyy-MM-dd_HH:mm:ss" --> baseTime + * argv[4] = 基準画像ファイルの精確な撮影日時 "yyyy-MM-dd HH:mm:ss z" --> baseTime * * @throws IOException * @throws ImageReadException @@ -141,7 +143,7 @@ public class Restamp extends Thread { return; } - DateFormat df1 = new SimpleDateFormat("yyyy-MM-dd'_'HH:mm:ss"); + DateFormat df1 = new SimpleDateFormat(TIME_PATTERN); Date baseTime1 = df1.parse(argv[2]); File baseFile2 = new File(imgDir, argv[3]); @@ -156,7 +158,7 @@ public class Restamp extends Thread { return; } - DateFormat df2 = new SimpleDateFormat("yyyy-MM-dd'_'HH:mm:ss"); + DateFormat df2 = new SimpleDateFormat(TIME_PATTERN); Date baseTime2 = df2.parse(argv[4]); Restamp obj = new Restamp(); diff --git a/src/osm/jp/gpx/matchtime/gui/AdjustTime.java b/src/osm/jp/gpx/matchtime/gui/AdjustTime.java index 9dd5872..8f4921a 100644 --- a/src/osm/jp/gpx/matchtime/gui/AdjustTime.java +++ b/src/osm/jp/gpx/matchtime/gui/AdjustTime.java @@ -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); } diff --git a/src/osm/jp/gpx/matchtime/gui/Command.java b/src/osm/jp/gpx/matchtime/gui/Command.java index 5918db8..a1e0686 100644 --- a/src/osm/jp/gpx/matchtime/gui/Command.java +++ b/src/osm/jp/gpx/matchtime/gui/Command.java @@ -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" }) diff --git a/src/osm/jp/gpx/matchtime/gui/DoDialog.java b/src/osm/jp/gpx/matchtime/gui/DoDialog.java index bcaa10f..8c991e1 100644 --- a/src/osm/jp/gpx/matchtime/gui/DoDialog.java +++ b/src/osm/jp/gpx/matchtime/gui/DoDialog.java @@ -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); } /** diff --git a/src/osm/jp/gpx/matchtime/gui/ParameterPanelGpx.java b/src/osm/jp/gpx/matchtime/gui/ParameterPanelGpx.java index d160126..4fe3267 100644 --- a/src/osm/jp/gpx/matchtime/gui/ParameterPanelGpx.java +++ b/src/osm/jp/gpx/matchtime/gui/ParameterPanelGpx.java @@ -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; } } diff --git a/src/osm/jp/gpx/matchtime/gui/ParameterPanelTime.java b/src/osm/jp/gpx/matchtime/gui/ParameterPanelTime.java index 28cbabf..e540e03 100644 --- a/src/osm/jp/gpx/matchtime/gui/ParameterPanelTime.java +++ b/src/osm/jp/gpx/matchtime/gui/ParameterPanelTime.java @@ -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 index 0000000..5a84225 --- /dev/null +++ b/src/osm/jp/gpx/matchtime/gui/restamp/CardGpxFile.java @@ -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: セグメントの最初の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 index 0000000..b4011b7 --- /dev/null +++ b/src/osm/jp/gpx/matchtime/gui/restamp/CardPerformFile.java @@ -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 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 index 0000000..b8f251d --- /dev/null +++ b/src/osm/jp/gpx/matchtime/gui/restamp/DoRestamp.java @@ -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 { + 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); + } + } +} diff --git a/src/osm/jp/gpx/matchtime/gui/restamp/RestampDialog.java b/src/osm/jp/gpx/matchtime/gui/restamp/RestampDialog.java index 3b19e8a..665e27d 100644 --- a/src/osm/jp/gpx/matchtime/gui/restamp/RestampDialog.java +++ b/src/osm/jp/gpx/matchtime/gui/restamp/RestampDialog.java @@ -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); -- 2.11.0