4 * Created on 2011/05/28, 18:14:51
6 package yukihane.inqubus.gui;
8 import java.awt.ItemSelectable;
9 import java.awt.datatransfer.DataFlavor;
10 import java.awt.datatransfer.Transferable;
11 import java.awt.event.ItemEvent;
13 import java.io.FilenameFilter;
14 import java.util.Collection;
15 import java.util.List;
16 import java.util.logging.Level;
17 import java.util.logging.Logger;
18 import java.util.regex.Matcher;
19 import java.util.regex.Pattern;
20 import javax.swing.JButton;
21 import javax.swing.JTextField;
22 import javax.swing.TransferHandler;
23 import javax.swing.UIManager;
24 import javax.swing.UIManager.LookAndFeelInfo;
25 import yukihane.inqubus.config.Properties;
26 import yukihane.inqubus.model.Target;
27 import yukihane.inqubus.model.TargetsTableModel;
33 public class MainFrame extends javax.swing.JFrame {
35 private static final long serialVersionUID = 1L;
36 private static final Logger logger = Logger.getLogger(MainFrame.class.getName());
37 private final TargetsTableModel targetModel = new TargetsTableModel();
39 /** Creates new form MainFrame */
43 jPanel1.setTransferHandler(new DownloadListTransferHandler());
44 jTable1.setTransferHandler(new TableTransferHandler());
47 /** This method is called from within the constructor to
48 * initialize the form.
49 * WARNING: Do NOT modify this code. The content of this method is
50 * always regenerated by the Form Editor.
52 @SuppressWarnings("unchecked")
53 // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
54 private void initComponents() {
56 jPanel1 = new javax.swing.JPanel();
57 jScrollPane1 = new javax.swing.JScrollPane();
58 jTable1 = new javax.swing.JTable();
59 jPanel2 = new javax.swing.JPanel();
60 jButton2 = new javax.swing.JButton();
61 jButton3 = new javax.swing.JButton();
62 jButton4 = new javax.swing.JButton();
63 jPanel3 = new javax.swing.JPanel();
64 idLabel = new javax.swing.JLabel();
65 idField = new javax.swing.JTextField();
66 movieLabel = new javax.swing.JLabel();
67 useMovieLocalCheckBox = new javax.swing.JCheckBox();
68 movieFileField = new javax.swing.JTextField();
69 movieFileSelectButton = new javax.swing.JButton();
70 commentLabel = new javax.swing.JLabel();
71 useCommentLocalCheckBox = new javax.swing.JCheckBox();
72 commentFileField = new javax.swing.JTextField();
73 commentFileSelectButton = new javax.swing.JButton();
74 outputLabel = new javax.swing.JLabel();
75 outputConvertCheckBox = new javax.swing.JCheckBox();
76 outputFileField = new javax.swing.JTextField();
77 applyButton = new javax.swing.JButton();
78 jMenuBar1 = new javax.swing.JMenuBar();
79 jMenu1 = new javax.swing.JMenu();
80 jMenu2 = new javax.swing.JMenu();
82 setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
84 jPanel1.setBorder(javax.swing.BorderFactory.createEtchedBorder());
86 jTable1.setModel(targetModel);
87 jTable1.setDropMode(javax.swing.DropMode.INSERT_ROWS);
88 jScrollPane1.setViewportView(jTable1);
90 jPanel2.setBorder(javax.swing.BorderFactory.createEtchedBorder());
92 jButton2.setText("開始");
94 jButton3.setText("停止");
96 jButton4.setText("選択解除");
98 javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
99 jPanel2.setLayout(jPanel2Layout);
100 jPanel2Layout.setHorizontalGroup(
101 jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
102 .addGroup(jPanel2Layout.createSequentialGroup()
104 .addComponent(jButton2)
105 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
106 .addComponent(jButton3)
107 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 250, Short.MAX_VALUE)
108 .addComponent(jButton4)
111 jPanel2Layout.setVerticalGroup(
112 jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
113 .addGroup(jPanel2Layout.createSequentialGroup()
115 .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
116 .addComponent(jButton2)
117 .addComponent(jButton3)
118 .addComponent(jButton4))
119 .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
122 jPanel3.setBorder(javax.swing.BorderFactory.createEtchedBorder());
124 idLabel.setText("ID");
126 idField.addFocusListener(new java.awt.event.FocusAdapter() {
127 public void focusLost(java.awt.event.FocusEvent evt) {
128 idFieldFocusLost(evt);
132 movieLabel.setText("動画");
134 useMovieLocalCheckBox.setText("local");
135 useMovieLocalCheckBox.addItemListener(new java.awt.event.ItemListener() {
136 public void itemStateChanged(java.awt.event.ItemEvent evt) {
137 useMovieLocalCheckBoxItemStateChanged(evt);
141 movieFileSelectButton.setText("...");
143 commentLabel.setText("コメント");
145 useCommentLocalCheckBox.setText("local");
146 useCommentLocalCheckBox.addItemListener(new java.awt.event.ItemListener() {
147 public void itemStateChanged(java.awt.event.ItemEvent evt) {
148 useMovieLocalCheckBoxItemStateChanged(evt);
152 commentFileSelectButton.setText("...");
154 outputLabel.setText("出力");
156 outputConvertCheckBox.setText("変換");
157 outputConvertCheckBox.addItemListener(new java.awt.event.ItemListener() {
158 public void itemStateChanged(java.awt.event.ItemEvent evt) {
159 outputConvertCheckBoxItemStateChanged(evt);
163 applyButton.setText("適用");
165 javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
166 jPanel3.setLayout(jPanel3Layout);
167 jPanel3Layout.setHorizontalGroup(
168 jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
169 .addGroup(jPanel3Layout.createSequentialGroup()
171 .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
172 .addGroup(jPanel3Layout.createSequentialGroup()
173 .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
174 .addComponent(commentLabel)
175 .addComponent(movieLabel)
176 .addComponent(idLabel)
177 .addComponent(outputLabel))
178 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
179 .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
180 .addGroup(jPanel3Layout.createSequentialGroup()
181 .addComponent(useMovieLocalCheckBox)
182 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
183 .addComponent(movieFileField, javax.swing.GroupLayout.DEFAULT_SIZE, 317, Short.MAX_VALUE)
184 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
185 .addComponent(movieFileSelectButton))
186 .addComponent(idField, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
187 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup()
188 .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
189 .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel3Layout.createSequentialGroup()
190 .addComponent(outputConvertCheckBox)
191 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
192 .addComponent(outputFileField, javax.swing.GroupLayout.DEFAULT_SIZE, 317, Short.MAX_VALUE))
193 .addGroup(jPanel3Layout.createSequentialGroup()
194 .addComponent(useCommentLocalCheckBox)
195 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
196 .addComponent(commentFileField, javax.swing.GroupLayout.DEFAULT_SIZE, 317, Short.MAX_VALUE)))
197 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
198 .addComponent(commentFileSelectButton))))
199 .addComponent(applyButton, javax.swing.GroupLayout.Alignment.TRAILING))
202 jPanel3Layout.setVerticalGroup(
203 jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
204 .addGroup(jPanel3Layout.createSequentialGroup()
206 .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
207 .addComponent(idField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
208 .addComponent(idLabel))
209 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
210 .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
211 .addComponent(movieLabel)
212 .addComponent(movieFileField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
213 .addComponent(movieFileSelectButton)
214 .addComponent(useMovieLocalCheckBox))
215 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
216 .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
217 .addComponent(commentLabel)
218 .addComponent(commentFileField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
219 .addComponent(commentFileSelectButton)
220 .addComponent(useCommentLocalCheckBox))
221 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
222 .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
223 .addComponent(outputLabel)
224 .addComponent(outputFileField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
225 .addComponent(outputConvertCheckBox))
226 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
227 .addComponent(applyButton)
228 .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
231 javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
232 jPanel1.setLayout(jPanel1Layout);
233 jPanel1Layout.setHorizontalGroup(
234 jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
235 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
237 .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
238 .addComponent(jPanel3, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
239 .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 480, Short.MAX_VALUE)
240 .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
243 jPanel1Layout.setVerticalGroup(
244 jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
245 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
247 .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 197, Short.MAX_VALUE)
248 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
249 .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
250 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
251 .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
255 jMenu1.setText("File");
256 jMenuBar1.add(jMenu1);
258 jMenu2.setText("Edit");
259 jMenuBar1.add(jMenu2);
261 setJMenuBar(jMenuBar1);
263 javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
264 getContentPane().setLayout(layout);
265 layout.setHorizontalGroup(
266 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
267 .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
269 layout.setVerticalGroup(
270 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
271 .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
275 }// </editor-fold>//GEN-END:initComponents
277 private File searchFileMatchId(final File dir, final String id) throws UnsupportedOperationException {
278 // TODO 候補は複数返すようにして、その後の対処は呼び出しもとで行ってもらった方が良いかも
283 final File[] lists = dir.listFiles(new FilenameFilter() {
285 final Pattern pattern = Pattern.compile(id + "\\D");
288 public boolean accept(File dir, String name) {
289 return pattern.matcher(name).find();
293 if (lists.length == 1) {
295 } else if (lists.length > 1) {
296 throw new UnsupportedOperationException();
302 private void useMovieLocalCheckBoxItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_useMovieLocalCheckBoxItemStateChanged
303 final Properties p = Properties.INSTANCE;
305 final ItemSelectable source = evt.getItemSelectable();
310 if (source == useMovieLocalCheckBox) {
311 btn = movieFileSelectButton;
312 field = movieFileField;
313 dir = p.getMovieDirectory();
315 btn = commentFileSelectButton;
316 field = commentFileField;
317 dir = p.getCommentDirectory();
320 final boolean useLocal = (evt.getStateChange() == ItemEvent.SELECTED);
321 btn.setEnabled(useLocal);
325 final File f = searchFileMatchId(dir, idField.getText());
332 text = p.getFileNamePattern();
335 }//GEN-LAST:event_useMovieLocalCheckBoxItemStateChanged
337 private void outputConvertCheckBoxItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_outputConvertCheckBoxItemStateChanged
338 final boolean convert = (evt.getStateChange() == ItemEvent.SELECTED);
339 outputFileField.setEnabled(convert);
340 }//GEN-LAST:event_outputConvertCheckBoxItemStateChanged
342 private void idFieldFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_idFieldFocusLost
343 final Properties p = Properties.INSTANCE;
344 final String id = idField.getText();
349 if (useMovieLocalCheckBox.isSelected() && movieFileField.getText().isEmpty()) {
350 final File dir = p.getMovieDirectory();
351 final File file = searchFileMatchId(dir, id);
353 movieFileField.setText(file.getPath());
357 if (useCommentLocalCheckBox.isSelected() && commentFileField.getText().isEmpty()) {
358 final File dir = p.getCommentDirectory();
359 final File file = searchFileMatchId(dir, id);
361 commentFileField.setText(file.getPath());
365 }//GEN-LAST:event_idFieldFocusLost
368 * @param args the command line arguments
370 public static void main(String args[]) {
372 for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
373 if ("Nimbus".equals(info.getName())) {
374 UIManager.setLookAndFeel(info.getClassName());
378 } catch (Exception e) {
380 UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
381 } catch (Exception ex) {
384 java.awt.EventQueue.invokeLater(new Runnable() {
387 new MainFrame().setVisible(true);
391 // Variables declaration - do not modify//GEN-BEGIN:variables
392 private javax.swing.JButton applyButton;
393 private javax.swing.JTextField commentFileField;
394 private javax.swing.JButton commentFileSelectButton;
395 private javax.swing.JLabel commentLabel;
396 private javax.swing.JTextField idField;
397 private javax.swing.JLabel idLabel;
398 private javax.swing.JButton jButton2;
399 private javax.swing.JButton jButton3;
400 private javax.swing.JButton jButton4;
401 private javax.swing.JMenu jMenu1;
402 private javax.swing.JMenu jMenu2;
403 private javax.swing.JMenuBar jMenuBar1;
404 private javax.swing.JPanel jPanel1;
405 private javax.swing.JPanel jPanel2;
406 private javax.swing.JPanel jPanel3;
407 private javax.swing.JScrollPane jScrollPane1;
408 private javax.swing.JTable jTable1;
409 private javax.swing.JTextField movieFileField;
410 private javax.swing.JButton movieFileSelectButton;
411 private javax.swing.JLabel movieLabel;
412 private javax.swing.JCheckBox outputConvertCheckBox;
413 private javax.swing.JTextField outputFileField;
414 private javax.swing.JLabel outputLabel;
415 private javax.swing.JCheckBox useCommentLocalCheckBox;
416 private javax.swing.JCheckBox useMovieLocalCheckBox;
417 // End of variables declaration//GEN-END:variables
419 private void initInputPanel() {
422 final Properties p = Properties.INSTANCE;
424 final boolean movieLocal = p.getUseMovieFileLocal();
425 useMovieLocalCheckBox.setSelected(movieLocal);
426 movieFileSelectButton.setEnabled(movieLocal);
428 movieFileField.setText(p.getFileNamePattern());
431 final boolean commentLocal = p.getCommentFileLocal();
432 useCommentLocalCheckBox.setSelected(commentLocal);
433 commentFileSelectButton.setEnabled(commentLocal);
435 commentFileField.setText(p.getFileNamePattern());
438 final boolean convert = p.getOutputConvert();
439 outputConvertCheckBox.setSelected(convert);
440 outputFileField.setEnabled(convert);
441 outputFileField.setText(p.getFileNamePattern());
445 private class DownloadListTransferHandler extends TransferHandler {
447 private static final long serialVersionUID = 1L;
448 private final Pattern movieIdPattern = Pattern.compile("(\\w\\w\\d+)");
451 public boolean canImport(TransferHandler.TransferSupport support) {
452 Transferable transferable = support.getTransferable();
453 if (transferable.isDataFlavorSupported(DataFlavor.javaFileListFlavor)
454 || transferable.isDataFlavorSupported(DataFlavor.stringFlavor)) {
461 public boolean importData(TransferHandler.TransferSupport support) {
463 Transferable transferable = support.getTransferable();
464 if (transferable.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
465 @SuppressWarnings("unchecked")
466 final List<File> data = (List<File>) transferable.getTransferData(DataFlavor.javaFileListFlavor);
467 Collection<Target> targets = Target.from(data);
468 targetModel.addTarget(targets);
469 } else if (transferable.isDataFlavorSupported(DataFlavor.stringFlavor)) {
470 String data = (String) transferable.getTransferData(DataFlavor.stringFlavor);
471 Matcher matcher = movieIdPattern.matcher(data);
472 if (matcher.find()) {
473 String movieId = matcher.group(1);
474 Target target = Target.fromId(movieId);
475 targetModel.addTarget(target);
482 } catch (Exception e) {
483 logger.log(Level.SEVERE, null, e);
489 private class TableTransferHandler extends DownloadListTransferHandler {
490 private static final long serialVersionUID = 1L;
493 public boolean canImport(TransferHandler.TransferSupport support) {
494 return super.canImport(support);
498 public boolean importData(TransferHandler.TransferSupport support) {
499 return super.importData(support);