diff --git a/jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java b/jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java index 81abde3d99773ff1b72eb00da854a649a97aeb0a..24f1eaef87e5d26d6eda9ab1e8b502d3a0e9fbea 100644 --- a/jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java +++ b/jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java @@ -35,7 +35,7 @@ public class JadxSettings extends JadxCLIArgs { private static final Path USER_HOME = Paths.get(System.getProperty("user.home")); private static final int RECENT_PROJECTS_COUNT = 15; - private static final int CURRENT_SETTINGS_VERSION = 9; + private static final int CURRENT_SETTINGS_VERSION = 10; private static final Font DEFAULT_FONT = new RSyntaxTextArea().getFont(); @@ -57,7 +57,7 @@ public class JadxSettings extends JadxCLIArgs { protected String excludedPackages = ""; private boolean autoSaveProject = false; - private boolean showHeapUsageBar = true; + private boolean showHeapUsageBar = false; private Map windowPos = new HashMap<>(); private int mainWindowExtendedState = JFrame.NORMAL; @@ -436,6 +436,10 @@ public class JadxSettings extends JadxCLIArgs { if (fromVersion == 8) { fromVersion++; } + if (fromVersion == 9) { + showHeapUsageBar = false; + fromVersion++; + } settingsVersion = CURRENT_SETTINGS_VERSION; sync(); } diff --git a/jadx-gui/src/main/java/jadx/gui/ui/HeapUsageBar.java b/jadx-gui/src/main/java/jadx/gui/ui/HeapUsageBar.java index 313a29506c285992d476b92594786ba6ae53128e..3d7ac2d676e8bd3dcb9aa04dbab74365c54231bb 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/HeapUsageBar.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/HeapUsageBar.java @@ -1,47 +1,62 @@ package jadx.gui.ui; import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.util.Objects; +import java.util.concurrent.TimeUnit; import javax.swing.*; +import javax.swing.FocusManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import hu.akarnokd.rxjava2.swing.SwingSchedulers; +import io.reactivex.Flowable; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; + import jadx.gui.utils.NLS; import jadx.gui.utils.UiUtils; -public class HeapUsageBar extends JProgressBar implements ActionListener { - private static final Logger LOG = LoggerFactory.getLogger(HeapUsageBar.class); +public class HeapUsageBar extends JProgressBar { private static final long serialVersionUID = -8739563124249884967L; - private static final double TWO_TO_20 = 1048576d; + private static final Logger LOG = LoggerFactory.getLogger(HeapUsageBar.class); + + private static final double GB = 1024 * 1024 * 1024; private static final Color GREEN = new Color(0, 180, 0); private static final Color RED = new Color(200, 0, 0); private final transient Runtime runtime = Runtime.getRuntime(); - private final transient Timer timer; + private final transient FocusManager focusManager = FocusManager.getCurrentManager(); private final double maxGB; + private final long limit; + private final String labelTemplate; + + private transient Disposable timer; + private transient Color currentColor; public HeapUsageBar() { setBorderPainted(false); setStringPainted(true); - setValue(10); - int maxKB = (int) (runtime.maxMemory() / 1024); - setMaximum(maxKB); - maxGB = maxKB / TWO_TO_20; - update(); - timer = new Timer(2000, this); + + long maxMemory = runtime.maxMemory(); + maxGB = maxMemory / GB; + limit = maxMemory - UiUtils.MIN_FREE_MEMORY; + labelTemplate = NLS.str("heapUsage.text"); + + setMaximum((int) (maxMemory / 1024)); + setColor(GREEN); + addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { Runtime.getRuntime().gc(); - update(); + HeapUsageBar.this.update(); if (LOG.isDebugEnabled()) { LOG.debug("Memory used: {}", UiUtils.memoryInfo()); } @@ -49,31 +64,74 @@ public class HeapUsageBar extends JProgressBar implements ActionListener { }); } - public void update() { - long used = runtime.totalMemory() - runtime.freeMemory(); - int usedKB = (int) (used / 1024); - setValue(usedKB); - setString(NLS.str("heapUsage.text", (usedKB / TWO_TO_20), maxGB)); - - if ((used + UiUtils.MIN_FREE_MEMORY) > runtime.maxMemory()) { - setForeground(RED); + @Override + public void setVisible(boolean enabled) { + super.setVisible(enabled); + if (enabled) { + startTimer(); } else { - setForeground(GREEN); + reset(); } } - @Override - public void actionPerformed(ActionEvent e) { + private static class UpdateData { + int value; + String label; + Color color; + } + + private static final UpdateData SKIP_UPDATE = new UpdateData(); + + private void startTimer() { + if (timer != null) { + return; + } update(); + timer = Flowable.interval(2, TimeUnit.SECONDS, Schedulers.newThread()) + .map(i -> prepareUpdate()) + .filter(update -> update != SKIP_UPDATE) + .distinctUntilChanged((a, b) -> Objects.equals(a.label, b.label)) // pass only if label changed + .subscribeOn(SwingSchedulers.edt()) + .subscribe(this::applyUpdate); } - @Override - public void setVisible(boolean aFlag) { - super.setVisible(aFlag); - if (aFlag) { - timer.start(); - } else { - timer.stop(); + public UpdateData prepareUpdate() { + if (focusManager.getActiveWindow() == null) { + // skip update if app window not active + return SKIP_UPDATE; + } + UpdateData updateData = new UpdateData(); + long used = runtime.totalMemory() - runtime.freeMemory(); + updateData.value = (int) (used / 1024); + updateData.label = String.format(labelTemplate, used / GB, maxGB); + updateData.color = used > limit ? RED : GREEN; + return updateData; + } + + public void applyUpdate(UpdateData update) { + setValue(update.value); + setString(update.label); + setColor(update.color); + } + + private void setColor(Color color) { + if (currentColor != color) { + setForeground(color); + currentColor = color; + } + } + + private void update() { + UpdateData update = prepareUpdate(); + if (update != SKIP_UPDATE) { + applyUpdate(update); + } + } + + public void reset() { + if (timer != null) { + timer.dispose(); + timer = null; } } } diff --git a/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java b/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java index ee41542cea5e3736baf298b73f01074ba5b88d3b..2de4b87732fbd83ed2cd54e957ebf230ea069fc3 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java @@ -1116,6 +1116,7 @@ public class MainWindow extends JFrame { settings.setMainWindowExtendedState(getExtendedState()); cancelBackgroundJobs(); wrapper.close(); + heapUsageBar.reset(); dispose(); FileUtils.deleteTempRootDir();