1 package edu.jiangxin.apktoolbox.swing.extend; 2 3 import edu.jiangxin.apktoolbox.utils.Constants; 4 import org.apache.logging.log4j.LogManager; 5 import org.apache.logging.log4j.Logger; 6 7 import javax.swing.*; 8 import java.awt.*; 9 import java.awt.datatransfer.DataFlavor; 10 import java.awt.datatransfer.Transferable; 11 import java.awt.datatransfer.UnsupportedFlavorException; 12 import java.awt.event.ActionEvent; 13 import java.awt.event.ActionListener; 14 import java.io.File; 15 import java.io.IOException; 16 import java.util.ArrayList; 17 import java.util.List; 18 19 public class FileListPanel extends JPanel { 20 21 private static final Logger LOGGER = LogManager.getLogger(FileListPanel.class.getSimpleName()); 22 23 private JPanel leftPanel; 24 25 private JPanel rightPanel; 26 27 private JList<File> fileList; 28 29 private DefaultListModel<File> fileListModel; 30 31 public FileListPanel() { 32 super(); 33 initUI(); 34 } 35 36 public List<File> getFileList() { 37 List<File> fileList = new ArrayList<>(); 38 Object[] objectArray = fileListModel.toArray(); 39 for (Object obj : objectArray) { 40 if (obj instanceof File) { 41 fileList.add((File) obj); 42 } 43 } 44 return fileList; 45 } 46 47 private void initUI() { 48 setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); 49 50 createLeftPanel(); 51 add(leftPanel); 52 53 add(Box.createHorizontalStrut(Constants.DEFAULT_X_BORDER)); 54 55 createRightPanel(); 56 add(rightPanel); 57 } 58 59 private void createLeftPanel() { 60 fileList = new JList<>(); 61 fileListModel = new DefaultListModel<>(); 62 fileList.setModel(fileListModel); 63 64 JScrollPane scrollPane = new JScrollPane(fileList); 65 scrollPane.setPreferredSize(new Dimension(Constants.DEFAULT_SCROLL_PANEL_WIDTH, Constants.DEFAULT_SCROLL_PANEL_HEIGHT)); 66 67 leftPanel = new JPanel(); 68 leftPanel.setBorder(BorderFactory.createTitledBorder("File List")); 69 leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.Y_AXIS)); 70 leftPanel.setTransferHandler(new FileListTransferHandler()); 71 leftPanel.add(scrollPane); 72 } 73 74 private void createRightPanel() { 75 rightPanel = new JPanel(); 76 rightPanel.setLayout(new BoxLayout(rightPanel, BoxLayout.Y_AXIS)); 77 78 JPanel rightContentPanel = new JPanel(); 79 rightPanel.add(Box.createVerticalGlue()); 80 rightPanel.add(rightContentPanel); 81 rightPanel.add(Box.createVerticalGlue()); 82 83 rightContentPanel.setLayout(new GridLayout(6, 1, 0, Constants.DEFAULT_Y_BORDER)); 84 85 JButton addFileButton = new JButton("Add File"); 86 addFileButton.addActionListener(new AddFileButtonActionListener()); 87 rightContentPanel.add(addFileButton); 88 89 JButton addDirectoryButton = new JButton("Add Directory"); 90 addDirectoryButton.addActionListener(new AddDirectoryButtonActionListener()); 91 rightContentPanel.add(addDirectoryButton); 92 93 JButton removeSelectedButton = new JButton("Remove Selected"); 94 removeSelectedButton.addActionListener(new RemoveSelectedButtonActionListener()); 95 rightContentPanel.add(removeSelectedButton); 96 97 JButton clearButton = new JButton("Clear All"); 98 clearButton.addActionListener(new ClearButtonActionListener()); 99 rightContentPanel.add(clearButton); 100 101 JButton selectAllButton = new JButton("Select All"); 102 selectAllButton.addActionListener(new SelectAllButtonActionListener()); 103 rightContentPanel.add(selectAllButton); 104 105 JButton inverseSelectedButton = new JButton("Inverse Selected"); 106 inverseSelectedButton.addActionListener(new InverseSelectedButtonActionListener()); 107 rightContentPanel.add(inverseSelectedButton); 108 109 for (Component component : rightContentPanel.getComponents()) { 110 component.setPreferredSize(new Dimension(Constants.DEFAULT_BUTTON_WIDTH, Constants.DEFAULT_BUTTON_HEIGHT)); 111 } 112 } 113 114 private final class FileListTransferHandler extends TransferHandler { 115 @Override 116 public boolean importData(JComponent comp, Transferable t) { 117 try { 118 Object object = t.getTransferData(DataFlavor.javaFileListFlavor); 119 for (File file : (List<File>)object) { 120 fileListModel.addElement(file); 121 } 122 return true; 123 } catch (IOException e) { 124 LOGGER.error("importData failed: IOException"); 125 } catch (UnsupportedFlavorException e) { 126 LOGGER.error("importData failed: UnsupportedFlavorException"); 127 } 128 return false; 129 } 130 131 @Override 132 public boolean canImport(JComponent jComponent, DataFlavor[] dataFlavors) { 133 for (DataFlavor dataFlavor : dataFlavors) { 134 if (DataFlavor.javaFileListFlavor.equals(dataFlavor)) { 135 return true; 136 } 137 } 138 return false; 139 } 140 } 141 142 private final class AddFileButtonActionListener implements ActionListener { 143 @Override 144 public void actionPerformed(ActionEvent e) { 145 JFileChooser jfc = new JFileChooser(); 146 jfc.setFileSelectionMode(JFileChooser.FILES_ONLY); 147 jfc.setDialogTitle("Select A File"); 148 int ret = jfc.showDialog(new JLabel(), null); 149 if (ret == JFileChooser.APPROVE_OPTION) { 150 File file = jfc.getSelectedFile(); 151 fileListModel.addElement(file); 152 } 153 } 154 } 155 156 private final class AddDirectoryButtonActionListener implements ActionListener { 157 @Override 158 public void actionPerformed(ActionEvent e) { 159 JFileChooser jfc = new JFileChooser(); 160 jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); 161 jfc.setDialogTitle("Select A Directory"); 162 int ret = jfc.showDialog(new JLabel(), null); 163 if (ret == JFileChooser.APPROVE_OPTION) { 164 File file = jfc.getSelectedFile(); 165 fileListModel.addElement(file); 166 } 167 168 } 169 } 170 171 private final class RemoveSelectedButtonActionListener implements ActionListener { 172 @Override 173 public void actionPerformed(ActionEvent e) { 174 List<File> files = fileList.getSelectedValuesList(); 175 for (File file : files) { 176 fileListModel.removeElement(file); 177 } 178 } 179 } 180 181 private final class ClearButtonActionListener implements ActionListener { 182 @Override 183 public void actionPerformed(ActionEvent e) { 184 fileListModel.removeAllElements(); 185 } 186 } 187 188 private final class SelectAllButtonActionListener implements ActionListener { 189 @Override 190 public void actionPerformed(ActionEvent e) { 191 int[] selectedIndices = new int[fileListModel.getSize()]; 192 for (int i = 0; i < selectedIndices.length; i++) { 193 selectedIndices[i] = i; 194 } 195 fileList.clearSelection(); 196 fileList.setSelectedIndices(selectedIndices); 197 } 198 } 199 200 private final class InverseSelectedButtonActionListener implements ActionListener { 201 @Override 202 public void actionPerformed(ActionEvent e) { 203 int[] newIndices = new int[fileListModel.getSize() - fileList.getSelectedIndices().length]; 204 for (int i = 0, j = 0; i < fileListModel.getSize(); ++i) { 205 if (!fileList.isSelectedIndex(i)) { 206 newIndices[j++] = i; 207 } 208 } 209 fileList.clearSelection(); 210 fileList.setSelectedIndices(newIndices); 211 } 212 } 213 214 }