• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

jiangxincode / ApkToolBoxGUI / #1207

13 Sep 2025 11:58PM UTC coverage: 2.895% (-0.006%) from 2.901%
#1207

push

jiangxincode
fix #569: 可能在完全初始化子类之前逃逸了 'this'

0 of 32 new or added lines in 22 files covered. (0.0%)

9 existing lines in 8 files now uncovered.

248 of 8567 relevant lines covered (2.89%)

0.03 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/main/java/edu/jiangxin/apktoolbox/swing/extend/FileListPanel.java
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();
×
NEW
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
                Object object = t.getTransferData(DataFlavor.javaFileListFlavor);
×
129
                for (File file : (List<File>)object) {
×
130
                    fileListModel.addElement(file);
×
131
                }
×
132
                return true;
×
133
            } catch (IOException e) {
×
134
                LOGGER.error("importData failed: IOException");
×
135
            } catch (UnsupportedFlavorException e) {
×
136
                LOGGER.error("importData failed: UnsupportedFlavorException");
×
137
            }
×
138
            return false;
×
139
        }
140

141
        @Override
142
        public boolean canImport(JComponent jComponent, DataFlavor[] dataFlavors) {
143
            for (DataFlavor dataFlavor : dataFlavors) {
×
144
                if (DataFlavor.javaFileListFlavor.equals(dataFlavor)) {
×
145
                    return true;
×
146
                }
147
            }
148
            return false;
×
149
        }
150
    }
151

152
    private final class AddFileButtonActionListener implements ActionListener {
×
153
        @Override
154
        public void actionPerformed(ActionEvent e) {
155
            JFileChooser jfc = new JFileChooser();
×
156
            jfc.setFileSelectionMode(JFileChooser.FILES_ONLY);
×
157
            jfc.setDialogTitle("Select A File");
×
158
            int ret = jfc.showDialog(new JLabel(), null);
×
159
            if (ret == JFileChooser.APPROVE_OPTION) {
×
160
                File file = jfc.getSelectedFile();
×
161
                fileListModel.addElement(file);
×
162
            }
163
        }
×
164
    }
165

166
    private final class AddDirectoryButtonActionListener implements ActionListener {
×
167
        @Override
168
        public void actionPerformed(ActionEvent e) {
169
            JFileChooser jfc = new JFileChooser();
×
170
            jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
×
171
            jfc.setDialogTitle("Select A Directory");
×
172
            int ret = jfc.showDialog(new JLabel(), null);
×
173
            if (ret == JFileChooser.APPROVE_OPTION) {
×
174
                File file = jfc.getSelectedFile();
×
175
                fileListModel.addElement(file);
×
176
            }
177

178
        }
×
179
    }
180

181
    private final class RemoveSelectedButtonActionListener implements ActionListener {
×
182
        @Override
183
        public void actionPerformed(ActionEvent e) {
184
            List<File> files = fileList.getSelectedValuesList();
×
185
            for (File file : files) {
×
186
                fileListModel.removeElement(file);
×
187
            }
×
188
        }
×
189
    }
190

191
    private final class ClearButtonActionListener implements ActionListener {
×
192
        @Override
193
        public void actionPerformed(ActionEvent e) {
194
            fileListModel.removeAllElements();
×
195
        }
×
196
    }
197

198
    private final class SelectAllButtonActionListener implements ActionListener {
×
199
        @Override
200
        public void actionPerformed(ActionEvent e) {
201
            int[] selectedIndices = new int[fileListModel.getSize()];
×
202
            for (int i = 0; i < selectedIndices.length; i++) {
×
203
                selectedIndices[i] = i;
×
204
            }
205
            fileList.clearSelection();
×
206
            fileList.setSelectedIndices(selectedIndices);
×
207
        }
×
208
    }
209

210
    private final class InverseSelectedButtonActionListener implements ActionListener {
×
211
        @Override
212
        public void actionPerformed(ActionEvent e) {
213
            int[] newIndices = new int[fileListModel.getSize() - fileList.getSelectedIndices().length];
×
214
            for (int i = 0, j = 0; i < fileListModel.getSize(); ++i) {
×
215
                if (!fileList.isSelectedIndex(i)) {
×
216
                    newIndices[j++] = i;
×
217
                }
218
            }
219
            fileList.clearSelection();
×
220
            fileList.setSelectedIndices(newIndices);
×
221
        }
×
222
    }
223

224
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc