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

jiangxincode / ApkToolBoxGUI / #1114

26 Jul 2025 12:05PM UTC coverage: 3.079% (+0.002%) from 3.077%
#1114

push

jiangxincode
fix #543: add error tips

0 of 23 new or added lines in 8 files covered. (0.0%)

1 existing line in 1 file now uncovered.

236 of 7664 relevant lines covered (3.08%)

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/reverse/ApktoolPanel.java
1
package edu.jiangxin.apktoolbox.reverse;
2

3
import edu.jiangxin.apktoolbox.swing.extend.plugin.PluginPanel;
4
import edu.jiangxin.apktoolbox.swing.extend.listener.SelectDirectoryListener;
5
import edu.jiangxin.apktoolbox.swing.extend.listener.SelectFileListener;
6
import edu.jiangxin.apktoolbox.utils.Constants;
7
import edu.jiangxin.apktoolbox.utils.Utils;
8
import org.apache.commons.io.FilenameUtils;
9

10
import javax.swing.*;
11
import javax.swing.filechooser.FileFilter;
12
import java.awt.*;
13
import java.awt.event.ActionEvent;
14
import java.awt.event.ActionListener;
15
import java.io.File;
16

17
public class ApktoolPanel extends PluginPanel {
18
    public ApktoolPanel() throws HeadlessException {
19
        super();
×
20
    }
×
21

22
    @Override
23
    public String getPluginFilename() {
24
        return "apktool_2.12.0.jar";
×
25
    }
26

27
    @Override
28
    public void initUI() {
29
        BoxLayout boxLayout = new BoxLayout(this, BoxLayout.Y_AXIS);
×
30
        setLayout(boxLayout);
×
31

32
        JTabbedPane categoryTabbedPane = new JTabbedPane();
×
33
        add(categoryTabbedPane);
×
34

35
        JPanel decodeCategoryPanel = new ApktoolDecodePanel();
×
36
        JPanel rebuildCategoryPanel = new ApktoolRebuildPanel();
×
37

38
        categoryTabbedPane.addTab("Decode", null, decodeCategoryPanel, "Decode the APK file");
×
39
        categoryTabbedPane.setSelectedIndex(0);
×
40
        categoryTabbedPane.addTab("Rebuild", null, rebuildCategoryPanel, "Rebuild the APK file");
×
41
    }
×
42

43
    abstract class ApktoolPanelBase extends JPanel {
44
        protected JPanel srcPanel;
45

46
        protected JPanel targetPanel;
47

48
        protected JPanel optionPanel;
49

50
        protected JPanel operationPanel;
51

52
        protected ApktoolPanelBase() throws HeadlessException {
×
53
            super();
×
54
            initUI();
×
55
        }
×
56

57
        private void initUI() {
58
            BoxLayout boxLayout = new BoxLayout(this, BoxLayout.Y_AXIS);
×
59
            setLayout(boxLayout);
×
60

61
            createSrcPanel();
×
62
            add(srcPanel);
×
63
            add(Box.createVerticalStrut(Constants.DEFAULT_Y_BORDER));
×
64

65
            createTargetPanel();
×
66
            add(targetPanel);
×
67
            add(Box.createVerticalStrut(Constants.DEFAULT_Y_BORDER));
×
68

69
            createOptionPanel();
×
70
            add(optionPanel);
×
71
            add(Box.createVerticalStrut(Constants.DEFAULT_Y_BORDER));
×
72

73
            createOperationPanel();
×
74
            add(operationPanel);
×
75
        }
×
76

77
        protected void createSrcPanel() {
78
            srcPanel = new JPanel();
×
79
            srcPanel.setLayout(new BoxLayout(srcPanel, BoxLayout.X_AXIS));
×
80
        }
×
81

82
        protected void createTargetPanel() {
83
            targetPanel = new JPanel();
×
84
            targetPanel.setLayout(new BoxLayout(targetPanel, BoxLayout.X_AXIS));
×
85
        }
×
86

87
        protected void createOptionPanel() {
88
            optionPanel = new JPanel();
×
89
            optionPanel.setLayout(new BoxLayout(optionPanel, BoxLayout.X_AXIS));
×
90
        }
×
91

92
        protected void createOperationPanel() {
93
            operationPanel = new JPanel();
×
94
            operationPanel.setLayout(new BoxLayout(operationPanel, BoxLayout.X_AXIS));
×
95
        }
×
96
    }
97

98
    class ApktoolDecodePanel extends ApktoolPanelBase {
99
        private JTextField srcTextField;
100

101
        private JTextField targetTextField;
102

103
        private JCheckBox resourceIgnoreCheckBox;
104

105
        private JCheckBox overrideCheckBox;
106

107
        public ApktoolDecodePanel() throws HeadlessException {
×
108
            super();
×
109
        }
×
110

111
        @Override
112
        public void createSrcPanel() {
113
            super.createSrcPanel();
×
114

115
            srcTextField = new JTextField();
×
116
            srcTextField.setText(conf.getString("apktool.decode.src.file"));
×
117

118
            JButton srcButton = new JButton(bundle.getString("choose.file.button"));
×
119
            srcButton.addActionListener(new SelectFileListener("select a file", srcTextField));
×
120

121
            srcPanel.add(srcTextField);
×
122
            srcPanel.add(Box.createHorizontalStrut(Constants.DEFAULT_X_BORDER));
×
123
            srcPanel.add(srcButton);
×
124
        }
×
125

126
        @Override
127
        public void createTargetPanel() {
128
            super.createTargetPanel();
×
129

130
            targetTextField = new JTextField();
×
131
            targetTextField.setText(conf.getString("apktool.decode.target.dir"));
×
132

133
            JButton targetButton = new JButton(bundle.getString("save.dir.button"));
×
134
            targetButton.addActionListener(new SelectDirectoryListener("Save To", targetTextField));
×
135

136
            targetPanel.add(targetTextField);
×
137
            targetPanel.add(Box.createHorizontalStrut(Constants.DEFAULT_X_BORDER));
×
138
            targetPanel.add(targetButton);
×
139
        }
×
140

141
        @Override
142
        public void createOptionPanel() {
143
            super.createOptionPanel();
×
144

145
            resourceIgnoreCheckBox = new JCheckBox("Ignore res");
×
146
            resourceIgnoreCheckBox.setSelected(false);
×
147
            optionPanel.add(resourceIgnoreCheckBox);
×
148

149
            overrideCheckBox = new JCheckBox("Override");
×
150
            overrideCheckBox.setSelected(true);
×
151
            optionPanel.add(overrideCheckBox);
×
152
        }
×
153

154
        @Override
155
        public void createOperationPanel() {
156
            super.createOperationPanel();
×
157

158
            JButton decodeButton = new JButton("Decode");
×
159
            decodeButton.addActionListener(new ApktoolDecodePanel.DecodeButtonActionListener());
×
160

161
            operationPanel.add(decodeButton);
×
162
        }
×
163

164
        private final class DecodeButtonActionListener implements ActionListener {
×
165
            @Override
166
            public void actionPerformed(ActionEvent e) {
167
                String srcPath = checkAndGetFileContent(srcTextField, "apktool.decode.src.file", "Source file is invalid");
×
168
                if (srcPath == null) {
×
169
                    return;
×
170
                }
171

172
                String targetPath = checkAndGetDirContent(targetTextField, "apktool.decode.target.dir", "Target directory is invalid");
×
173
                if (targetPath == null) {
×
174
                    return;
×
175
                }
176

177
                String srcBaseName = FilenameUtils.getBaseName(srcPath);
×
178
                StringBuilder sb = new StringBuilder();
×
179
                sb.append(ApktoolPanel.this.getPluginStartupCmd()).append(" d ")
×
180
                        .append(srcPath).append(" -o ").append(targetPath).append(File.separator).append(srcBaseName);
×
181
                if (resourceIgnoreCheckBox.isSelected()) {
×
182
                    sb.append(" -r");
×
183
                }
184
                if (overrideCheckBox.isSelected()) {
×
185
                    sb.append(" -f");
×
186
                }
NEW
187
                Utils.executor(sb.toString(), true);
×
188
            }
×
189
        }
190
    }
191

192
    class ApktoolRebuildPanel extends ApktoolPanelBase {
193
        private JTextField srcTextField;
194

195
        private JTextField targetTextField;
196

197
        private JCheckBox signAPK;
198

199
        public ApktoolRebuildPanel() throws HeadlessException {
×
200
            super();
×
201
        }
×
202

203
        @Override
204
        public void createSrcPanel() {
205
            super.createSrcPanel();
×
206

207
            srcTextField = new JTextField();
×
208
            srcTextField.setText(conf.getString("apktool.rebuild.src.dir"));
×
209

210
            JButton srcButton = new JButton(bundle.getString("choose.dir.button"));
×
211
            srcButton.addActionListener(new SelectDirectoryListener("Select Directory", srcTextField));
×
212

213
            srcPanel.add(srcTextField);
×
214
            srcPanel.add(Box.createHorizontalStrut(Constants.DEFAULT_X_BORDER));
×
215
            srcPanel.add(srcButton);
×
216
        }
×
217

218
        @Override
219
        public void createTargetPanel() {
220
            super.createTargetPanel();
×
221

222
            targetTextField = new JTextField();
×
223
            targetTextField.setText(conf.getString("apktool.rebuild.target.file"));
×
224

225
            JButton targetButton = new JButton(bundle.getString("save.file.button"));
×
226
            targetButton.addActionListener(new SelectFileListener("save to", targetTextField, new ApktoolRebuildPanel.ApkFileFilter()));
×
227

228
            targetPanel.add(targetTextField);
×
229
            targetPanel.add(Box.createHorizontalStrut(Constants.DEFAULT_X_BORDER));
×
230
            targetPanel.add(targetButton);
×
231
        }
×
232

233
        @Override
234
        public void createOptionPanel() {
235
            super.createOptionPanel();
×
236

237
            signAPK = new JCheckBox("sign APK");
×
238
            signAPK.setSelected(false);
×
239
            optionPanel.add(signAPK);
×
240
        }
×
241

242
        @Override
243
        public void createOperationPanel() {
244
            super.createOperationPanel();
×
245

246
            JButton rebuildButton = new JButton("Rebuild");
×
247
            rebuildButton.addActionListener(new ApktoolRebuildPanel.RebuildButtonActionListener());
×
248
            operationPanel.add(rebuildButton);
×
249
        }
×
250

251
        private final class RebuildButtonActionListener implements ActionListener {
×
252
            @Override
253
            public void actionPerformed(ActionEvent e) {
254
                String srcPath = checkAndGetDirContent(srcTextField, "apktool.rebuild.src.dir", "Source directory is invalid");
×
255
                if (srcPath == null) {
×
256
                    return;
×
257
                }
258

259
                String targetPath = checkAndGetNewFileContent(targetTextField, "apktool.rebuild.target.file", "Target file is invalid");
×
260
                if (targetPath == null) {
×
261
                    return;
×
262
                }
263

264
                StringBuilder sb = new StringBuilder();
×
265
                sb.append(ApktoolPanel.this.getPluginStartupCmd()).append(" b ")
×
266
                        .append(srcPath).append(" -o ").append(targetPath);
×
NEW
267
                Utils.executor(sb.toString(), true);
×
268
                if (signAPK.isSelected()) {
×
269
                    sb = new StringBuilder();
×
270
                    sb.append(ApktoolPanel.this.getPluginStartupCmd())
×
271
                            .append(" -keystore ").append(Utils.getToolsPath()).append(File.separator)
×
272
                            .append("debug.keystore").append(" -alias androiddebugkey -pswd android ")
×
273
                            .append(targetPath);
×
NEW
274
                    Utils.executor(sb.toString(), true);
×
275
                }
276
            }
×
277
        }
278

279
        private final class ApkFileFilter extends FileFilter {
×
280

281
            @Override
282
            public boolean accept(File f) {
283
                String nameString = f.getName();
×
284
                return nameString.toLowerCase().endsWith(".apk");
×
285
            }
286

287
            @Override
288
            public String getDescription() {
289
                return "*.apk";
×
290
            }
291
        }
292
    }
293
}
294

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