1 package yukihane.inqubus.gui;
3 import static yukihane.inqubus.InqubusConstants.*;
5 import java.awt.EventQueue;
6 import java.awt.datatransfer.DataFlavor;
7 import java.awt.datatransfer.UnsupportedFlavorException;
8 import java.awt.event.FocusAdapter;
9 import java.awt.event.FocusEvent;
10 import java.awt.event.KeyAdapter;
11 import java.awt.event.KeyEvent;
13 import java.io.IOException;
15 import java.nio.file.Path;
16 import java.util.Collection;
17 import java.util.HashSet;
18 import java.util.List;
20 import java.util.SortedSet;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
23 import java.util.regex.Matcher;
24 import javax.swing.DefaultComboBoxModel;
25 import javax.swing.JComboBox;
26 import javax.swing.JTextField;
27 import javax.swing.TransferHandler;
28 import javax.swing.text.JTextComponent;
29 import org.apache.commons.io.FilenameUtils;
30 import yukihane.inqubus.filewatch.FileWatch;
31 import yukihane.inqubus.filewatch.FileWatchUtil;
33 final class IdComboBox extends JComboBox<String> {
35 private static final long serialVersionUID = 1L;
36 private static final Logger logger = LoggerFactory.getLogger(IdComboBox.class);
37 private final Set<Path> alternates = new HashSet<>();
38 private final FileWatch videoFileWatcher;
40 IdComboBox(FileWatch videoFileWather) {
42 this.videoFileWatcher = videoFileWather;
45 getEditorComponent().setTransferHandler(new IdTransferHander(getEditorComponent().getTransferHandler()));
46 getEditorComponent().addKeyListener(new AutoCompleteAdapter());
47 getEditorComponent().addFocusListener(new FocusAdapter() {
50 public void focusGained(FocusEvent e) {
51 setAlternates(videoFileWatcher.getFiles());
57 JTextField getEditorComponent() {
58 return (JTextField) getEditor().getEditorComponent();
61 void setAlternates(Collection<Path> alternates) {
62 this.alternates.clear();
63 this.alternates.addAll(alternates);
67 return getEditorComponent().getText();
70 void setText(String str) {
71 getEditorComponent().setText(str);
74 private class AutoCompleteAdapter extends KeyAdapter {
77 public void keyTyped(final KeyEvent e) {
78 EventQueue.invokeLater(new Runnable() {
82 final String text = getText();
83 final SortedSet<String> alt = FileWatchUtil.getVideoIdsStartWith(alternates, text);
84 final String[] altArray = alt.toArray(new String[0]);
85 DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>(altArray);
86 IdComboBox.this.setModel(model);
89 IdComboBox.this.showPopup();
96 class IdTransferHander extends TransferHandler {
98 private static final long serialVersionUID = 1L;
99 private static final Logger logger = LoggerFactory.getLogger(IdTransferHander.class);
100 private static final DataFlavor URL_FLAVOR;
104 URL_FLAVOR = new DataFlavor("application/x-java-url; class=java.net.URL");
105 } catch (ClassNotFoundException ex) {
106 throw new IllegalStateException(ex);
109 private final TransferHandler defaultTransferHandler;
111 IdTransferHander(TransferHandler defaultTransferHandler) {
112 this.defaultTransferHandler = defaultTransferHandler;
116 public boolean canImport(TransferHandler.TransferSupport support) {
117 if (logger.isTraceEnabled()) {
118 for (DataFlavor df : support.getDataFlavors()) {
119 logger.trace(df.toString() + ", " + df.getClass().getName());
123 if (support.isDataFlavorSupported(DataFlavor.stringFlavor)
124 || support.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
125 if (support.isDrop()) {
126 support.setDropAction(LINK);
134 public boolean importData(TransferHandler.TransferSupport support) {
137 if (support.isDataFlavorSupported(URL_FLAVOR)) {
138 final URL url = (URL) support.getTransferable().getTransferData(URL_FLAVOR);
139 targetText = url.getPath();
140 } else if (support.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
141 @SuppressWarnings("unchecked")
142 final List<File> files = (List<File>) support.getTransferable().getTransferData(DataFlavor.javaFileListFlavor);
143 if (!files.isEmpty()) {
144 final File file = files.get(0);
145 targetText = FilenameUtils.getBaseName(file.getPath());
149 } else if (support.isDataFlavorSupported(DataFlavor.stringFlavor)) {
150 targetText = (String) support.getTransferable().getTransferData(DataFlavor.stringFlavor);
155 final Matcher matcher = PATTERN_VIDEO_ID.matcher(targetText);
156 if (matcher.find()) {
157 final String text = matcher.group(1);
158 final JTextComponent component = (JTextComponent) support.getComponent();
159 component.setText(text);
162 } catch (UnsupportedFlavorException | IOException ex) {
163 logger.error(null, ex);