• 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/filepanel/FilePanel.java
1
package edu.jiangxin.apktoolbox.swing.extend.filepanel;
2

3
import edu.jiangxin.apktoolbox.utils.Constants;
4
import edu.jiangxin.apktoolbox.utils.FileUtils;
5
import org.apache.commons.lang3.ArrayUtils;
6
import org.apache.commons.lang3.StringUtils;
7
import org.apache.logging.log4j.LogManager;
8
import org.apache.logging.log4j.Logger;
9

10
import javax.swing.*;
11
import javax.swing.filechooser.FileNameExtensionFilter;
12
import java.awt.*;
13
import java.awt.datatransfer.DataFlavor;
14
import java.awt.datatransfer.Transferable;
15
import java.awt.datatransfer.UnsupportedFlavorException;
16
import java.awt.event.ActionEvent;
17
import java.awt.event.ActionListener;
18
import java.io.File;
19
import java.io.IOException;
20
import java.io.Serial;
21
import java.util.List;
22

23
public class FilePanel extends JPanel {
24
    @Serial
25
    private static final long serialVersionUID = 1L;
26

27
    private static final Logger LOGGER = LogManager.getLogger(FilePanel.class.getSimpleName());
×
28
    private JTextField fileTextField;
29

30
    private String buttonText;
31

32
    private String currentDirectoryPath = ".";
×
33

34
    private int fileSelectionMode = JFileChooser.FILES_ONLY;
×
35

36
    private String description;
37

38
    private String[] extensions;
39

40
    private JFileChooser fileChooser;
41

42
    private transient IFileReadyCallback callback;
43

44
    public FilePanel(String buttonText) {
45
        super();
×
46
        fileChooser = new JFileChooser();
×
47
        this.buttonText = buttonText;
×
NEW
48
    }
×
49

50
    // in case of escape of "this"
51
    public void initialize() {
52
        initUI();
×
53
    }
×
54

55
    public void setCurrentDirectoryPath(String currentDirectoryPath) {
56
        this.currentDirectoryPath = currentDirectoryPath;
×
57
    }
×
58

59
    public void setPersistentKey(String persistentKey) {
60
        fileTextField.setName(persistentKey);
×
61
    }
×
62

63
    public void setFileReadyCallback(IFileReadyCallback callback) {
64
        this.callback = callback;
×
65
    }
×
66

67
    public void setFileSelectionMode(int fileSelectionMode) {
68
        this.fileSelectionMode = fileSelectionMode;
×
69
    }
×
70

71
    public void setDescriptionAndFileExtensions(String description, String[] extensions) {
72
        this.description = description;
×
73
        this.extensions = extensions;
×
74
        if (StringUtils.isNotEmpty(description) || ArrayUtils.isNotEmpty(extensions)) {
×
75
            FileNameExtensionFilter filter = new FileNameExtensionFilter(description, extensions);
×
76
            if (fileChooser != null) {
×
77
                fileChooser.resetChoosableFileFilters();
×
78
                fileChooser.addChoosableFileFilter(filter);
×
79
                fileChooser.setAcceptAllFileFilterUsed(false);
×
80
            }
81
        } else {
×
82
            if (fileChooser != null) {
×
83
                fileChooser.resetChoosableFileFilters();
×
84
                fileChooser.setAcceptAllFileFilterUsed(true);
×
85
            }
86
        }
87
    }
×
88

89
    private void initUI() {
90
        setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
×
91

92
        fileTextField = new JTextField();
×
93
        fileTextField.setPreferredSize(new Dimension(600, 30));
×
94
        fileTextField.setMaximumSize(new Dimension(1200, 30));
×
95
        fileTextField.setTransferHandler(new FileTransferHandler());
×
96

97
        JButton chooseButton = new JButton(buttonText);
×
98
        chooseButton.addActionListener(new OpenDictionaryFileActionListener());
×
99

100
        add(fileTextField);
×
101
        add(Box.createHorizontalStrut(Constants.DEFAULT_X_BORDER));
×
102
        add(chooseButton);
×
103
    }
×
104

105
    public File getFile() {
106
        return new File(fileTextField.getText());
×
107
    }
108

109
    class OpenDictionaryFileActionListener implements ActionListener {
×
110
        @Override
111
        public void actionPerformed(ActionEvent e) {
112
            fileChooser.setCurrentDirectory(new File(currentDirectoryPath));
×
113
            fileChooser.setFileSelectionMode(fileSelectionMode);
×
114
            fileChooser.setMultiSelectionEnabled(false);
×
115
            if (StringUtils.isNotEmpty(description) || ArrayUtils.isNotEmpty(extensions)) {
×
116
                FileNameExtensionFilter filter = new FileNameExtensionFilter(description, extensions);
×
117
                fileChooser.addChoosableFileFilter(filter);
×
118
                fileChooser.setAcceptAllFileFilterUsed(false);
×
119
            } else {
×
120
                fileChooser.resetChoosableFileFilters();
×
121
                fileChooser.setAcceptAllFileFilterUsed(true);
×
122
            }
123
            int returnVal = fileChooser.showOpenDialog(FilePanel.this);
×
124
            if (returnVal == JFileChooser.APPROVE_OPTION) {
×
125
                File selectedFile = fileChooser.getSelectedFile();
×
126
                fileTextField.setText(FileUtils.getCanonicalPathQuiet(selectedFile));
×
127
                if (callback != null) {
×
128
                    callback.onFileReady(selectedFile);
×
129
                }
130
            }
131
        }
×
132
    }
133

134
    class FileTransferHandler extends TransferHandler {
135
        @Serial
136
        private static final long serialVersionUID = 1L;
137

138
        public FileTransferHandler() {
×
139
        }
×
140

141
        @Override
142
        public boolean importData(JComponent comp, Transferable t) {
143
            List<File> files = null;
×
144
            try {
145
                files = (List<File>) t.getTransferData(DataFlavor.javaFileListFlavor);
×
146
            } catch (IOException e) {
×
147
                LOGGER.error("importData failed: IOException");
×
148
            } catch (UnsupportedFlavorException e) {
×
149
                LOGGER.error("importData failed: UnsupportedFlavorException");
×
150
            }
×
151
            if (files == null || files.size() != 1) {
×
152
                LOGGER.error("importData failed: getTransferData failed");
×
153
                return false;
×
154
            }
155
            File file = files.get(0);
×
156
            if ((!file.isFile() && fileSelectionMode == JFileChooser.FILES_ONLY)
×
157
                    ||(!file.isDirectory() && fileSelectionMode == JFileChooser.DIRECTORIES_ONLY)) {
×
158
                LOGGER.error("importData failed: fileSelectionMode is not match");
×
159
                return false;
×
160
            }
161
            fileTextField.setText(FileUtils.getCanonicalPathQuiet(file));
×
162
            if (callback != null) {
×
163
                callback.onFileReady(file);
×
164
            }
165
            return true;
×
166
        }
167

168
        @Override
169
        public boolean canImport(JComponent jComponent, DataFlavor[] dataFlavors) {
170
            for (DataFlavor dataFlavor : dataFlavors) {
×
171
                if (DataFlavor.javaFileListFlavor.equals(dataFlavor)) {
×
172
                    return true;
×
173
                }
174
            }
175
            return false;
×
176
        }
177
    }
178
}
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