fix(gui): use another implementation for font dialog (#2310)

This commit is contained in:
Skylot
2024-10-22 21:29:00 +01:00
parent 3788e4ef3a
commit e5be41b9cc
6 changed files with 125 additions and 65 deletions
+1 -1
View File
@@ -31,7 +31,7 @@ dependencies {
implementation("io.github.oshai:kotlin-logging-jvm:7.0.0")
implementation("com.fifesoft:rsyntaxtextarea:3.4.1")
implementation(files("libs/jfontchooser-1.0.5.jar"))
implementation("org.drjekyll:fontchooser:3.1.0")
implementation("hu.kazocsaba:image-viewer:1.2.3")
implementation("com.formdev:flatlaf:3.5.1")
Binary file not shown.
@@ -1,52 +0,0 @@
package jadx.gui.settings.ui;
import java.awt.GraphicsEnvironment;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import say.swing.JFontChooser;
public class JPreferredFontChooser extends JFontChooser {
private static final Logger LOG = LoggerFactory.getLogger(JPreferredFontChooser.class);
private static final String[] PREFERRED_FONTS = new String[] {
"Monospaced", "Consolas", "Courier", "Courier New",
"Lucida Sans Typewriter", "Lucida Console",
"SimSun", "SimHei",
};
private String[] filteredFonts;
@Override
protected String[] getFontFamilies() {
if (filteredFonts == null) {
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
Set<String> fontSet = new HashSet<>();
Collections.addAll(fontSet, env.getAvailableFontFamilyNames());
List<String> found = new ArrayList<>(PREFERRED_FONTS.length);
for (String font : PREFERRED_FONTS) {
if (fontSet.contains(font)) {
found.add(font);
}
}
if (found.size() == PREFERRED_FONTS.length) {
filteredFonts = PREFERRED_FONTS;
} else if (found.size() > 0) {
filteredFonts = new String[found.size()];
for (int i = 0; i < found.size(); i++) {
filteredFonts[i] = found.get(i);
}
} else {
LOG.warn("Can't found any preferred fonts for smali, use all available.");
filteredFonts = env.getAvailableFontFamilyNames();
}
}
return filteredFonts;
}
}
@@ -44,8 +44,6 @@ import org.slf4j.LoggerFactory;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import say.swing.JFontChooser;
import jadx.api.CommentsLevel;
import jadx.api.DecompilationMode;
import jadx.api.JadxArgs;
@@ -63,6 +61,7 @@ import jadx.gui.settings.JadxUpdateChannel;
import jadx.gui.settings.LineNumbersMode;
import jadx.gui.settings.XposedCodegenLanguage;
import jadx.gui.settings.ui.cache.CacheSettingsGroup;
import jadx.gui.settings.ui.font.JadxFontDialog;
import jadx.gui.settings.ui.plugins.PluginSettings;
import jadx.gui.settings.ui.shortcut.ShortcutsSettingsGroup;
import jadx.gui.ui.MainWindow;
@@ -371,11 +370,9 @@ public class JadxSettingsWindow extends JDialog {
fontBtn.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
JFontChooser fontChooser = new JFontChooser();
fontChooser.setSelectedFont(settings.getFont());
int result = fontChooser.showDialog(JadxSettingsWindow.this);
if (result == JFontChooser.OK_OPTION) {
Font font = fontChooser.getSelectedFont();
Font font = new JadxFontDialog(JadxSettingsWindow.this, NLS.str("preferences.font"))
.select(settings.getFont(), false);
if (font != null) {
LOG.debug("Selected Font: {}", font);
settings.setFont(font);
mainWindow.loadSettings();
@@ -387,11 +384,9 @@ public class JadxSettingsWindow extends JDialog {
smaliFontBtn.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
JFontChooser fontChooser = new JPreferredFontChooser();
fontChooser.setSelectedFont(settings.getSmaliFont());
int result = fontChooser.showDialog(JadxSettingsWindow.this);
if (result == JFontChooser.OK_OPTION) {
Font font = fontChooser.getSelectedFont();
Font font = new JadxFontDialog(JadxSettingsWindow.this, NLS.str("preferences.smali_font"))
.select(settings.getSmaliFont(), true);
if (font != null) {
LOG.debug("Selected Font: {} for smali", font);
settings.setSmaliFont(font);
mainWindow.loadSettings();
@@ -0,0 +1,31 @@
package jadx.gui.settings.ui.font;
import java.lang.reflect.Field;
import javax.swing.JCheckBox;
import org.drjekyll.fontchooser.FontChooser;
import org.drjekyll.fontchooser.panes.FamilyPane;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FontChooserHack {
private static final Logger LOG = LoggerFactory.getLogger(FontChooserHack.class);
public static void setOnlyMonospace(FontChooser fontChooser) {
try {
FamilyPane familyPane = (FamilyPane) getPrivateField(fontChooser, "familyPane");
JCheckBox monospacedCheckBox = (JCheckBox) getPrivateField(familyPane, "monospacedCheckBox");
monospacedCheckBox.setSelected(true);
monospacedCheckBox.setEnabled(false);
} catch (Throwable e) {
LOG.debug("Failed to set only monospace check box", e);
}
}
private static Object getPrivateField(Object obj, String fieldName) throws NoSuchFieldException, IllegalAccessException {
Field f = obj.getClass().getDeclaredField(fieldName);
f.setAccessible(true);
return f.get(obj);
}
}
@@ -0,0 +1,86 @@
package jadx.gui.settings.ui.font;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Font;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
import org.drjekyll.fontchooser.FontChooser;
import org.jetbrains.annotations.Nullable;
import jadx.gui.settings.JadxSettings;
import jadx.gui.settings.ui.JadxSettingsWindow;
import jadx.gui.utils.NLS;
public class JadxFontDialog extends JDialog {
private static final long serialVersionUID = 7609857698785777587L;
private final FontChooser fontChooser = new FontChooser();
private final JadxSettings settings;
private boolean selected = false;
public JadxFontDialog(JadxSettingsWindow settingsWindow, String title) {
super(settingsWindow, title, true);
settings = settingsWindow.getMainWindow().getSettings();
initComponents();
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
if (!settings.loadWindowPos(this)) {
pack();
}
}
public @Nullable Font select(Font currentFont, boolean onlyMonospace) {
fontChooser.setSelectedFont(currentFont);
if (onlyMonospace) {
FontChooserHack.setOnlyMonospace(fontChooser);
}
setVisible(true);
Font selectedFont = fontChooser.getSelectedFont();
if (selected && !selectedFont.equals(currentFont)) {
return selectedFont;
}
return null;
}
private void initComponents() {
JPanel chooserPanel = new JPanel();
chooserPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10));
chooserPanel.setLayout(new BorderLayout(0, 10));
chooserPanel.add(fontChooser);
JPanel controlPanel = new JPanel();
controlPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
controlPanel.setLayout(new FlowLayout(FlowLayout.TRAILING));
JButton okBtn = new JButton();
okBtn.setText(NLS.str("common_dialog.ok"));
okBtn.setMnemonic('o');
okBtn.addActionListener(event -> {
selected = true;
dispose();
});
JButton cancelBtn = new JButton();
cancelBtn.setText(NLS.str("common_dialog.cancel"));
cancelBtn.setMnemonic('c');
cancelBtn.addActionListener(event -> dispose());
controlPanel.add(okBtn);
controlPanel.add(cancelBtn);
add(chooserPanel);
add(controlPanel, BorderLayout.PAGE_END);
getRootPane().setDefaultButton(okBtn);
}
@Override
public void dispose() {
settings.saveWindowPos(this);
super.dispose();
}
}