Skip to content

Commit e9bce19

Browse files
committed
fix: gui bugs and qol
1 parent e210d25 commit e9bce19

File tree

13 files changed

+202
-45
lines changed

13 files changed

+202
-45
lines changed

dev.skidfuscator.client.standalone/src/main/java/dev/skidfuscator/obfuscator/SkidfuscatorMain.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package dev.skidfuscator.obfuscator;
22

33
import com.formdev.flatlaf.intellijthemes.FlatDarkPurpleIJTheme;
4+
import com.formdev.flatlaf.intellijthemes.FlatGradiantoMidnightBlueIJTheme;
45
import dev.skidfuscator.obfuscator.command.HelpCommand;
56
import dev.skidfuscator.obfuscator.command.MappingsCommand;
67
import dev.skidfuscator.obfuscator.command.ObfuscateCommand;

dev.skidfuscator.client.standalone/src/main/java/dev/skidfuscator/obfuscator/gui/ActionPanel.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import java.awt.*;
77
import java.io.File;
88

9-
public class ActionPanel extends JPanel {
9+
public class ActionPanel extends JPanel implements SkidPanel{
1010
private final MainFrame mainFrame;
1111
private final JTextArea logArea;
1212
private final JButton startButton;
@@ -40,6 +40,8 @@ public void startObfuscation() {
4040
return;
4141
}
4242

43+
44+
4345
// Create session
4446
SkidfuscatorSession session = SkidfuscatorSession.builder()
4547
.input(new File(config.getInputPath()))
@@ -48,10 +50,7 @@ public void startObfuscation() {
4850
? new File[0]
4951
: new File(config.getLibsPath()).listFiles()
5052
)
51-
.runtime(config.getRuntimePath().isEmpty()
52-
? null
53-
: new File(config.getRuntimePath())
54-
)
53+
.runtime(null)
5554
.phantom(false)
5655
.debug(config.isDebugEnabled())
5756
.build();

dev.skidfuscator.client.standalone/src/main/java/dev/skidfuscator/obfuscator/gui/ConfigPanel.java

Lines changed: 53 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,22 @@
99
import dev.skidfuscator.obfuscator.gui.autosave.AutoSaveDocumentListener;
1010
import dev.skidfuscator.obfuscator.gui.config.SkidfuscatorConfig;
1111
import dev.skidfuscator.obfuscator.util.JdkDownloader;
12+
import dev.skidfuscator.obfuscator.util.Observable;
1213

13-
import javax.swing.*;
14-
import java.awt.*;
15-
import java.io.File;
16-
import java.awt.event.WindowAdapter;
17-
import java.awt.event.WindowEvent;
18-
import javax.swing.border.BevelBorder;
1914
import javax.swing.border.EtchedBorder;
2015
import javax.swing.event.DocumentEvent;
2116
import javax.swing.event.DocumentListener;
22-
import javax.swing.text.BadLocationException;
23-
import javax.swing.text.DefaultHighlighter;
2417

25-
public class ConfigPanel extends JPanel {
18+
public class ConfigPanel extends JPanel implements SkidPanel{
2619
private final JTextField inputField;
2720
private final JTextField outputField;
2821
private final JTextField libsField;
2922
private final JTextField runtimeField;
3023
private final JCheckBox debugBox;
3124
private final SkidfuscatorConfig config;
25+
private Observable<Boolean> runtimeInstalled = new Observable.SimpleObservable<>(
26+
JdkDownloader.isJdkDownloaded()
27+
);
3228

3329
public ConfigPanel() {
3430
setLayout(new GridBagLayout());
@@ -116,7 +112,9 @@ private void updateCheck() {
116112
boolean valid = new File(inputField.getText()).exists();
117113
inputCheck.setText(valid ? "✓" : "✗");
118114
inputCheck.setForeground(valid ? new Color(46, 204, 64) : new Color(255, 65, 54));
119-
115+
System.out.println("Input valid: " + valid);
116+
config.getValidInput().set(valid);
117+
120118
if (!valid) {
121119
StringBuilder tooltip = new StringBuilder("<html><body style='width: 250px; padding: 3px; background-color: #FFF3CD; border: 2px solid #FFE69C; border-radius: 4px'>");
122120
tooltip.append("<div style='color: #856404; font-weight: bold; margin-bottom: 5px'>⚠ Warning: Invalid Input Configuration</div>");
@@ -171,7 +169,10 @@ private void updateCheck() {
171169

172170
boolean valid = parent != null && parent.exists() && validEnd && validInput;
173171
outputCheck.setText(valid ? "✓" : "✗");
174-
outputCheck.setForeground(valid ? new Color(46, 204, 64) : new Color(255, 65, 54));
172+
outputCheck.setForeground(valid
173+
? new Color(46, 204, 64)
174+
: new Color(255, 65, 54)
175+
);
175176
// Set tooltip explaining validation failure
176177
StringBuilder tooltip = new StringBuilder("<html><body style='width: 250px; padding: 3px; background-color: #FFF3CD; border: 2px solid #FFE69C; border-radius: 4px'>");
177178
tooltip.append("<div style='color: #856404; font-weight: bold; margin-bottom: 5px'>⚠ Warning: Invalid Output Configuration</div>");
@@ -186,14 +187,15 @@ private void updateCheck() {
186187
tooltip.append("<div style='color: #664D03; margin: 3px 0'>Output file cannot be the same as input file</div>");
187188
}
188189
tooltip.append("</body></html>");
190+
config.getValidOutput().set(validInput);
189191

190192
if (!valid) {
191193
ToolTipManager.sharedInstance().setInitialDelay(0);
192194
ToolTipManager.sharedInstance().setDismissDelay(10000);
193195

194196
outputField.setToolTipText(tooltip.toString());
195197
} else {
196-
outputCheck.setToolTipText(null);
198+
outputField.setToolTipText(null);
197199
}
198200
}
199201
public void insertUpdate(DocumentEvent e) { updateCheck(); }
@@ -204,9 +206,15 @@ private void updateCheck() {
204206
if (config.getLastOutputPath() != null) {
205207
outputField.setText(config.getLastOutputPath());
206208
outputListener.insertUpdate(null);
207-
} else if (config.getLastInputPath() != null) {
208-
outputField.setText(config.getLastInputPath().replace(".jar", "-obf.jar"));
209+
} else if (config.getLastInputPath() != null || inputField.getText() != null) {
210+
final String input = config.getLastInputPath() != null
211+
? config.getLastInputPath()
212+
: inputField.getText();
213+
214+
outputField.setText(input.replace(".jar", "-obf.jar"));
209215
outputListener.insertUpdate(null);
216+
} else {
217+
config.getValidOutput().set(false);
210218
}
211219
add(outputField, gbc);
212220
gbc.gridx = 2;
@@ -271,12 +279,14 @@ private void updateCheck() {
271279
String jmodPath = JdkDownloader.getCachedJmodPath();
272280
runtimeField.setText(jmodPath);
273281
runtimeField.setEnabled(!JdkDownloader.isJdkDownloaded());
282+
runtimeInstalled.set(JdkDownloader.isJdkDownloaded());
274283
} catch (IOException e) {
275284
// Fallback to config
276285
if (config.getLastRuntimePath() != null) {
277286
if (config.getLastRuntimePath().isEmpty()) {
278287
runtimeField.setText(Jvm.getLibsPath());
279288
runtimeField.setEnabled(false);
289+
runtimeInstalled.set(true);
280290
} else {
281291
runtimeField.setText(config.getLastRuntimePath());
282292
}
@@ -288,12 +298,19 @@ private void updateCheck() {
288298
// Add download button next to browse button
289299
gbc.gridx = 2;
290300
JPanel runtimeButtonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 0));
291-
JButton downloadButton = new JButton("Download JDK");
292-
301+
JLabel downloadCheck = new JLabel("✗");
302+
downloadCheck.setForeground(new Color(255, 65, 54));
303+
304+
JButton downloadButton = new JButton("Install");
305+
runtimeButtonPanel.setPreferredSize(new Dimension(150, 30));
306+
293307
// Set initial button state based on JDK download status
294308
if (JdkDownloader.isJdkDownloaded()) {
295-
downloadButton.setText("Downloaded");
309+
downloadButton.setText("Installed");
296310
downloadButton.setEnabled(false);
311+
downloadCheck.setText("✓");
312+
downloadCheck.setForeground(new Color(46, 204, 64));
313+
runtimeInstalled.set(true);
297314
}
298315

299316
downloadButton.addActionListener(e -> {
@@ -312,23 +329,32 @@ protected void done() {
312329
String path = get();
313330
runtimeField.setText(path);
314331
runtimeField.setEnabled(false);
315-
downloadButton.setText("Downloaded");
332+
downloadButton.setText("Installed");
316333
downloadButton.setEnabled(false);
334+
downloadCheck.setText("✓");
335+
downloadCheck.setForeground(new Color(46, 204, 64));
336+
runtimeInstalled.set(true);
337+
317338
} catch (Exception ex) {
318339
JOptionPane.showMessageDialog(
319340
ConfigPanel.this,
320341
"Failed to download JDK: " + ex.getMessage(),
321342
"Download Error",
322343
JOptionPane.ERROR_MESSAGE
323344
);
324-
downloadButton.setText("Download JDK");
345+
downloadButton.setText("Install");
325346
downloadButton.setEnabled(true);
347+
downloadCheck.setText("✗");
348+
downloadCheck.setForeground(new Color(255, 65, 54));
349+
runtimeInstalled.set(false);
326350
}
327351
}
328352
};
329353
worker.execute();
330354
});
331355
runtimeButtonPanel.add(downloadButton);
356+
runtimeButtonPanel.add(Box.createHorizontalGlue());
357+
runtimeButtonPanel.add(downloadCheck);
332358

333359
// removing for now
334360
//runtimeButtonPanel.add(createBrowseButton(runtimeField, false));
@@ -413,5 +439,13 @@ public String getLibraryPath() {
413439
// TODO: Add a library path field to the config panel
414440
return null;
415441
}
442+
443+
public Observable<Boolean> getRuntimeInstalled() {
444+
return runtimeInstalled;
445+
}
446+
447+
public SkidfuscatorConfig getConfig() {
448+
return config;
449+
}
416450
}
417451

dev.skidfuscator.client.standalone/src/main/java/dev/skidfuscator/obfuscator/gui/ConsolePanel.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
import java.util.regex.Matcher;
2525
import java.util.regex.Pattern;
2626

27-
public class ConsolePanel extends JPanel {
27+
public class ConsolePanel extends JPanel implements SkidPanel {
2828
private final JTextPane consoleOutput;
2929
private final SimpleDateFormat timeFormat;
3030
private final StyledDocument doc;

dev.skidfuscator.client.standalone/src/main/java/dev/skidfuscator/obfuscator/gui/LibrariesPanel.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
import java.util.concurrent.atomic.AtomicInteger;
2929
import javax.swing.Timer;
3030

31-
public class LibrariesPanel extends JPanel {
31+
public class LibrariesPanel extends JPanel implements SkidPanel {
3232
private final JList<String> libraryList;
3333
private final DefaultListModel<String> libraryModel;
3434
private final JList<String> missingClassesList;
@@ -179,6 +179,9 @@ public LibrariesPanel(ConfigPanel configPanel, SkidApplicationClassSource classS
179179
add(bottomPanel, BorderLayout.SOUTH);
180180

181181
// Analyze the input jar if specified in config
182+
}
183+
184+
public void open() {
182185
SwingUtilities.invokeLater(this::analyzeConfigJar);
183186
}
184187

dev.skidfuscator.client.standalone/src/main/java/dev/skidfuscator/obfuscator/gui/MainFrame.java

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import com.formdev.flatlaf.ui.FlatTabbedPaneUI;
55
import dev.skidfuscator.obfuscator.Skidfuscator;
66
import dev.skidfuscator.obfuscator.SkidfuscatorSession;
7+
import dev.skidfuscator.obfuscator.util.JdkDownloader;
8+
import dev.skidfuscator.obfuscator.util.Observable;
79
import lombok.Getter;
810

911
import javax.imageio.ImageIO;
@@ -96,7 +98,7 @@ protected void paintTabArea(Graphics g, int tabPlacement, int selectedIndex) {
9698
g.drawString("Skidfuscator Community", 20, 175);
9799
g.setColor(new Color(130, 130, 130));
98100
g.setFont(new Font("Segoe UI", Font.ITALIC, 11));
99-
g.drawString("Build: 2023.1", 20, 190);
101+
g.drawString("Build: " + Skidfuscator.VERSION, 20, 190);
100102

101103
// Draw second separator
102104
g.setColor(Color.DARK_GRAY);
@@ -228,22 +230,37 @@ public void mouseClicked(MouseEvent e) {
228230
contentPanel.removeAll();
229231
switch (tabbedPane.getSelectedIndex()) {
230232
case 0:
233+
configPanel.open();
231234
contentPanel.add(configPanel, BorderLayout.CENTER);
232235
break;
233236
case 1:
237+
if (!JdkDownloader.isJdkDownloaded()) {
238+
JOptionPane.showMessageDialog(this, "Please download the JDK first", "Error", JOptionPane.ERROR_MESSAGE);
239+
tabbedPane.setSelectedIndex(0);
240+
return;
241+
}
242+
librariesPanel.open();
234243
contentPanel.add(librariesPanel, BorderLayout.CENTER);
235244
break;
236245
case 2:
237246
contentPanel.add(transformerPanel, BorderLayout.CENTER);
238247
break;
239248
case 3:
249+
consolePanel.open();
240250
contentPanel.add(consolePanel, BorderLayout.CENTER);
241251
break;
242252
}
243253
contentPanel.revalidate();
244254
contentPanel.repaint();
245255
});
246256

257+
258+
// Observe input/output and adapt button to it
259+
configPanel.getConfig().getValidInput().addObserver(value -> refreshStartButton());
260+
configPanel.getConfig().getValidOutput().addObserver(value -> refreshStartButton());
261+
configPanel.getRuntimeInstalled().addObserver(value -> refreshStartButton());
262+
refreshStartButton();
263+
247264
// Final setup
248265
pack();
249266
setLocationRelativeTo(null);
@@ -309,6 +326,23 @@ public void updateTabStates(boolean configEnabled, boolean transformersEnabled)
309326
tabbedPane.setEnabledAt(1, transformersEnabled);
310327
}
311328

329+
private void refreshStartButton() {
330+
System.out.println("Refreshing start button");
331+
332+
if (!configPanel.getConfig().isValid() || !configPanel.getRuntimeInstalled().get()) {
333+
// Set warning icon
334+
final Image warningIcon = new ImageIcon(getClass().getResource("/images/warning.png")).getImage();
335+
final Image warningImage = warningIcon.getScaledInstance(16, 16, Image.SCALE_SMOOTH);
336+
final ImageIcon warningIconScaled = new ImageIcon(warningImage);
337+
startButton.setIcon(warningIconScaled);
338+
startButton.setEnabled(false);
339+
} else {
340+
startButton.setToolTipText(null);
341+
startButton.setIcon(null);
342+
startButton.setEnabled(true);
343+
}
344+
}
345+
312346
public void startObfuscation() {
313347
ConfigPanel config = this.getConfigPanel();
314348
TransformerPanel transformers = this.getTransformerPanel();
@@ -347,15 +381,17 @@ public void startObfuscation() {
347381
? libraryFolder.toFile().listFiles()
348382
: new File(config.getLibsPath()).listFiles()
349383
)
350-
.runtime(config.getRuntimePath().isEmpty()
351-
? null
352-
: new File(config.getRuntimePath())
353-
)
384+
//.runtime(config.getRuntimePath().isEmpty()
385+
// ? null
386+
// : new File(config.getRuntimePath())
387+
//)
354388
.jmod(config.getRuntimePath().contains("jmods"))
355389
.debug(config.isDebugEnabled())
356390
.build();
357391
// Start obfuscation in background
358392
startButton.setEnabled(false);
393+
394+
359395
SwingWorker<Void, String> worker = new SwingWorker() {
360396
@Override
361397
protected Void doInBackground() {
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package dev.skidfuscator.obfuscator.gui;
2+
3+
public interface SkidPanel {
4+
default void open() {}
5+
}

dev.skidfuscator.client.standalone/src/main/java/dev/skidfuscator/obfuscator/gui/config/SkidfuscatorConfig.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@
22

33
import com.google.gson.Gson;
44
import com.google.gson.GsonBuilder;
5+
import dev.skidfuscator.obfuscator.util.Observable;
56
import lombok.Data;
67

78
import java.io.*;
8-
import java.nio.file.*;
9-
import java.util.Properties;
109

1110
@Data
1211
public class SkidfuscatorConfig {
@@ -22,6 +21,14 @@ public class SkidfuscatorConfig {
2221
private boolean phantomEnabled;
2322
private String lastDirectory;
2423

24+
private transient Observable<Boolean>
25+
validInput = new Observable.SimpleObservable<>(false),
26+
validOutput = new Observable.SimpleObservable<>(false);
27+
28+
public boolean isValid() {
29+
return validInput.get() && validOutput.get();
30+
}
31+
2532
public static class Builder {
2633
private final SkidfuscatorConfig config;
2734

dev.skidfuscator.client.standalone/src/main/java/dev/skidfuscator/obfuscator/util/LogoUtil.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package dev.skidfuscator.obfuscator.util;
22

3+
import dev.skidfuscator.obfuscator.Skidfuscator;
34
import lombok.experimental.UtilityClass;
45

56
import java.text.DateFormat;
@@ -61,7 +62,7 @@ public static void printLogo() {
6162
" │ " + topMemory + " │",
6263
" └───────────────────────────────────────────┘",
6364
"",
64-
" Author: Ghast Version: 2.0.11 Today: "
65+
" Author: Ghast Version: " + Skidfuscator.VERSION + " Today: "
6566
+ DateFormat.getDateTimeInstance().format(new Date(Instant.now().toEpochMilli())),
6667
""
6768
};

0 commit comments

Comments
 (0)