mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 16:47:31 -05:00
Merge pull request #1732 from DSheirer/1731-application-status-bar
#1731 Application Status Bar (cpu/memory/disk space).
This commit is contained in:
@@ -41,6 +41,8 @@ import io.github.dsheirer.icon.IconModel;
|
||||
import io.github.dsheirer.jmbe.JmbeEditor;
|
||||
import io.github.dsheirer.jmbe.JmbeEditorRequest;
|
||||
import io.github.dsheirer.module.log.EventLogManager;
|
||||
import io.github.dsheirer.monitor.ResourceMonitor;
|
||||
import io.github.dsheirer.monitor.StatusBox;
|
||||
import io.github.dsheirer.playlist.PlaylistManager;
|
||||
import io.github.dsheirer.preference.UserPreferences;
|
||||
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||
@@ -90,6 +92,7 @@ public class JavaFxWindowManager extends Application
|
||||
private Stage mPlaylistStage;
|
||||
private Stage mUserPreferencesStage;
|
||||
private Stage mRecordingViewerStage;
|
||||
private JFXPanel mStatusPanel;
|
||||
|
||||
/**
|
||||
* Constructs an instance. Note: this constructor is used for Swing applications.
|
||||
@@ -118,6 +121,27 @@ public class JavaFxWindowManager extends Application
|
||||
setup();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates or accesses the JavaFX status panel, used by the main application GUI.
|
||||
* @param resourceMonitor for statistics
|
||||
* @return JFXPanel accessible on Swing thread that delegates JavaFX scene creation to the FX event thread.
|
||||
*/
|
||||
public JFXPanel getStatusPanel(ResourceMonitor resourceMonitor)
|
||||
{
|
||||
if(mStatusPanel == null)
|
||||
{
|
||||
mStatusPanel = new JFXPanel();
|
||||
|
||||
//JFXPanel has to be populated on the FX event thread
|
||||
Platform.runLater(() -> {
|
||||
Scene scene = new Scene(new StatusBox(resourceMonitor));
|
||||
mStatusPanel.setScene(scene);
|
||||
});
|
||||
}
|
||||
|
||||
return mStatusPanel;
|
||||
}
|
||||
|
||||
private void setup()
|
||||
{
|
||||
//Register this class to receive events via each method annotated with @Subscribe
|
||||
|
||||
@@ -43,6 +43,7 @@ import io.github.dsheirer.icon.IconModel;
|
||||
import io.github.dsheirer.log.ApplicationLog;
|
||||
import io.github.dsheirer.map.MapService;
|
||||
import io.github.dsheirer.module.log.EventLogManager;
|
||||
import io.github.dsheirer.monitor.ResourceMonitor;
|
||||
import io.github.dsheirer.playlist.PlaylistManager;
|
||||
import io.github.dsheirer.preference.UserPreferences;
|
||||
import io.github.dsheirer.properties.SystemProperties;
|
||||
@@ -68,7 +69,6 @@ import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Point;
|
||||
import java.awt.Robot;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
@@ -82,6 +82,7 @@ import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
import javafx.application.Platform;
|
||||
import javafx.embed.swing.JFXPanel;
|
||||
import javafx.scene.control.ButtonType;
|
||||
import jiconfont.icons.font_awesome.FontAwesome;
|
||||
import jiconfont.swing.IconFontSwing;
|
||||
@@ -128,6 +129,8 @@ public class SDRTrunk implements Listener<TunerEvent>
|
||||
private UserPreferences mUserPreferences = new UserPreferences();
|
||||
private TunerManager mTunerManager;
|
||||
private ApplicationLog mApplicationLog;
|
||||
private ResourceMonitor mResourceMonitor;
|
||||
private JFXPanel mStatusPanel;
|
||||
|
||||
private String mTitle;
|
||||
|
||||
@@ -141,6 +144,8 @@ public class SDRTrunk implements Listener<TunerEvent>
|
||||
mApplicationLog = new ApplicationLog(mUserPreferences);
|
||||
mApplicationLog.start();
|
||||
|
||||
mResourceMonitor = new ResourceMonitor(mUserPreferences);
|
||||
|
||||
String operatingSystem = System.getProperty("os.name", "generic").toLowerCase(Locale.ENGLISH);
|
||||
|
||||
if(operatingSystem.contains("mac") || operatingSystem.contains("nux"))
|
||||
@@ -316,7 +321,7 @@ public class SDRTrunk implements Listener<TunerEvent>
|
||||
*/
|
||||
private void initGUI()
|
||||
{
|
||||
mMainGui.setLayout(new MigLayout("insets 0 0 0 0 ", "[grow,fill]", "[grow,fill]"));
|
||||
mMainGui.setLayout(new MigLayout("insets 0 0 0 0 ", "[grow,fill]", "[grow,fill][]"));
|
||||
|
||||
/**
|
||||
* Setup main JFrame window
|
||||
@@ -382,6 +387,10 @@ public class SDRTrunk implements Listener<TunerEvent>
|
||||
|
||||
mMainGui.add(mSplitPane, "cell 0 0,span,grow");
|
||||
|
||||
mResourceMonitor.start();
|
||||
mStatusPanel = mJavaFxWindowManager.getStatusPanel(mResourceMonitor);
|
||||
mMainGui.add(mStatusPanel, "span,growx");
|
||||
|
||||
/**
|
||||
* Menu items
|
||||
*/
|
||||
@@ -392,14 +401,9 @@ public class SDRTrunk implements Listener<TunerEvent>
|
||||
menuBar.add(fileMenu);
|
||||
|
||||
JMenuItem exitMenu = new JMenuItem("Exit");
|
||||
exitMenu.addActionListener(
|
||||
new ActionListener()
|
||||
{
|
||||
public void actionPerformed(ActionEvent event)
|
||||
{
|
||||
processShutdown();
|
||||
System.exit(0);
|
||||
}
|
||||
exitMenu.addActionListener(event -> {
|
||||
processShutdown();
|
||||
System.exit(0);
|
||||
}
|
||||
);
|
||||
|
||||
@@ -571,6 +575,7 @@ public class SDRTrunk implements Listener<TunerEvent>
|
||||
mLog.info("Stopping channels ...");
|
||||
mPlaylistManager.getChannelProcessingManager().shutdown();
|
||||
mAudioRecordingManager.stop();
|
||||
mResourceMonitor.stop();
|
||||
|
||||
mLog.info("Stopping spectral display ...");
|
||||
mSpectralPanel.clearTuner();
|
||||
@@ -742,14 +747,9 @@ public class SDRTrunk implements Listener<TunerEvent>
|
||||
|
||||
setSelected(mBroadcastStatusPanel != null);
|
||||
|
||||
addActionListener(new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
toggleBroadcastStatusPanelVisibility();
|
||||
setSelected(mBroadcastStatusVisible);
|
||||
}
|
||||
addActionListener(e -> {
|
||||
toggleBroadcastStatusPanelVisibility();
|
||||
setSelected(mBroadcastStatusVisible);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
* Copyright (C) 2014-2023 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -24,6 +24,7 @@ import io.github.dsheirer.eventbus.MyEventBus;
|
||||
import io.github.dsheirer.preference.PreferenceType;
|
||||
import io.github.dsheirer.preference.UserPreferences;
|
||||
import io.github.dsheirer.preference.directory.DirectoryPreference;
|
||||
import java.io.File;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.geometry.Insets;
|
||||
@@ -31,6 +32,7 @@ import javafx.geometry.Orientation;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.Separator;
|
||||
import javafx.scene.control.Spinner;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
@@ -39,8 +41,6 @@ import javafx.stage.Stage;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
|
||||
/**
|
||||
* Preference settings for channel event view
|
||||
@@ -97,6 +97,9 @@ public class DirectoryPreferenceEditor extends HBox
|
||||
private Button mResetStreamingButton;
|
||||
private Label mStreamingPathLabel;
|
||||
|
||||
private Spinner<Integer> mRecordingSpinner;
|
||||
private Spinner<Integer> mEventLogSpinner;
|
||||
|
||||
public DirectoryPreferenceEditor(UserPreferences userPreferences)
|
||||
{
|
||||
mDirectoryPreference = userPreferences.getDirectoryPreference();
|
||||
@@ -247,11 +250,57 @@ public class DirectoryPreferenceEditor extends HBox
|
||||
|
||||
GridPane.setMargin(getResetStreamingButton(), new Insets(2, 0, 2, 0));
|
||||
mEditorPane.add(getResetStreamingButton(), 3, row++);
|
||||
|
||||
Label monitorLabel = new Label("File storage usage monitoring - maximum size thresholds (MB)");
|
||||
GridPane.setMargin(monitorLabel, new Insets(15, 0, 2, 0));
|
||||
mEditorPane.add(monitorLabel, 0, row++, 4, 1);
|
||||
mEditorPane.add(new Separator(Orientation.HORIZONTAL), 0, row++, 4, 1);
|
||||
|
||||
mEditorPane.add(new Label("Event Logs"), 0, row);
|
||||
GridPane.setMargin(getEventLogSpinner(), new Insets(2, 2, 2, 0));
|
||||
mEditorPane.add(getEventLogSpinner(), 1, row++);
|
||||
|
||||
mEditorPane.add(new Label("Recordings"), 0, row);
|
||||
GridPane.setMargin(getRecordingSpinner(), new Insets(2, 2, 2, 0));
|
||||
mEditorPane.add(getRecordingSpinner(), 1, row);
|
||||
}
|
||||
|
||||
return mEditorPane;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recording directory maximum size threshold spinner
|
||||
* @return spinner
|
||||
*/
|
||||
private Spinner<Integer> getRecordingSpinner()
|
||||
{
|
||||
if(mRecordingSpinner == null)
|
||||
{
|
||||
mRecordingSpinner = new Spinner<>(100, Integer.MAX_VALUE, mDirectoryPreference.getDirectoryMaxUsageRecordings(), 100);
|
||||
mRecordingSpinner.valueProperty().addListener((observable, oldValue, newValue) -> mDirectoryPreference
|
||||
.setDirectoryMaxUsageRecordings(newValue));
|
||||
}
|
||||
|
||||
return mRecordingSpinner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Event log directory maximum size threshold spinner
|
||||
* @return spinner
|
||||
*/
|
||||
private Spinner<Integer> getEventLogSpinner()
|
||||
{
|
||||
if(mEventLogSpinner == null)
|
||||
{
|
||||
mEventLogSpinner = new Spinner<>(100, Integer.MAX_VALUE, mDirectoryPreference.getDirectoryMaxUsageEventLogs(), 100);
|
||||
mEventLogSpinner.setEditable(true);
|
||||
mEventLogSpinner.valueProperty().addListener((observable, oldValue, newValue) -> mDirectoryPreference
|
||||
.setDirectoryMaxUsageEventLogs(newValue));
|
||||
}
|
||||
|
||||
return mEventLogSpinner;
|
||||
}
|
||||
|
||||
private Label getApplicationRootLabel()
|
||||
{
|
||||
if(mApplicationRootLabel == null)
|
||||
|
||||
272
src/main/java/io/github/dsheirer/monitor/ResourceMonitor.java
Normal file
272
src/main/java/io/github/dsheirer/monitor/ResourceMonitor.java
Normal file
@@ -0,0 +1,272 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2023 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
package io.github.dsheirer.monitor;
|
||||
|
||||
import io.github.dsheirer.log.LoggingSuppressor;
|
||||
import io.github.dsheirer.preference.UserPreferences;
|
||||
import io.github.dsheirer.util.ThreadPool;
|
||||
import java.io.IOException;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.OperatingSystemMXBean;
|
||||
import java.nio.file.FileStore;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.DoubleProperty;
|
||||
import javafx.beans.property.LongProperty;
|
||||
import javafx.beans.property.SimpleDoubleProperty;
|
||||
import javafx.beans.property.SimpleLongProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Provides real-time monitoring of application resource usage.
|
||||
*
|
||||
* Monitors:
|
||||
* - CPU usage
|
||||
* - RAM usage
|
||||
* - Drive Space - Event Logs
|
||||
* - Drive Space - Recordings
|
||||
*/
|
||||
public class ResourceMonitor
|
||||
{
|
||||
private static final Logger sLog = LoggerFactory.getLogger(ResourceMonitor.class);
|
||||
private static final LoggingSuppressor sLogSuppressor = new LoggingSuppressor(sLog);
|
||||
private static final int SCALOR_MEGABYTE = 1024 * 1024;
|
||||
private UserPreferences mUserPreferences;
|
||||
private ScheduledFuture<?> mMemoryCpuMonitorFuture;
|
||||
private ScheduledFuture<?> mStorageMonitorFuture;
|
||||
private LongProperty mMemoryTotal = new SimpleLongProperty();
|
||||
private LongProperty mMemoryAllocated = new SimpleLongProperty();
|
||||
private LongProperty mMemoryUsed = new SimpleLongProperty();
|
||||
private DoubleProperty mJavaMemoryUsedPercentage = new SimpleDoubleProperty();
|
||||
private DoubleProperty mSystemMemoryUsedPercentage = new SimpleDoubleProperty();
|
||||
private DoubleProperty mCpuPercentage = new SimpleDoubleProperty();
|
||||
private DoubleProperty mDirectoryUsePercentEventLogs = new SimpleDoubleProperty();
|
||||
private DoubleProperty mDirectoryUsePercentRecordings = new SimpleDoubleProperty();
|
||||
private StringProperty mFileSizeEventLogs = new SimpleStringProperty();
|
||||
private StringProperty mFileSizeRecordings = new SimpleStringProperty();
|
||||
private OperatingSystemMXBean mOperatingSystemMXBean;
|
||||
|
||||
/**
|
||||
* Constructs an instance
|
||||
*/
|
||||
public ResourceMonitor(UserPreferences userPreferences)
|
||||
{
|
||||
mUserPreferences = userPreferences;
|
||||
|
||||
try
|
||||
{
|
||||
mOperatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
sLog.error("Error accessing operating system MX bean to monitor CPU usage", e);
|
||||
}
|
||||
|
||||
mMemoryTotal.set(Runtime.getRuntime().maxMemory());
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts resource monitoring.
|
||||
*/
|
||||
public void start()
|
||||
{
|
||||
if(mMemoryCpuMonitorFuture == null)
|
||||
{
|
||||
mMemoryCpuMonitorFuture = ThreadPool.SCHEDULED.scheduleAtFixedRate(() -> updateCpuMemory(), 1, 1, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
if(mStorageMonitorFuture == null)
|
||||
{
|
||||
mStorageMonitorFuture = ThreadPool.SCHEDULED.scheduleAtFixedRate(() -> updateDirectoryUsage(), 1,30, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops resource monitoring.
|
||||
*/
|
||||
public void stop()
|
||||
{
|
||||
if(mMemoryCpuMonitorFuture != null)
|
||||
{
|
||||
mMemoryCpuMonitorFuture.cancel(true);
|
||||
mMemoryCpuMonitorFuture = null;
|
||||
}
|
||||
|
||||
if(mStorageMonitorFuture != null)
|
||||
{
|
||||
mStorageMonitorFuture.cancel(true);
|
||||
mStorageMonitorFuture = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Timer-driven method to update CPU and memory usage statistics.
|
||||
*/
|
||||
private void updateCpuMemory()
|
||||
{
|
||||
double cpuLoadScaled = 0.0;
|
||||
|
||||
if(mOperatingSystemMXBean != null)
|
||||
{
|
||||
double load = mOperatingSystemMXBean.getSystemLoadAverage();
|
||||
cpuLoadScaled = load / mOperatingSystemMXBean.getAvailableProcessors();
|
||||
}
|
||||
|
||||
final double loadFinal = cpuLoadScaled;
|
||||
|
||||
Platform.runLater(() -> {
|
||||
mMemoryAllocated.set(Runtime.getRuntime().totalMemory());
|
||||
mMemoryUsed.set(mMemoryAllocated.getValue() - Runtime.getRuntime().freeMemory());
|
||||
mJavaMemoryUsedPercentage.set((double)mMemoryUsed.get() / (double)mMemoryAllocated.get());
|
||||
mSystemMemoryUsedPercentage.set((double)mMemoryAllocated.get() / (double)mMemoryTotal.get());
|
||||
mCpuPercentage.set(loadFinal);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Timer-driven method to update directory space usage statistics
|
||||
*/
|
||||
private void updateDirectoryUsage()
|
||||
{
|
||||
long thresholdEventLog = mUserPreferences.getDirectoryPreference().getDirectoryMaxUsageEventLogs() * SCALOR_MEGABYTE;
|
||||
long thresholdRecording = mUserPreferences.getDirectoryPreference().getDirectoryMaxUsageRecordings() * SCALOR_MEGABYTE;
|
||||
|
||||
Path recordingPath = mUserPreferences.getDirectoryPreference().getDirectoryRecording();
|
||||
Path eventLogsPath = mUserPreferences.getDirectoryPreference().getDirectoryEventLog();
|
||||
|
||||
try
|
||||
{
|
||||
FileStore recordingFileStore = Files.getFileStore(recordingPath);
|
||||
FileStore eventLogsFileStore = Files.getFileStore(eventLogsPath);
|
||||
|
||||
long recordingAvailable = recordingFileStore.getUsableSpace();
|
||||
long eventLogsAvailable = eventLogsFileStore.getUsableSpace();
|
||||
|
||||
long eventLogUsed = FileUtils.sizeOfDirectory(eventLogsPath.toFile());
|
||||
long recordingUsed = FileUtils.sizeOfDirectory(recordingPath.toFile());
|
||||
|
||||
long eventLogMax = Math.min(thresholdEventLog, eventLogUsed + eventLogsAvailable);
|
||||
long recordingMax = Math.min(thresholdRecording, recordingUsed + recordingAvailable);
|
||||
|
||||
Platform.runLater(() -> {
|
||||
mDirectoryUsePercentEventLogs.set((double)eventLogUsed / (double)eventLogMax);
|
||||
mDirectoryUsePercentRecordings.set((double)recordingUsed / (double)recordingMax);
|
||||
mFileSizeEventLogs.set(FileUtils.byteCountToDisplaySize(eventLogUsed));
|
||||
mFileSizeRecordings.set(FileUtils.byteCountToDisplaySize(recordingUsed));
|
||||
});
|
||||
}
|
||||
catch(IOException ioe)
|
||||
{
|
||||
sLogSuppressor.error("Log Once", 1, "Unable to monitor file system - " + ioe.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Directory use percentage for event logs directory.
|
||||
* @return usage in range 0.0 - 1.0 (or larger if it exceeds the threshold)
|
||||
*/
|
||||
public DoubleProperty directoryUsePercentEventLogsProperty()
|
||||
{
|
||||
return mDirectoryUsePercentEventLogs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Directory use percentage for recordings directory.
|
||||
* @return usage in range 0.0 - 1.0 (or larger if it exceeds the threshold)
|
||||
*/
|
||||
public DoubleProperty directoryUsePercentRecordingsProperty()
|
||||
{
|
||||
return mDirectoryUsePercentRecordings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formatted value property for file size in event logs directory.
|
||||
* @return print friendly value property
|
||||
*/
|
||||
public StringProperty fileSizeEventLogsProperty()
|
||||
{
|
||||
return mFileSizeEventLogs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formatted value property for file size in recordings directory.
|
||||
* @return print friendly value property
|
||||
*/
|
||||
public StringProperty fileSizeRecordingsProperty()
|
||||
{
|
||||
return mFileSizeRecordings;
|
||||
}
|
||||
|
||||
/**
|
||||
* CPU usage percentage.
|
||||
* @return usage in range 0.0 - 1.0
|
||||
*/
|
||||
public DoubleProperty cpuPercentageProperty()
|
||||
{
|
||||
return mCpuPercentage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Property for total system memory
|
||||
*/
|
||||
public LongProperty memoryTotalProperty()
|
||||
{
|
||||
return mMemoryTotal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Property for memory currently allocated to the JVM
|
||||
*/
|
||||
public LongProperty memoryAllocatedProperty()
|
||||
{
|
||||
return mMemoryAllocated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Property for memory used by the JVM (out of what has been allocated)
|
||||
*/
|
||||
public LongProperty memoryUsedProperty()
|
||||
{
|
||||
return mMemoryUsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Property for memory used vs memory allocated to the JVM.
|
||||
*/
|
||||
public DoubleProperty javaMemoryUsedPercentageProperty()
|
||||
{
|
||||
return mJavaMemoryUsedPercentage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Property for JVM allocated vs total system memory.
|
||||
*/
|
||||
public DoubleProperty systemMemoryUsedPercentageProperty()
|
||||
{
|
||||
return mSystemMemoryUsedPercentage;
|
||||
}
|
||||
}
|
||||
96
src/main/java/io/github/dsheirer/monitor/StatusBox.java
Normal file
96
src/main/java/io/github/dsheirer/monitor/StatusBox.java
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2023 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
package io.github.dsheirer.monitor;
|
||||
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ProgressBar;
|
||||
import javafx.scene.layout.HBox;
|
||||
|
||||
/**
|
||||
* JavaFX status panel box.
|
||||
*/
|
||||
public class StatusBox extends HBox
|
||||
{
|
||||
private ResourceMonitor mResourceMonitor;
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
* @param resourceMonitor for accessing resource usage statistics.
|
||||
*/
|
||||
public StatusBox(ResourceMonitor resourceMonitor)
|
||||
{
|
||||
mResourceMonitor = resourceMonitor;
|
||||
setPadding(new Insets(0, 0, 2, 0));
|
||||
setSpacing(6);
|
||||
Label cpuLabel = new Label("CPU:");
|
||||
cpuLabel.setPadding(new Insets(0, 0, 0, 10));
|
||||
cpuLabel.setAlignment(Pos.CENTER_RIGHT);
|
||||
getChildren().add(cpuLabel);
|
||||
|
||||
ProgressBar cpuIndicator = new ProgressBar();
|
||||
cpuIndicator.progressProperty().bind(mResourceMonitor.cpuPercentageProperty());
|
||||
getChildren().add(cpuIndicator);
|
||||
|
||||
Label memoryLabel = new Label("Allocated Memory:");
|
||||
memoryLabel.setAlignment(Pos.CENTER_RIGHT);
|
||||
getChildren().add(memoryLabel);
|
||||
|
||||
ProgressBar memoryBar = new ProgressBar();
|
||||
memoryBar.progressProperty().bind(mResourceMonitor.systemMemoryUsedPercentageProperty());
|
||||
getChildren().add(memoryBar);
|
||||
|
||||
Label javaMemoryLabel = new Label("Used Memory:");
|
||||
javaMemoryLabel.setAlignment(Pos.CENTER_RIGHT);
|
||||
getChildren().add(javaMemoryLabel);
|
||||
|
||||
ProgressBar javaMemoryBar = new ProgressBar();
|
||||
javaMemoryBar.progressProperty().bind(mResourceMonitor.javaMemoryUsedPercentageProperty());
|
||||
getChildren().add(javaMemoryBar);
|
||||
|
||||
Label eventLogsLabel = new Label("Event Logs:");
|
||||
eventLogsLabel.setAlignment(Pos.CENTER_RIGHT);
|
||||
getChildren().add(eventLogsLabel);
|
||||
|
||||
ProgressBar eventLogsBar = new ProgressBar();
|
||||
eventLogsBar.progressProperty().bind(mResourceMonitor.directoryUsePercentEventLogsProperty());
|
||||
getChildren().add(eventLogsBar);
|
||||
|
||||
Label eventLogsSizeLabel = new Label();
|
||||
eventLogsSizeLabel.textProperty().bind(mResourceMonitor.fileSizeEventLogsProperty());
|
||||
eventLogsSizeLabel.setAlignment(Pos.CENTER_RIGHT);
|
||||
getChildren().add(eventLogsSizeLabel);
|
||||
|
||||
Label recordingsLabel = new Label("Recordings:");
|
||||
recordingsLabel.setPadding(new Insets(0, 0, 0, 10));
|
||||
recordingsLabel.setAlignment(Pos.CENTER_RIGHT);
|
||||
getChildren().add(recordingsLabel);
|
||||
|
||||
ProgressBar recordingsBar = new ProgressBar();
|
||||
recordingsBar.progressProperty().bind(mResourceMonitor.directoryUsePercentRecordingsProperty());
|
||||
getChildren().add(recordingsBar);
|
||||
|
||||
Label recordingsSizeLabel = new Label();
|
||||
recordingsSizeLabel.textProperty().bind(mResourceMonitor.fileSizeRecordingsProperty());
|
||||
recordingsSizeLabel.setAlignment(Pos.CENTER_RIGHT);
|
||||
getChildren().add(recordingsSizeLabel);
|
||||
}
|
||||
}
|
||||
37
src/main/java/io/github/dsheirer/monitor/StatusPanel.java
Normal file
37
src/main/java/io/github/dsheirer/monitor/StatusPanel.java
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2023 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
package io.github.dsheirer.monitor;
|
||||
|
||||
import javafx.embed.swing.JFXPanel;
|
||||
|
||||
/**
|
||||
* Status panel providing resource usage statistics.
|
||||
*/
|
||||
public class StatusPanel extends JFXPanel
|
||||
{
|
||||
private ResourceMonitor mResourceMonitor;
|
||||
|
||||
public StatusPanel(ResourceMonitor resourceMonitor)
|
||||
{
|
||||
mResourceMonitor = resourceMonitor;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
* Copyright (C) 2014-2023 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -22,13 +22,12 @@ package io.github.dsheirer.preference.directory;
|
||||
import io.github.dsheirer.preference.Preference;
|
||||
import io.github.dsheirer.preference.PreferenceType;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.prefs.Preferences;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* User preferences for directories
|
||||
@@ -38,6 +37,9 @@ public class DirectoryPreference extends Preference
|
||||
private final static Logger mLog = LoggerFactory.getLogger(DirectoryPreference.class);
|
||||
private Preferences mPreferences = Preferences.userNodeForPackage(DirectoryPreference.class);
|
||||
|
||||
private static final int DEFAULT_USAGE_THRESHOLD_RECORDINGS_MB = 2000;
|
||||
private static final int DEFAULT_USAGE_THRESHOLD_EVENT_LOGS_MB = 200;
|
||||
|
||||
private static final String DIRECTORY_APPLICATION_ROOT = "SDRTrunk";
|
||||
private static final String DIRECTORY_APPLICATION_LOG = "logs";
|
||||
private static final String DIRECTORY_CONFIGURATION = "configuration";
|
||||
@@ -57,6 +59,8 @@ public class DirectoryPreference extends Preference
|
||||
private static final String PREFERENCE_KEY_DIRECTORY_RECORDING = "directory.recording";
|
||||
private static final String PREFERENCE_KEY_DIRECTORY_SCREEN_CAPTURE = "directory.screen.capture";
|
||||
private static final String PREFERENCE_KEY_DIRECTORY_STREAMING = "directory.streaming";
|
||||
private static final String PREFERENCE_KEY_DIRECTORY_MAX_USAGE_RECORDINGS = "directory.max.usage.recordings";
|
||||
private static final String PREFERENCE_KEY_DIRECTORY_MAX_USAGE_EVENT_LOGS = "directory.max.usage.event.logs";
|
||||
|
||||
private Path mDirectoryApplicationRoot;
|
||||
private Path mDirectoryApplicationLogs;
|
||||
@@ -67,6 +71,8 @@ public class DirectoryPreference extends Preference
|
||||
private Path mDirectoryRecording;
|
||||
private Path mDirectoryScreenCapture;
|
||||
private Path mDirectoryStreaming;
|
||||
private Integer mDirectoryMaxUsageRecordings;
|
||||
private Integer mDirectoryMaxUsageEventLogs;
|
||||
|
||||
/**
|
||||
* Constructs this preference with an update listener
|
||||
@@ -127,6 +133,58 @@ public class DirectoryPreference extends Preference
|
||||
mDirectoryStreaming = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* User-specified maximum drive space usage for the recording directory.
|
||||
* @return max usage threshold in MB.
|
||||
*/
|
||||
public int getDirectoryMaxUsageRecordings()
|
||||
{
|
||||
if(mDirectoryMaxUsageRecordings == null)
|
||||
{
|
||||
mDirectoryMaxUsageRecordings = mPreferences.getInt(PREFERENCE_KEY_DIRECTORY_MAX_USAGE_RECORDINGS,
|
||||
DEFAULT_USAGE_THRESHOLD_RECORDINGS_MB);
|
||||
}
|
||||
|
||||
return mDirectoryMaxUsageRecordings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the threshold for maximum drive space usage for the recordings directory.
|
||||
* @param thresholdMB threshold in MB
|
||||
*/
|
||||
public void setDirectoryMaxUsageRecordings(int thresholdMB)
|
||||
{
|
||||
mPreferences.putInt(PREFERENCE_KEY_DIRECTORY_MAX_USAGE_RECORDINGS, thresholdMB);
|
||||
mDirectoryMaxUsageRecordings = thresholdMB;
|
||||
notifyPreferenceUpdated();
|
||||
}
|
||||
|
||||
/**
|
||||
* User-specified maximum drive space usage for the event logs directory.
|
||||
* @return max usage threshold in MB.
|
||||
*/
|
||||
public int getDirectoryMaxUsageEventLogs()
|
||||
{
|
||||
if(mDirectoryMaxUsageEventLogs == null)
|
||||
{
|
||||
mDirectoryMaxUsageEventLogs = mPreferences.getInt(PREFERENCE_KEY_DIRECTORY_MAX_USAGE_EVENT_LOGS,
|
||||
DEFAULT_USAGE_THRESHOLD_EVENT_LOGS_MB);
|
||||
}
|
||||
|
||||
return mDirectoryMaxUsageEventLogs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the threshold for maximum drive space usage for the event logs directory.
|
||||
* @param thresholdMB threshold in MB
|
||||
*/
|
||||
public void setDirectoryMaxUsageEventLogs(int thresholdMB)
|
||||
{
|
||||
mPreferences.putInt(PREFERENCE_KEY_DIRECTORY_MAX_USAGE_EVENT_LOGS, thresholdMB);
|
||||
mDirectoryMaxUsageEventLogs = thresholdMB;
|
||||
notifyPreferenceUpdated();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a stored recording directory preference so that the default path can be used again
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user