4 * Created on 2011/05/28, 18:14:51
6 package yukihane.inqubus.gui;
8 import java.awt.Dimension;
10 import java.awt.ItemSelectable;
11 import java.awt.Point;
12 import java.awt.Toolkit;
13 import java.awt.event.ActionEvent;
14 import java.awt.event.ActionListener;
15 import java.awt.event.ItemEvent;
16 import java.awt.event.ItemListener;
17 import java.awt.event.KeyEvent;
18 import java.awt.event.WindowAdapter;
19 import java.awt.event.WindowEvent;
20 import java.beans.PropertyChangeEvent;
21 import java.beans.PropertyChangeListener;
23 import java.io.IOException;
25 import java.nio.file.FileSystem;
26 import java.nio.file.FileSystems;
27 import java.nio.file.Path;
28 import java.util.ArrayList;
29 import java.util.HashSet;
30 import java.util.List;
32 import java.util.SortedSet;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35 import javax.swing.BorderFactory;
36 import javax.swing.DefaultComboBoxModel;
37 import javax.swing.DropMode;
38 import javax.swing.GroupLayout;
39 import javax.swing.GroupLayout.Alignment;
40 import javax.swing.JButton;
41 import javax.swing.JCheckBox;
42 import javax.swing.JFileChooser;
43 import javax.swing.JFrame;
44 import javax.swing.JLabel;
45 import javax.swing.JMenu;
46 import javax.swing.JMenuBar;
47 import javax.swing.JMenuItem;
48 import javax.swing.JOptionPane;
49 import javax.swing.JPanel;
50 import javax.swing.JScrollPane;
51 import javax.swing.JTabbedPane;
52 import javax.swing.JTable;
53 import javax.swing.JTextField;
54 import javax.swing.KeyStroke;
55 import javax.swing.LayoutStyle.ComponentPlacement;
56 import javax.swing.SwingUtilities;
57 import javax.swing.WindowConstants;
58 import javax.swing.border.BevelBorder;
59 import org.apache.commons.configuration.ConfigurationException;
60 import org.apache.commons.lang.builder.ToStringBuilder;
61 import saccubus.MainFrame_AboutBox;
62 import saccubus.util.WayBackTimeParser;
63 import saccubus.worker.profile.CommentProfile;
64 import saccubus.worker.profile.DownloadProfile;
65 import saccubus.worker.profile.FfmpegProfile;
66 import saccubus.worker.profile.GeneralProfile;
67 import saccubus.worker.profile.LoginProfile;
68 import saccubus.worker.profile.OutputProfile;
69 import saccubus.worker.profile.ProxyProfile;
70 import saccubus.worker.profile.VideoProfile;
72 import yukihane.inqubus.config.Config;
73 import yukihane.inqubus.config.ConfigCommentProfile;
74 import yukihane.inqubus.config.ConfigConvertProfile;
75 import yukihane.inqubus.config.ConfigFfmpegProfile;
76 import yukihane.inqubus.config.ConfigGeneralProfile;
77 import yukihane.inqubus.config.ConfigLoginProfile;
78 import yukihane.inqubus.config.ConfigOutputProfile;
79 import yukihane.inqubus.config.ConfigProxyProfile;
80 import yukihane.inqubus.filewatch.FileWatch;
81 import yukihane.inqubus.filewatch.FileWatchUtil;
82 import yukihane.inqubus.manager.RequestProcess;
83 import yukihane.inqubus.manager.TaskKind;
84 import yukihane.inqubus.manager.TaskManage;
85 import yukihane.inqubus.manager.TaskManageListener;
86 import yukihane.inqubus.manager.TaskStatus;
87 import yukihane.inqubus.model.Target;
88 import yukihane.inqubus.model.TargetsTableModel;
94 public class MainFrame extends JFrame {
96 private static final long serialVersionUID = 1L;
97 private static final Logger logger = LoggerFactory.getLogger(MainFrame.class);
98 private final TargetsTableModel targetModel = new TargetsTableModel();
99 private final TaskManage taskManager;
100 private final Thread videoFileWatcherThread;
101 private final FileWatch videoFileWatcher;
102 private final Thread commentFileWatcherThread;
103 private final FileWatch commentFileWatcher;
106 /** Creates new form MainFrame */
109 addWindowListener(new MainFrameWindowListener());
111 final Config p = Config.INSTANCE;
114 final int thDownload = p.getSystemDownloadThread();
115 final int secDownload = p.getSystemDownloadWait();
116 final int thConvert = p.getSystemConvertThread();
117 taskManager = new TaskManage(thDownload, secDownload, thConvert, new GuiTaskManageListener());
120 final FileSystem fs = FileSystems.getDefault();
122 final List<String> videoSearchDirs = p.getSearchVideoDirs();
123 videoSearchDirs.add(p.getVideoDir());
124 final Set<Path> videoPaths = new HashSet<>(videoSearchDirs.size());
125 for (String s : videoSearchDirs) {
126 videoPaths.add(fs.getPath(s));
128 videoFileWatcher = new FileWatch(videoPaths);
129 this.videoFileWatcherThread = new Thread(videoFileWatcher);
130 this.videoFileWatcherThread.setDaemon(true);
132 final List<String> commentSearchDirs = p.getSearchCommentDirs();
133 commentSearchDirs.add(p.getCommentDir());
134 final Set<Path> commentPaths = new HashSet<>(commentSearchDirs.size());
135 for(String s : commentSearchDirs) {
136 commentPaths.add(fs.getPath(s));
138 commentFileWatcher = new FileWatch(commentPaths);
139 this.commentFileWatcherThread = new Thread(commentFileWatcher);
140 this.commentFileWatcherThread.setDaemon(true);
142 final URL url = MainFrame_AboutBox.class.getResource("icon.png");
143 final Image icon1 = Toolkit.getDefaultToolkit().createImage(url);
144 final URL url32 = MainFrame_AboutBox.class.getResource("icon32.png");
145 final Image icon2 = Toolkit.getDefaultToolkit().createImage(url32);
146 final List<Image> images = new ArrayList<>(2);
149 setIconImages(images);
151 final JPanel pnlMain = new JPanel();
152 final JScrollPane scrDisplay = new JScrollPane();
153 tblDisplay = new JTable(targetModel, new TargetsColumnModel());
154 tblDisplay.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
155 final JPanel pnlButton = new JPanel();
156 final JPanel pnlInputMain = new JPanel();
157 final JLabel lblId = new JLabel();
158 final JLabel lblVideo = new JLabel();
159 cbVideoLocal = new JCheckBox();
160 btnVideo.addActionListener(
161 new FileChooseActionListener(MainFrame.this, JFileChooser.FILES_ONLY, fldVideo));
162 fldVideo.setTransferHandler(new ContentTransferHandler(fldVideo.getTransferHandler(), cbVideoLocal));
163 final JLabel lblComment = new JLabel();
165 fldBackLog.setToolTipText("YYYY/MM/DD hh:mm:ss形式、あるいは1970/01/01からの経過秒を入力します。");
166 cbBackLog.addItemListener(new ItemListener() {
169 public void itemStateChanged(ItemEvent e) {
170 final boolean selected = (e.getStateChange() == ItemEvent.SELECTED);
171 fldBackLog.setEnabled(selected);
174 cbBackLog.addPropertyChangeListener("enabled", new PropertyChangeListener() {
177 public void propertyChange(PropertyChangeEvent evt) {
178 final boolean enabled = ((Boolean) evt.getNewValue()).booleanValue();
179 final boolean fldEnabled = enabled ? cbBackLog.isSelected() : false;
180 fldBackLog.setEnabled(fldEnabled);
183 cbBackLogReduce.setToolTipText("「コメントの量を減らす」場合はチェックを付けます。");
185 cbCommentLocal = new JCheckBox();
186 cbCommentLocal.addItemListener(new ItemListener() {
189 public void itemStateChanged(ItemEvent e) {
190 final boolean selected = (e.getStateChange() == ItemEvent.SELECTED);
191 cbBackLogReduce.setEnabled(!selected);
192 cbBackLog.setEnabled(!selected);
195 btnComment.addActionListener(
196 new FileChooseActionListener(MainFrame.this, JFileChooser.FILES_ONLY, fldComment));
197 fldComment.setTransferHandler(new ContentTransferHandler(fldComment.getTransferHandler(), cbCommentLocal));
198 final JLabel lblOutput = new JLabel();
199 cbOutputEnable = new JCheckBox();
200 fldOutput = new JTextField();
202 setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
204 btnStop.addActionListener(new StopActionListener());
205 final ApplyActionListener applyListener = new ApplyActionListener();
206 btnApply.addActionListener(applyListener);
207 btnClear.addActionListener(new ActionListener() {
210 public void actionPerformed(ActionEvent e) {
215 pnlMain.setBorder(BorderFactory.createEtchedBorder());
217 tblDisplay.setDropMode(DropMode.INSERT_ROWS);
218 scrDisplay.setViewportView(tblDisplay);
220 pnlButton.setBorder(BorderFactory.createEtchedBorder());
222 GroupLayout gl_pnlButton = new GroupLayout(pnlButton);
223 pnlButton.setLayout(gl_pnlButton);
224 gl_pnlButton.setHorizontalGroup(
225 gl_pnlButton.createParallelGroup(Alignment.LEADING)
226 .addGroup(gl_pnlButton.createSequentialGroup()
228 .addPreferredGap(ComponentPlacement.RELATED)
229 .addComponent(btnStop)
230 .addPreferredGap(ComponentPlacement.RELATED, 250, Short.MAX_VALUE)
233 gl_pnlButton.setVerticalGroup(
234 gl_pnlButton.createParallelGroup(Alignment.LEADING)
235 .addGroup(gl_pnlButton.createSequentialGroup()
237 .addGroup(gl_pnlButton.createParallelGroup(Alignment.BASELINE)
238 .addComponent(btnStop)
240 .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
247 cmbId = new IdComboBox(videoFileWatcher);
248 cmbId.getEditorComponent().addActionListener(applyListener);
249 cmbId.getEditorComponent().addFocusListener(new java.awt.event.FocusAdapter() {
251 public void focusLost(java.awt.event.FocusEvent evt) {
252 idFieldFocusLost(evt);
256 lblVideo.setText("動画");
258 cbVideoLocal.setText("local");
259 cbVideoLocal.addItemListener(new java.awt.event.ItemListener() {
261 public void itemStateChanged(java.awt.event.ItemEvent evt) {
262 useMovieLocalCheckBoxItemStateChanged(evt);
266 lblComment.setText("コメント");
268 cbCommentLocal.setText("local");
269 cbCommentLocal.addItemListener(new java.awt.event.ItemListener() {
271 public void itemStateChanged(java.awt.event.ItemEvent evt) {
272 useMovieLocalCheckBoxItemStateChanged(evt);
276 lblOutput.setText("出力");
278 cbOutputEnable.setText("変換");
279 cbOutputEnable.addItemListener(new java.awt.event.ItemListener() {
281 public void itemStateChanged(java.awt.event.ItemEvent evt) {
282 outputConvertCheckBoxItemStateChanged(evt);
287 final GroupLayout glInputMain = new GroupLayout(pnlInputMain);
288 pnlInputMain.setLayout(glInputMain);
289 glInputMain.setHorizontalGroup(
290 glInputMain.createParallelGroup(Alignment.LEADING)
291 .addGroup(glInputMain.createSequentialGroup()
294 .addPreferredGap(ComponentPlacement.RELATED)
295 .addComponent(cmbId, GroupLayout.PREFERRED_SIZE, 100, Short.MAX_VALUE)
296 .addPreferredGap(ComponentPlacement.UNRELATED)
297 .addComponent(cbBackLogReduce)
298 .addPreferredGap(ComponentPlacement.UNRELATED)
299 .addComponent(cbBackLog)
300 .addPreferredGap(ComponentPlacement.RELATED)
301 .addComponent(fldBackLog, GroupLayout.PREFERRED_SIZE, 150, GroupLayout.PREFERRED_SIZE)
304 .addGroup(glInputMain.createSequentialGroup()
306 .addGroup(glInputMain.createParallelGroup(Alignment.LEADING)
307 .addComponent(lblVideo)
308 .addComponent(lblComment)
309 .addComponent(lblOutput)
311 .addPreferredGap(ComponentPlacement.RELATED)
312 .addGroup(glInputMain.createParallelGroup(Alignment.LEADING)
313 .addComponent(cbVideoLocal)
314 .addComponent(cbCommentLocal)
315 .addComponent(cbOutputEnable)
317 .addPreferredGap(ComponentPlacement.RELATED)
318 .addGroup(glInputMain.createParallelGroup(Alignment.LEADING)
319 .addComponent(cmbVideo, 300, 300, Short.MAX_VALUE)
320 .addComponent(cmbComment, 300, 300, Short.MAX_VALUE)
321 .addComponent(fldOutput, 300, 300, Short.MAX_VALUE)
323 .addGroup(glInputMain.createParallelGroup()
324 .addComponent(btnVideo)
325 .addComponent(btnComment)
331 glInputMain.setVerticalGroup(
332 glInputMain.createParallelGroup(Alignment.LEADING)
333 .addGroup(glInputMain.createSequentialGroup()
335 .addGroup(glInputMain.createParallelGroup(Alignment.BASELINE)
336 .addComponent(cmbId, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
338 .addComponent(cbBackLogReduce)
339 .addComponent(cbBackLog)
340 .addComponent(fldBackLog)
342 .addPreferredGap(ComponentPlacement.RELATED)
343 .addGroup(glInputMain.createParallelGroup(Alignment.BASELINE)
344 .addComponent(lblVideo)
345 .addComponent(cbVideoLocal)
346 .addComponent(cmbVideo, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
347 .addComponent(btnVideo)
349 .addPreferredGap(ComponentPlacement.RELATED)
350 .addGroup(glInputMain.createParallelGroup(Alignment.BASELINE)
351 .addComponent(lblComment)
352 .addComponent(cbCommentLocal)
353 .addComponent(cmbComment, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
354 .addComponent(btnComment)
356 .addPreferredGap(ComponentPlacement.RELATED)
357 .addGroup(glInputMain.createParallelGroup(Alignment.BASELINE)
358 .addComponent(lblOutput)
359 .addComponent(fldOutput, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
360 .addComponent(cbOutputEnable)
366 pnlInputFfmpeg.fldFfmpegOptionResizeWidth.setEnabled(false);
367 pnlInputFfmpeg.fldFfmpegOptionResizeHeight.setEnabled(false);
368 pnlInputFfmpeg.cbFfmpegOptionKeepAspect.setEnabled(false);
369 pnlInputFfmpeg.cmbFfmpegOptionFile.addActionListener(new ActionListener() {
372 public void actionPerformed(ActionEvent e) {
373 final boolean notFile = !pnlInputFfmpeg.mdlFfmpegOption.isFile();
374 pnlInputFfmpeg.fldFfmpegOptionExtension.setEnabled(notFile);
375 pnlInputFfmpeg.fldFfmpegOptionMain.setEnabled(notFile);
376 pnlInputFfmpeg.fldFfmpegOptionIn.setEnabled(notFile);
377 pnlInputFfmpeg.fldFfmpegOptionOut.setEnabled(notFile);
378 pnlInputFfmpeg.fldFfmpegOptionAv.setEnabled(notFile);
379 pnlInputFfmpeg.cbFfmpegOptionResize.setEnabled(notFile);
382 pnlInputFfmpeg.cbFfmpegOptionResize.addItemListener(new ItemListener() {
385 public void itemStateChanged(ItemEvent e) {
386 final boolean selected = (e.getStateChange() == ItemEvent.SELECTED);
387 pnlInputFfmpeg.fldFfmpegOptionResizeWidth.setEnabled(selected);
388 pnlInputFfmpeg.fldFfmpegOptionResizeHeight.setEnabled(selected);
389 pnlInputFfmpeg.cbFfmpegOptionKeepAspect.setEnabled(selected);
392 pnlInputFfmpeg.cbFfmpegOptionResize.addPropertyChangeListener("enabled", new PropertyChangeListener() {
395 public void propertyChange(PropertyChangeEvent evt) {
396 final boolean enabled = ((Boolean) evt.getNewValue()).booleanValue();
397 final boolean fldEnabled = enabled ? pnlInputFfmpeg.cbFfmpegOptionResize.isSelected() : false;
398 pnlInputFfmpeg.fldFfmpegOptionResizeWidth.setEnabled(fldEnabled);
399 pnlInputFfmpeg.fldFfmpegOptionResizeHeight.setEnabled(fldEnabled);
400 pnlInputFfmpeg.cbFfmpegOptionKeepAspect.setEnabled(fldEnabled);
405 tbpInput.add("メイン", pnlInputMain);
406 tbpInput.add("ffmpeg", pnlInputFfmpeg);
409 fldInputMessage.setEditable(false);
410 fldInputMessage.setEnabled(false);
411 fldInputMessage.setBorder(BorderFactory.createEmptyBorder());
413 final JPanel pnlInputButton = new JPanel();
414 final GroupLayout glInputButton = new GroupLayout(pnlInputButton);
415 pnlInputButton.setLayout(glInputButton);
416 glInputButton.setHorizontalGroup(glInputButton.createSequentialGroup()
418 .addComponent(fldInputMessage, GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
419 .addPreferredGap(ComponentPlacement.UNRELATED)
420 .addComponent(btnClear)
421 .addPreferredGap(ComponentPlacement.UNRELATED)
422 .addComponent(btnApply)
425 glInputButton.setVerticalGroup(glInputButton.createSequentialGroup()
427 .addGroup(glInputButton.createParallelGroup(Alignment.BASELINE)
428 .addComponent(fldInputMessage, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
429 .addComponent(btnClear)
430 .addComponent(btnApply)
436 final JPanel pnlInputAll = new JPanel();
437 pnlInputAll.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
438 final GroupLayout glInputAll = new GroupLayout(pnlInputAll);
439 pnlInputAll.setLayout(glInputAll);
440 glInputAll.setHorizontalGroup(glInputAll.createParallelGroup()
441 .addComponent(tbpInput)
442 .addComponent(pnlInputButton)
444 glInputAll.setVerticalGroup(glInputAll.createSequentialGroup()
445 .addComponent(tbpInput)
446 .addComponent(pnlInputButton)
449 GroupLayout gl_pnlMain = new GroupLayout(pnlMain);
450 pnlMain.setLayout(gl_pnlMain);
451 gl_pnlMain.setHorizontalGroup(
452 gl_pnlMain.createParallelGroup(Alignment.LEADING)
453 .addGroup(Alignment.TRAILING, gl_pnlMain.createSequentialGroup()
455 .addGroup(gl_pnlMain.createParallelGroup(Alignment.TRAILING)
456 .addComponent(scrDisplay, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 480, Short.MAX_VALUE)
457 .addComponent(pnlButton, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
458 .addComponent(pnlInputAll, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
462 gl_pnlMain.setVerticalGroup(
463 gl_pnlMain.createParallelGroup(Alignment.LEADING)
464 .addGroup(Alignment.TRAILING, gl_pnlMain.createSequentialGroup()
466 .addComponent(scrDisplay, GroupLayout.DEFAULT_SIZE, 197, Short.MAX_VALUE)
467 .addPreferredGap(ComponentPlacement.RELATED)
468 .addComponent(pnlButton, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
469 .addPreferredGap(ComponentPlacement.RELATED)
470 .addComponent(pnlInputAll, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
476 JMenuBar menuBar = initMenuBar();
477 setJMenuBar(menuBar);
479 GroupLayout layout = new GroupLayout(getContentPane());
480 getContentPane().setLayout(layout);
481 layout.setHorizontalGroup(
482 layout.createParallelGroup(Alignment.LEADING)
483 .addComponent(pnlMain, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
485 layout.setVerticalGroup(
486 layout.createParallelGroup(Alignment.LEADING)
487 .addComponent(pnlMain, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
491 setMinimumSize(getSize());
494 * 画面のサイズや位置を前回終了時のものに設定する
496 final int windowWidth = p.getSystemWindowWidth();
497 final int windowHeight = p.getSystemWindowHeight();
498 if (windowWidth > 0 && windowHeight > 0) {
499 setSize(windowWidth, windowHeight);
502 final int windowPosX = p.getSystemWindowPosX();
503 final int windowPosY = p.getSystemWindowPosY();
504 final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
505 if (windowPosX + windowWidth > 0 && windowPosX < screenSize.width
506 && windowPosY + windowHeight > 0 && windowPosY < screenSize.height) {
507 setLocation(windowPosX, windowPosY);
509 setLocationByPlatform(true);
512 final int colId = p.getSystemColumnId();
514 tblDisplay.getColumnModel().getColumn(0).setPreferredWidth(colId);
516 final int colStatus = p.getSystemColumnStatus();
518 tblDisplay.getColumnModel().getColumn(4).setPreferredWidth(colStatus);
524 public void startWatcher() {
525 videoFileWatcherThread.start();
526 commentFileWatcherThread.start();
529 private static void createFieldInfo( FileComboBox combo, boolean useLocal, String text, String pattern, Set<Path> allFiles) {
531 final SortedSet<String> matchFiles = FileWatchUtil.getFileNamesContain(allFiles, text);
532 DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>(matchFiles.toArray(new String[0]));
533 combo.setModel(model);
535 combo.setModel(new DefaultComboBoxModel<String>());
536 combo.getEditorComponent().setText(pattern);
540 private class GuiTaskManageListener implements TaskManageListener {
543 public void process(final int id, final TaskKind kind, final TaskStatus status, final double percentage,
544 final String message) {
545 SwingUtilities.invokeLater(new Runnable() {
549 targetModel.setStatus(id, kind, status, percentage, message);
555 private class StopActionListener implements ActionListener {
558 public void actionPerformed(ActionEvent e) {
559 final int row = tblDisplay.getSelectedRow();
560 final Target t = targetModel.getTarget(row);
561 final boolean res = taskManager.cancel(t.getRowId());
562 logger.debug("停止: {} {}", t.getVideoId(), res);
564 targetModel.setStatus(t.getRowId(), null, TaskStatus.CANCELLED, -1.0, "キャンセル");
569 private class ApplyActionListener implements ActionListener {
572 public void actionPerformed(ActionEvent e) {
574 final DownloadProfile downProf = new InqubusDownloadProfile();
575 final String id = Util.getVideoId(cmbId.getText());
576 final InqubusConvertProfile convProf = new InqubusConvertProfile();
577 logger.debug(downProf.toString());
578 logger.debug(convProf.toString());
579 final RequestProcess rp = new RequestProcess(downProf, id, convProf);
581 targetModel.addTarget(new Target(rp));
583 } catch (Throwable th) {
584 logger.error(null, th);
585 JOptionPane.showMessageDialog(MainFrame.this, th.getMessage(), "中断しました", JOptionPane.ERROR_MESSAGE);
591 * 動画, コメントの"local"チェックボックス更新時の処理.
593 private void useMovieLocalCheckBoxItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_useMovieLocalCheckBoxItemStateChanged
594 final Config p = Config.INSTANCE;
596 final ItemSelectable source = evt.getItemSelectable();
602 if (source == cbVideoLocal) {
605 allFiles = videoFileWatcher.getFiles();
606 pattern = p.getVideoFileNamePattern();
610 allFiles = commentFileWatcher.getFiles();
611 pattern = p.getCommentFileNamePattern();
614 final boolean useLocal = (evt.getStateChange() == ItemEvent.SELECTED);
616 button.setEnabled(useLocal);
617 createFieldInfo(combo, useLocal, cmbId.getText(), pattern, allFiles);
621 private void outputConvertCheckBoxItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_outputConvertCheckBoxItemStateChanged
622 final boolean convert = (evt.getStateChange() == ItemEvent.SELECTED);
623 fldOutput.setEnabled(convert);
624 }//GEN-LAST:event_outputConvertCheckBoxItemStateChanged
626 private void idFieldFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_idFieldFocusLost
627 final Config p = Config.INSTANCE;
628 final String id = cmbId.getText();
630 createFieldInfo(cmbVideo, cbVideoLocal.isSelected(), id, p.getVideoFileNamePattern(), videoFileWatcher.getFiles());
631 createFieldInfo(cmbComment, cbCommentLocal.isSelected(), id, p.getCommentFileNamePattern(), commentFileWatcher.getFiles());
632 }//GEN-LAST:event_idFieldFocusLost
633 // Variables declaration - do not modify//GEN-BEGIN:variables
634 private final JTable tblDisplay;
636 private final JButton btnStop = new JButton("停止");
638 private final JTabbedPane tbpInput = new JTabbedPane(JTabbedPane.BOTTOM);
640 private final IdComboBox cmbId;
641 private final JCheckBox cbBackLogReduce = new JCheckBox("少コメ");
642 private final JCheckBox cbBackLog = new JCheckBox("過去ログ");
643 private final JTextField fldBackLog = new JTextField();
644 private final JCheckBox cbVideoLocal;
645 private final FileComboBox cmbVideo = new FileComboBox();
646 private final JTextField fldVideo = cmbVideo.getEditorComponent();
647 private final JButton btnVideo = new JButton("...");
648 private final JCheckBox cbCommentLocal;
649 private final FileComboBox cmbComment = new FileComboBox();
650 private final JTextField fldComment = cmbComment.getEditorComponent();
651 private final JButton btnComment = new JButton("...");
652 private final JCheckBox cbOutputEnable;
653 private final JTextField fldOutput;
655 private final FfmpegParamPanel pnlInputFfmpeg = new FfmpegParamPanel();
657 private final JTextField fldInputMessage = new JTextField();
658 private final JButton btnClear = new JButton("クリア");
659 private final JButton btnApply = new JButton("適用");
660 // End of variables declaration//GEN-END:variables
662 private void initInputPanel() {
665 tbpInput.setSelectedIndex(0);
666 cmbId.requestFocus();
669 private void initMainTab() {
670 final Config p = Config.INSTANCE;
673 cbBackLogReduce.setSelected(p.getCommentMinDisabled());
674 cbBackLog.setEnabled(true);
675 cbBackLog.setSelected(false);
676 fldBackLog.setEnabled(false);
677 fldBackLog.setText("");
679 final boolean videoLocal = p.getVideoUseLocal();
680 cbVideoLocal.setSelected(videoLocal);
682 fldVideo.setText(p.getVideoFileNamePattern());
684 btnVideo.setEnabled(videoLocal);
686 final boolean commentLocal = p.getCommentUseLocal();
687 cbCommentLocal.setSelected(commentLocal);
689 fldComment.setText(p.getCommentFileNamePattern());
691 btnComment.setEnabled(commentLocal);
693 final boolean convert = p.getOutputEnable();
694 cbOutputEnable.setSelected(convert);
695 fldOutput.setEnabled(convert);
696 fldOutput.setText(p.getOutputFileNamePattern());
699 private void initFfmpegTab() {
700 pnlInputFfmpeg.init(Config.INSTANCE);
703 private JMenuBar initMenuBar() {
704 final JMenuBar menuBar = new JMenuBar();
706 final JMenu mnFile = new JMenu("ファイル(F)");
709 final JMenuItem itExit = new JMenuItem("終了(X)", KeyEvent.VK_X);
710 itExit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.CTRL_MASK));
711 final ActionListener exitActionListener = new ActionListener() {
714 public void actionPerformed(ActionEvent e) {
715 processWindowEvent(new WindowEvent(MainFrame.this, WindowEvent.WINDOW_CLOSING));
718 itExit.addActionListener(exitActionListener);
721 final JMenu mnTool = new JMenu("ツール(T)");
724 final JMenuItem itOption = new JMenuItem("オプション(O)...", KeyEvent.VK_O);
725 itOption.addActionListener(new ActionListener() {
728 public void actionPerformed(ActionEvent e) {
729 final yukihane.inqubus.gui.ConfigDialog dlg = new yukihane.inqubus.gui.ConfigDialog(MainFrame.this);
730 dlg.setLocationRelativeTo(MainFrame.this);
732 dlg.setVisible(true);
735 mnTool.add(itOption);
737 final JMenu mnHelp = new JMenu("ヘルプ(H)");
740 final JMenuItem itAbout = new JMenuItem("このソフトウェアについて(A)...", KeyEvent.VK_A);
741 itAbout.addActionListener(new ActionListener() {
744 public void actionPerformed(ActionEvent e) {
745 MainFrame_AboutBox dlg = new MainFrame_AboutBox(MainFrame.this);
747 dlg.setLocationRelativeTo(MainFrame.this);
749 dlg.setVisible(true);
757 private class MainFrameWindowListener extends WindowAdapter {
759 public void windowClosing(WindowEvent e) {
760 final Config p = Config.INSTANCE;
762 // 保存するのは最大化していない場合だけ
763 if (JFrame.NORMAL == getExtendedState()) {
764 final Dimension size = getSize();
765 p.setSystemWindowWidth(size.width);
766 p.setSystemWindowHeight(size.height);
768 final Point pos = getLocation();
769 p.setSystemWindowPosX(pos.x);
770 p.setSystemWindowPosY(pos.y);
773 p.setSystemColumnId(tblDisplay.getColumnModel().getColumn(0).getWidth());
774 p.setSystemColumnVideo(tblDisplay.getColumnModel().getColumn(1).getWidth());
775 p.setSystemColumnComment(tblDisplay.getColumnModel().getColumn(2).getWidth());
776 p.setSystemColumnConvert(tblDisplay.getColumnModel().getColumn(3).getWidth());
777 p.setSystemColumnStatus(tblDisplay.getColumnModel().getColumn(4).getWidth());
780 } catch (ConfigurationException ex) {
781 logger.error("コンフィグ保存失敗", ex);
787 * ここからDownloadProfile作成用クラスの定義
789 private class InqubusDownloadProfile implements DownloadProfile {
791 private final LoginProfile loginProfile;
792 private final ProxyProfile proxyProfile;
793 private final VideoProfile videoProfile;
794 private final CommentProfile commentProfile;
795 private final GeneralProfile generalProfile;
797 private InqubusDownloadProfile() {
798 this.loginProfile = new ConfigLoginProfile();
799 this.proxyProfile = new ConfigProxyProfile();
800 this.videoProfile = new InqubusVideoProfile();
801 this.commentProfile = new InqubusCommentProfile();
802 this.generalProfile = new ConfigGeneralProfile();
806 public LoginProfile getLoginProfile() {
807 return this.loginProfile;
811 public ProxyProfile getProxyProfile() {
812 return this.proxyProfile;
816 public VideoProfile getVideoProfile() {
817 return this.videoProfile;
821 public CommentProfile getCommentProfile() {
822 return this.commentProfile;
826 public GeneralProfile getGeneralProfile() {
827 return this.generalProfile;
831 public String toString(){
832 return ToStringBuilder.reflectionToString(this);
836 private class InqubusVideoProfile implements VideoProfile {
837 private final boolean download;
838 private final File dir;
839 private final String fileName;
840 private final File localFile;
842 private InqubusVideoProfile(){
843 final Config p = Config.INSTANCE;
844 this.download = !cbVideoLocal.isSelected();
846 this.dir = new File(p.getVideoDir());
847 this.fileName = fldVideo.getText();
848 this.localFile = null;
851 this.fileName = null;
852 this.localFile = new File(fldVideo.getText());
857 public boolean isDownload() {
858 return this.download;
862 public File getDir() {
867 public String getFileName() {
868 return this.fileName;
872 public File getLocalFile() {
873 return this.localFile;
877 public String toString(){
878 return ToStringBuilder.reflectionToString(this);
882 private class InqubusCommentProfile extends ConfigCommentProfile {
883 private final boolean download;
884 private final File dir;
885 private final String fileName;
886 private final File localFile;
887 private final boolean disablePerMinComment;
888 private final long backLogPoint;
890 private InqubusCommentProfile() {
893 final Config p = Config.INSTANCE;
894 this.download = !cbCommentLocal.isSelected();
896 this.dir = new File(p.getCommentDir());
897 this.fileName = fldComment.getText();
898 this.localFile = null;
901 this.fileName = null;
902 this.localFile = new File(fldComment.getText());
905 if(cbBackLog.isSelected()) {
907 this.backLogPoint = WayBackTimeParser.parse(fldBackLog.getText());
908 } catch (IOException ex) {
909 throw new IllegalArgumentException("過去ログ時刻指定が誤っています。", ex);
912 this.backLogPoint = -1L;
915 this.disablePerMinComment = cbBackLogReduce.isSelected();
919 public boolean isDownload() {
920 return this.download;
924 public File getDir() {
929 public String getFileName() {
930 return this.fileName;
934 public File getLocalFile() {
935 return this.localFile;
939 public boolean isDisablePerMinComment() {
940 return this.disablePerMinComment;
944 public long getBackLogPoint() {
945 return this.backLogPoint;
949 public String toString(){
950 return ToStringBuilder.reflectionToString(this);
955 * ここからConvertProfile作成用クラスの定義
957 private class InqubusConvertProfile extends ConfigConvertProfile {
958 private final OutputProfile outputProfile;
959 private final GeneralProfile generalProfile;
960 private final FfmpegProfile ffmpegProfile;
961 private final boolean convert;
963 private InqubusConvertProfile() throws IOException {
964 this.outputProfile = new InqubusOutputProfile();
965 this.generalProfile = new ConfigGeneralProfile();
967 final File file = pnlInputFfmpeg.mdlFfmpegOption.getSelectedFile();
969 this.ffmpegProfile = new ConfigFfmpegProfile();
971 this.ffmpegProfile = new InqubusFfmpegProfile();
974 this.convert = cbOutputEnable.isSelected();
978 public OutputProfile getOutputProfile() {
979 return this.outputProfile;
983 public GeneralProfile getGeneralProfile() {
984 return this.generalProfile;
988 public FfmpegProfile getFfmpegOption() {
989 return this.ffmpegProfile;
993 public boolean isConvert() {
998 public String toString(){
999 return ToStringBuilder.reflectionToString(this);
1003 private class InqubusOutputProfile extends ConfigOutputProfile {
1004 private final String fileName;
1005 private final String videoId;
1006 private final String title;
1009 private InqubusOutputProfile() {
1010 this.fileName = fldOutput.getText();
1011 // TODO この時点でのID/Titleはどうするか…
1017 public String getFileName() {
1018 return this.fileName;
1022 public String getVideoId() {
1023 return this.videoId;
1027 public String getTitile() {
1032 public String toString(){
1033 return ToStringBuilder.reflectionToString(this);
1037 private class InqubusFfmpegProfile implements FfmpegProfile {
1038 private final String extOption;
1039 private final String inOption;
1040 private final String mainOption;
1041 private final String outOption;
1042 private final String avOption;
1043 private final boolean resize;
1044 private final int resizeWidth;
1045 private final int resizeHeight;
1046 private final boolean adjustRatio;
1048 private InqubusFfmpegProfile() throws IOException {
1049 String ext = pnlInputFfmpeg.fldFfmpegOptionExtension.getText();
1050 if (!ext.startsWith(".")) {
1053 this.extOption = ext;
1054 this.inOption = pnlInputFfmpeg.fldFfmpegOptionIn.getText();
1055 this.mainOption = pnlInputFfmpeg.fldFfmpegOptionMain.getText();
1056 this.outOption = pnlInputFfmpeg.fldFfmpegOptionOut.getText();
1057 this.avOption = pnlInputFfmpeg.fldFfmpegOptionAv.getText();
1058 this.resize = pnlInputFfmpeg.cbFfmpegOptionResize.isSelected();
1059 this.resizeWidth = Integer.parseInt(pnlInputFfmpeg.fldFfmpegOptionResizeWidth.getText());
1060 this.resizeHeight = Integer.parseInt(pnlInputFfmpeg.fldFfmpegOptionResizeHeight.getText());
1061 this.adjustRatio = pnlInputFfmpeg.cbFfmpegOptionKeepAspect.isSelected();
1065 public String getExtOption() {
1066 return this.extOption;
1070 public String getInOption() {
1071 return this.inOption;
1075 public String getMainOption() {
1076 return this.mainOption;
1080 public String getOutOption() {
1081 return this.outOption;
1085 public String getAvfilterOption() {
1086 return this.avOption;
1090 public boolean isResize() {
1095 public int getResizeWidth() {
1096 return this.resizeWidth;
1100 public int getResizeHeight() {
1101 return this.resizeHeight;
1105 public boolean isAdjustRatio() {
1106 return this.adjustRatio;
1110 public String toString(){
1111 return ToStringBuilder.reflectionToString(this);