1 package osm.jp.gpx.matchtime.gui;
3 import osm.jp.gpx.matchtime.gui.restamp.RestampDialog;
5 import java.awt.event.ActionEvent;
6 import java.io.IOException;
7 import java.text.SimpleDateFormat;
8 import java.util.ResourceBundle;
9 import java.util.TimeZone;
10 import java.util.logging.Level;
11 import java.util.logging.Logger;
13 import javax.swing.event.DocumentEvent;
15 import osm.jp.gpx.matchtime.gui.restamp.CardImageFile;
16 import osm.jp.gpx.matchtime.gui.restamp.CardSourceFolder;
21 @SuppressWarnings("serial")
22 public class AdjustTime extends JFrame
24 public static final String PROGRAM_NAME = "AdjustTime for JOSM";
25 public static final String PROGRAM_VARSION = "5.01";
26 public static final String PROGRAM_UPDATE = "2019/09/11";
29 public static SimpleDateFormat dfjp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
31 // Used for addNotify check.
32 boolean fComponentsAdjusted = false;
33 public static ResourceBundle i18n = ResourceBundle.getBundle("i18n");
36 JTabbedPane cardPanel; // ウィザード形式パネル(タブ型)
39 JPanel argsPanel; // パラメータ設定パネル (上部)
40 JScrollPane imageSPane; // スクロールパネル
41 JLabel imageLabel; // 基準時刻画像表示
42 JCheckBox noFirstNode; // GPX: <trkseg>セグメントの最初の1ノードは無視する。 {ON | OFF}
43 JCheckBox gpxReuse; // 生成されたGPXファイル(ファイル名が'_.gpx'で終わるもの)も対象にする。 {ON | OFF}
44 JTextArea textArea; // 実行結果表示領域
46 ParameterPanel arg3_basetime; // 基準時刻:
47 JCheckBox outputIMG; // IMGの変換 する/しない
48 JCheckBox outputIMG_all; // 'out of GPX time'でもIMGの変換をする {ON | OFF}
49 JCheckBox exifON; // EXIF 書き出しモード / !(EXIFの書き換えはしない)
50 JCheckBox gpxOutputWpt; // GPXに<WPT>を書き出す
51 JCheckBox gpxOverwriteMagvar; // ソースGPXの<MAGVAR>を無視する
52 JCheckBox gpxOutputSpeed; // GPXに<SPEED>を書き出す
53 ParameterPanelFolder arg5_outputFolder; // EXIF 書き出しフォルダ
54 ParameterPanelGpx arg4_gpxFolder; // GPXファイル・フォルダ
56 JPanel buttonPanel; // ボタンパネル (下部)
58 JButton doButton; // [処理実行]ボタン
61 //---入力フィールド----------------------------------------------------
62 ParameterPanelFolder arg1_srcFolder; // 対象フォルダ
63 ParameterPanelImageFile arg2_baseTimeImg; // 開始画像ファイルパス
64 ParameterPanelTime arg2_basetime; // 開始画像の基準時刻:
67 java.awt.MenuBar mainMenuBar;
69 java.awt.MenuItem miDoNewFileList;
70 java.awt.MenuItem miDoDirSize;
71 java.awt.MenuItem miDoReadXML;
72 java.awt.MenuItem miExit;
74 java.awt.MenuItem miRestamp;
76 java.awt.MenuItem miAbout;
79 class SymWindow extends java.awt.event.WindowAdapter {
82 * このパネルが閉じられたら、このアプリケーションも終了させる。
85 public void windowClosing(java.awt.event.WindowEvent event) {
86 Object object = event.getSource();
87 if (object == AdjustTime.this) {
88 DbMang_WindowClosing(event);
93 class SymAction implements java.awt.event.ActionListener {
95 public void actionPerformed(java.awt.event.ActionEvent event) {
96 Object object = event.getSource();
97 if (object == miAbout) {
98 miAbout_Action(event);
100 else if (object == miRestamp) {
102 miRestamp_Action(event);
103 } catch (IOException ex) {
104 Logger.getLogger(AdjustTime.class.getName()).log(Level.SEVERE, null, ex);
107 else if (object == miExit) {
108 miExit_Action(event);
110 else if (object == outputIMG) {
111 outputIMG_Action(event);
113 else if (object == outputIMG_all) {
114 outputIMGall_Action(event);
116 else if (object == exifON) {
117 exifON_Action(event);
119 else if (object == gpxOutputWpt) {
120 gpxOutputWpt_Action(event);
122 else if (object == gpxOutputSpeed) {
123 gpxOutputSpeed_Action(event);
125 else if (object == doButton) {
126 doButton_Action(event);
132 * データベース内のテーブルを一覧で表示するFrame
133 * @throws IOException
135 @SuppressWarnings("OverridableMethodCallInConstructor")
136 public AdjustTime() throws IOException
138 dfjp.setTimeZone(TimeZone.getTimeZone("JST"));
141 Container container = getContentPane();
142 container.setLayout(new BorderLayout());
144 getInsets().left + getInsets().right + 720,
145 getInsets().top + getInsets().bottom + 480
147 setTitle(AdjustTime.PROGRAM_NAME +" v"+ AdjustTime.PROGRAM_VARSION);
150 JPanel mainPanel = new JPanel();
151 mainPanel.setLayout(new BorderLayout());
152 container.add(mainPanel, BorderLayout.CENTER);
155 JPanel southPanel = new JPanel(new BorderLayout());
156 southPanel.add(Box.createVerticalStrut(10), BorderLayout.SOUTH);
157 southPanel.add(Box.createVerticalStrut(10), BorderLayout.NORTH);
158 container.add(southPanel, BorderLayout.SOUTH);
161 container.add(Box.createVerticalStrut(30), BorderLayout.NORTH);
162 container.add(Box.createHorizontalStrut(10), BorderLayout.WEST);
163 container.add(Box.createHorizontalStrut(10), BorderLayout.EAST);
165 params = new AppParameters();
167 //---------------------------------------------------------------------
168 cardPanel = new JTabbedPane(JTabbedPane.LEFT);
169 mainPanel.add(cardPanel, BorderLayout.CENTER);
174 //---------------------------------------------------------------------
177 arg1_srcFolder = new ParameterPanelFolder(
178 i18n.getString("label.110") +": ",
179 params.getProperty(AppParameters.IMG_SOURCE_FOLDER)
181 arg1_srcFolder.argField
183 .addDocumentListener(
184 new SimpleDocumentListener() {
186 public void update(DocumentEvent e) {
187 toEnable(0, arg1_srcFolder.isEnable());
192 Card card = new CardSourceFolder(cardPanel, arg1_srcFolder);
193 cardPanel.addTab(card.getTitle(), card);
194 cardPanel.setEnabledAt(cardNo, true);
195 cards[cardNo] = card;
199 //---------------------------------------------------------------------
204 arg2_baseTimeImg = new ParameterPanelImageFile(
205 i18n.getString("label.210") +": ",
211 arg2_basetime = new ParameterPanelTime(
212 i18n.getString("label.310"),
216 arg2_basetime.argField.getDocument().addDocumentListener(
217 new SimpleDocumentListener() {
219 public void update(DocumentEvent e) {
220 toEnable(1, arg2_basetime.isEnable());
226 arg2_basetime.addExifBase(i18n.getString("label.220"), params);
229 arg2_basetime.addFileUpdate(i18n.getString("label.230"), params);
231 CardImageFile card = new CardImageFile(
232 cardPanel, arg2_basetime, (Window)this,
233 AdjustTime.i18n.getString("tab.300"), 0, 2);
234 cardPanel.addTab(card.getTitle(), card);
235 cardPanel.setEnabledAt(cardNo, false);
236 cards[cardNo] = card;
240 //---------------------------------------------------------------------
244 Card card = new Card(cardPanel, i18n.getString("tab.400"), 2, 4);
245 cardPanel.addTab(card.getTitle(), card);
246 cards[cardNo] = card;
248 // 4. ヒモ付を行うGPXファイルを選択してください。
249 // - フォルダを指定すると、フォルダ内のすべてのGPXファイルを対象とします。
250 JLabel label4 = new JLabel();
251 label4.setText(i18n.getString("label.400"));
252 card.mainPanel.add(label4, BorderLayout.NORTH);
254 JPanel tmpPanel4a = new JPanel();
255 tmpPanel4a.setLayout(new BoxLayout(tmpPanel4a, BoxLayout.Y_AXIS));
258 arg4_gpxFolder = new ParameterPanelGpx(
259 i18n.getString("label.410") + ": ",
260 params.getProperty(AppParameters.GPX_SOURCE_FOLDER)
262 tmpPanel4a.add(arg4_gpxFolder);
264 // "セグメント'trkseg'の最初の1ノードは無視する。"
265 noFirstNode = new JCheckBox(
266 i18n.getString("label.420"),
267 params.getProperty(AppParameters.GPX_NO_FIRST_NODE).equals("ON")
269 tmpPanel4a.add(noFirstNode);
271 // "生成されたGPXファイル(ファイル名が'_.gpx'で終わるもの)も変換の対象にする"
272 gpxReuse = new JCheckBox(
273 i18n.getString("label.430"),
274 params.getProperty(AppParameters.GPX_REUSE).equals("ON")
276 gpxReuse.setEnabled(true);
277 tmpPanel4a.add(gpxReuse);
278 card.mainPanel.add(tmpPanel4a, BorderLayout.CENTER);
282 //---------------------------------------------------------------------
285 Card card = new Card(cardPanel, i18n.getString("tab.500"), 3, -1);
286 cardPanel.addTab(card.getTitle(), card);
287 cards[cardNo] = card;
289 // 5. EXIF変換を行うかどうかを選択してください。
290 // - EXIF変換を行う場合には、変換ファイルを出力するフォルダも指定する必要があります。
291 // - 出力フォルダには、書き込み権限と、十分な空き容量が必要です。
292 JLabel label5 = new JLabel();
295 "<html><p>5. %s</p><ul><li>%s</li><li>%s</li></ul>",
296 i18n.getString("label.500"),
297 i18n.getString("label.501"),
298 i18n.getString("label.502")
301 card.mainPanel.add(label5, BorderLayout.NORTH);
303 JPanel tmpPanel5 = new JPanel();
304 tmpPanel5.setLayout(new BoxLayout(tmpPanel5, BoxLayout.Y_AXIS));
307 outputIMG = new JCheckBox(
308 i18n.getString("label.510"),
309 Boolean.parseBoolean(params.getProperty(AppParameters.IMG_OUTPUT))
311 tmpPanel5.add(outputIMG);
313 // "GPXファイル時間外のファイルもコピーする"
314 outputIMG_all = new JCheckBox(
315 i18n.getString("label.520"),
316 Boolean.parseBoolean(params.getProperty(AppParameters.IMG_OUTPUT_ALL))
318 tmpPanel5.add(outputIMG_all);
321 arg5_outputFolder = new ParameterPanelFolder(
322 i18n.getString("label.530") + ": ",
323 params.getProperty(AppParameters.IMG_OUTPUT_FOLDER)
325 tmpPanel5.add(arg5_outputFolder);
328 exifON = new JCheckBox(
329 i18n.getString("label.540"),
330 Boolean.parseBoolean(params.getProperty(AppParameters.IMG_OUTPUT_EXIF))
332 tmpPanel5.add(exifON);
334 // "ポイントマーカー<WPT>をGPXファイルに出力する"
335 gpxOutputWpt = new JCheckBox(
336 i18n.getString("label.550"),
337 Boolean.parseBoolean(params.getProperty(AppParameters.GPX_OUTPUT_WPT))
339 gpxOutputWpt.setEnabled(true);
340 tmpPanel5.add(gpxOutputWpt);
342 // "ソースGPXの<MAGVAR>を無視する"
343 gpxOverwriteMagvar = new JCheckBox(
344 i18n.getString("label.560"),
345 Boolean.parseBoolean(params.getProperty(AppParameters.GPX_OVERWRITE_MAGVAR))
347 gpxOverwriteMagvar.setEnabled(true);
348 tmpPanel5.add(gpxOverwriteMagvar);
350 // "出力GPXに<SPEED>を上書きする"
351 gpxOutputSpeed = new JCheckBox(
352 i18n.getString("label.570"),
353 Boolean.parseBoolean(params.getProperty(AppParameters.GPX_OUTPUT_SPEED))
355 gpxOutputSpeed.setEnabled(true);
356 tmpPanel5.add(gpxOutputSpeed);
358 card.mainPanel.add(tmpPanel5, BorderLayout.CENTER);
361 doButton = new JButton(
362 i18n.getString("button.execute"),
363 AdjustTime.createImageIcon("images/media_playback_start.png")
365 card.mainPanel.add(doButton, BorderLayout.SOUTH);
369 //---------------------------------------------------------------------
371 menu1 = new java.awt.Menu("File");
372 miExit = new java.awt.MenuItem(i18n.getString("menu.quit"));
373 miExit.setFont(new Font("Dialog", Font.PLAIN, 12));
376 miRestamp = new java.awt.MenuItem(i18n.getString("menu.restamp") + "...");
377 miRestamp.setFont(new Font("Dialog", Font.PLAIN, 12));
379 menu2 = new java.awt.Menu(i18n.getString("menu.tools"));
380 menu2.setFont(new Font("Dialog", Font.PLAIN, 12));
381 menu2.add(miRestamp);
383 miAbout = new java.awt.MenuItem("About...");
384 miAbout.setFont(new Font("Dialog", Font.PLAIN, 12));
386 menu3 = new java.awt.Menu("Help");
387 menu3.setFont(new Font("Dialog", Font.PLAIN, 12));
390 mainMenuBar = new java.awt.MenuBar();
391 mainMenuBar.setHelpMenu(menu3);
392 mainMenuBar.add(menu1);
393 mainMenuBar.add(menu2);
394 mainMenuBar.add(menu3);
395 setMenuBar(mainMenuBar);
397 //{{REGISTER_LISTENERS
398 SymWindow aSymWindow = new SymWindow();
399 this.addWindowListener(aSymWindow);
400 SymAction lSymAction = new SymAction();
401 miAbout.addActionListener(lSymAction);
402 miRestamp.addActionListener(lSymAction);
403 miExit.addActionListener(lSymAction);
404 arg2_baseTimeImg.openButton.addActionListener(lSymAction);
405 doButton.addActionListener(lSymAction);
406 outputIMG_all.addActionListener(lSymAction);
407 exifON.addActionListener(lSymAction);
408 gpxOutputSpeed.addActionListener(lSymAction);
409 noFirstNode.addActionListener(lSymAction);
410 gpxReuse.addActionListener(lSymAction);
415 * Shows or hides the component depending on the boolean flag b.
416 * @param b trueのときコンポーネントを表示; その他のとき, componentを隠す.
417 * @see java.awt.Component#isVisible
420 public void setVisible(boolean b) {
428 * このクラスをインスタンスを生成して表示する。
432 @SuppressWarnings("UseSpecificCatch")
433 static public void main(String args[]) {
434 SwingUtilities.invokeLater(() -> {
437 } catch (Exception e) {
442 private static void createAndShowGUI() throws IOException {
443 (new AdjustTime()).setVisible(true);
447 public void addNotify() {
448 // Record the size of the window prior to calling parents addNotify.
449 Dimension d = getSize();
453 if (fComponentsAdjusted)
456 // Adjust components according to the insets
457 setSize(getInsets().left + getInsets().right + d.width, getInsets().top + getInsets().bottom + d.height);
458 Component components[] = getComponents();
459 for (Component component : components) {
460 Point p = component.getLocation();
461 p.translate(getInsets().left, getInsets().top);
462 component.setLocation(p);
464 fComponentsAdjusted = true;
467 void DbMang_WindowClosing(java.awt.event.WindowEvent event) {
468 setVisible(false); // hide the Manager
469 dispose(); // free the system resources
470 System.exit(0); // close the application
473 void miAbout_Action(java.awt.event.ActionEvent event) {
474 // Action from About Create and show as modal
475 (new AboutDialog(this, true)).setVisible(true);
478 void miRestamp_Action(java.awt.event.ActionEvent event) throws IOException {
479 (new RestampDialog(this, false)).setVisible(true);
482 void miExit_Action(java.awt.event.ActionEvent event) {
483 // Action from Exit Create and show as modal
484 //(new hayashi.yuu.tools.gui.QuitDialog(this, true)).setVisible(true);
485 (new QuitDialog(this, true)).setVisible(true);
488 void toEnable(final int cardNo, final boolean enable) {
489 if ((cardNo >= 0) && (cardNo < cards.length)) {
490 cardPanel.setEnabledAt(cardNo, enable);
491 if ((cardNo -1) >= 0) {
492 cards[cardNo -1].nextButton.setEnabled(enable);
494 if ((cardNo +1) < cards.length) {
495 cardPanel.setEnabledAt(cardNo+1, enable);
496 cards[cardNo +1].backButton.setEnabled(enable);
497 cards[cardNo].nextButton.setEnabled(enable);
505 * ソースディレクトリが選択された時のアクション
506 * → AdjustTime.ini に書き込む
509 public void selectSource_Action(ActionEvent ev) {
512 /** Returns an ImageIcon, or null if the path was invalid.
515 public static ImageIcon createImageIcon(String path) {
516 java.net.URL imgURL = AdjustTime.class.getResource(path);
517 if (imgURL != null) {
518 return new ImageIcon(imgURL);
520 System.err.println("Couldn't find file: " + path);
526 * checkbox[IMG変換]を変更した場合のアクション
527 * ON ー> IMG出力フォルダのフィールドを有効にする
528 * OFF -> IMG出力フォルダのフィールドを無効にする
531 void outputIMG_Action (ActionEvent event) {
532 arg5_outputFolder.setEnabled(outputIMG.isEnabled());
536 * checkbox[GPXファイル時間外のファイルもコピーする]を変更した場合のアクション
539 void outputIMGall_Action (ActionEvent event) {
543 * checkbox[EXIF書き出し]を変更した場合のアクション
546 void exifON_Action (ActionEvent event) {
550 * checkbox[GPXの<WPT>を出力する]を変更した場合のアクション
553 void gpxOutputWpt_Action (ActionEvent event) {
557 * checkbox[GPXの<SPPED>を書き換える]を変更した場合のアクション
560 void gpxOutputSpeed_Action (ActionEvent event) {
564 * [実行]ボタンをクリックしたときの動作
567 @SuppressWarnings("UseSpecificCatch")
568 void doButton_Action(java.awt.event.ActionEvent event) {
569 doButton.setEnabled(false);
571 String[] argv = new String[0];
572 this.params.setProperty(AppParameters.GPX_NO_FIRST_NODE, String.valueOf(noFirstNode.isSelected()));
573 this.params.setProperty(AppParameters.GPX_REUSE, String.valueOf(gpxReuse.isSelected()));
574 this.params.setProperty(AppParameters.GPX_SOURCE_FOLDER, arg4_gpxFolder.getText());
576 if (exifBase.isSelected()) {
577 this.params.setProperty(AppParameters.GPX_BASETIME, "EXIF_TIME");
580 this.params.setProperty(AppParameters.GPX_BASETIME, "FILE_UPDATE");
584 this.params.setProperty(AppParameters.IMG_SOURCE_FOLDER, arg1_srcFolder.getText());
585 this.params.setProperty(AppParameters.IMG_BASE_FILE, arg2_baseTimeImg.getText());
586 this.params.setProperty(AppParameters.IMG_TIME, ImportPicture.toUTCString(dfjp.parse(arg3_basetime.getText())));
587 this.params.setProperty(AppParameters.IMG_OUTPUT, String.valueOf(outputIMG.isSelected()));
588 this.params.setProperty(AppParameters.IMG_OUTPUT_FOLDER, arg5_outputFolder.getText());
589 this.params.setProperty(AppParameters.IMG_OUTPUT_ALL, String.valueOf(outputIMG_all.isSelected()));
590 this.params.setProperty(AppParameters.IMG_OUTPUT_EXIF, String.valueOf(exifON.isSelected()));
591 this.params.setProperty(AppParameters.GPX_OVERWRITE_MAGVAR, String.valueOf(gpxOverwriteMagvar.isSelected()));
592 this.params.setProperty(AppParameters.GPX_OUTPUT_SPEED, String.valueOf(gpxOutputSpeed.isSelected()));
593 this.params.setProperty(AppParameters.GPX_OUTPUT_WPT, String.valueOf(gpxOutputWpt.isSelected()));
600 (new DoDialog(argv)).setVisible(true);
602 doButton.setEnabled(true);