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