mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 08:37:25 -05:00
Updates pull request from Roman Tsypuk to convert the build system from
ant to gradle. Removes linux and windows application launch scripts and produces an executable jar with all resources included.
This commit is contained in:
514
src/main/java/io/github/dsheirer/gui/SDRTrunk.java
Normal file
514
src/main/java/io/github/dsheirer/gui/SDRTrunk.java
Normal file
@@ -0,0 +1,514 @@
|
||||
/*******************************************************************************
|
||||
* sdrtrunk
|
||||
* Copyright (C) 2014-2017 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.gui;
|
||||
|
||||
import com.jidesoft.swing.JideSplitPane;
|
||||
import io.github.dsheirer.audio.AudioManager;
|
||||
import io.github.dsheirer.audio.broadcast.BroadcastModel;
|
||||
import io.github.dsheirer.audio.broadcast.BroadcastStatusPanel;
|
||||
import io.github.dsheirer.controller.ControllerPanel;
|
||||
import io.github.dsheirer.controller.channel.ChannelModel;
|
||||
import io.github.dsheirer.controller.channel.ChannelProcessingManager;
|
||||
import io.github.dsheirer.controller.channel.ChannelSelectionManager;
|
||||
import io.github.dsheirer.controller.channel.map.ChannelMapModel;
|
||||
import io.github.dsheirer.icon.IconManager;
|
||||
import io.github.dsheirer.map.MapService;
|
||||
import io.github.dsheirer.playlist.PlaylistManager;
|
||||
import io.github.dsheirer.properties.SystemProperties;
|
||||
import io.github.dsheirer.record.RecorderManager;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.settings.SettingsManager;
|
||||
import io.github.dsheirer.source.SourceManager;
|
||||
import io.github.dsheirer.source.tuner.TunerEvent;
|
||||
import io.github.dsheirer.source.tuner.TunerModel;
|
||||
import io.github.dsheirer.source.tuner.TunerSpectralDisplayManager;
|
||||
import io.github.dsheirer.source.tuner.configuration.TunerConfigurationModel;
|
||||
import io.github.dsheirer.spectrum.SpectralDisplayPanel;
|
||||
import io.github.dsheirer.util.ThreadPool;
|
||||
import io.github.dsheirer.util.TimeStamp;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import io.github.dsheirer.alias.AliasModel;
|
||||
import io.github.dsheirer.alias.action.AliasActionManager;
|
||||
import io.github.dsheirer.module.log.EventLogManager;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class SDRTrunk implements Listener<TunerEvent>
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(SDRTrunk.class);
|
||||
private static final String PROPERTY_BROADCAST_STATUS_VISIBLE = "main.broadcast.status.visible";
|
||||
private boolean mBroadcastStatusVisible;
|
||||
|
||||
private IconManager mIconManager;
|
||||
private BroadcastStatusPanel mBroadcastStatusPanel;
|
||||
private BroadcastModel mBroadcastModel;
|
||||
private ControllerPanel mControllerPanel;
|
||||
private SettingsManager mSettingsManager;
|
||||
private SpectralDisplayPanel mSpectralPanel;
|
||||
private JFrame mMainGui = new JFrame();
|
||||
private JideSplitPane mSplitPane;
|
||||
|
||||
private String mTitle;
|
||||
|
||||
public SDRTrunk()
|
||||
{
|
||||
mLog.info("*******************************************************************");
|
||||
mLog.info("**** sdrtrunk: a trunked radio and digital decoding application ***");
|
||||
mLog.info("**** website: https://github.com/dsheirer/sdrtrunk ***");
|
||||
mLog.info("*******************************************************************");
|
||||
mLog.info("Memory Logging Format: [Used/Allocated PercentUsed%]");
|
||||
mLog.info("Host CPU Cores: " + Runtime.getRuntime().availableProcessors());
|
||||
mLog.info("Host OS Name: " + System.getProperty("os.name"));
|
||||
mLog.info("Host OS Arch: " + System.getProperty("os.arch"));
|
||||
mLog.info("Host OS Version: " + System.getProperty("os.version"));
|
||||
mLog.info("Host Max Java Memory: " + FileUtils.byteCountToDisplaySize(Runtime.getRuntime().maxMemory()));
|
||||
|
||||
//Setup the application home directory
|
||||
Path home = getHomePath();
|
||||
|
||||
ThreadPool.logSettings();
|
||||
|
||||
mLog.info("Home path: " + home.toString());
|
||||
|
||||
//Load properties file
|
||||
if(home != null)
|
||||
{
|
||||
loadProperties(home);
|
||||
}
|
||||
|
||||
//Log current properties setting
|
||||
SystemProperties.getInstance().logCurrentSettings();
|
||||
|
||||
TunerConfigurationModel tunerConfigurationModel = new TunerConfigurationModel();
|
||||
TunerModel tunerModel = new TunerModel(tunerConfigurationModel);
|
||||
|
||||
mIconManager = new IconManager();
|
||||
|
||||
mSettingsManager = new SettingsManager(tunerConfigurationModel);
|
||||
|
||||
AliasModel aliasModel = new AliasModel();
|
||||
|
||||
ChannelModel channelModel = new ChannelModel();
|
||||
|
||||
ChannelMapModel channelMapModel = new ChannelMapModel();
|
||||
|
||||
EventLogManager eventLogManager = new EventLogManager();
|
||||
|
||||
RecorderManager recorderManager = new RecorderManager();
|
||||
|
||||
SourceManager sourceManager = new SourceManager(tunerModel, mSettingsManager);
|
||||
|
||||
ChannelProcessingManager channelProcessingManager = new ChannelProcessingManager(
|
||||
channelModel, channelMapModel, aliasModel, eventLogManager, recorderManager, sourceManager);
|
||||
channelProcessingManager.addAudioPacketListener(recorderManager);
|
||||
|
||||
channelModel.addListener(channelProcessingManager);
|
||||
|
||||
ChannelSelectionManager channelSelectionManager =
|
||||
new ChannelSelectionManager(channelModel);
|
||||
channelModel.addListener(channelSelectionManager);
|
||||
|
||||
AliasActionManager aliasActionManager = new AliasActionManager();
|
||||
channelProcessingManager.addMessageListener(aliasActionManager);
|
||||
|
||||
AudioManager audioManager = new AudioManager(sourceManager.getMixerManager());
|
||||
channelProcessingManager.addAudioPacketListener(audioManager);
|
||||
|
||||
mBroadcastModel = new BroadcastModel(mIconManager);
|
||||
|
||||
channelProcessingManager.addAudioPacketListener(mBroadcastModel);
|
||||
|
||||
MapService mapService = new MapService(mIconManager);
|
||||
channelProcessingManager.addMessageListener(mapService);
|
||||
|
||||
mControllerPanel = new ControllerPanel(audioManager, aliasModel, mBroadcastModel,
|
||||
channelModel, channelMapModel, channelProcessingManager, mIconManager,
|
||||
mapService, mSettingsManager, sourceManager, tunerModel);
|
||||
|
||||
mSpectralPanel = new SpectralDisplayPanel(channelModel,
|
||||
channelProcessingManager, mSettingsManager);
|
||||
|
||||
TunerSpectralDisplayManager tunerSpectralDisplayManager =
|
||||
new TunerSpectralDisplayManager(mSpectralPanel,
|
||||
channelModel, channelProcessingManager, mSettingsManager);
|
||||
tunerModel.addListener(tunerSpectralDisplayManager);
|
||||
tunerModel.addListener(this);
|
||||
|
||||
PlaylistManager playlistManager = new PlaylistManager(aliasModel, mBroadcastModel, channelModel,
|
||||
channelMapModel);
|
||||
|
||||
playlistManager.init();
|
||||
|
||||
mLog.info("starting main application gui");
|
||||
|
||||
//Initialize the GUI
|
||||
initGUI();
|
||||
|
||||
tunerModel.requestFirstTunerDisplay();
|
||||
|
||||
//Start the gui
|
||||
EventQueue.invokeLater(new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
mMainGui.setVisible(true);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch the application.
|
||||
*/
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new SDRTrunk();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the contents of the frame.
|
||||
*/
|
||||
private void initGUI()
|
||||
{
|
||||
mMainGui.setLayout(new MigLayout("insets 0 0 0 0 ", "[grow,fill]", "[grow,fill]"));
|
||||
|
||||
/**
|
||||
* Setup main JFrame window
|
||||
*/
|
||||
mTitle = SystemProperties.getInstance().getApplicationName();
|
||||
mMainGui.setTitle(mTitle);
|
||||
mMainGui.setBounds(100, 100, 1280, 800);
|
||||
mMainGui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
|
||||
//Set preferred sizes to influence the split
|
||||
mSpectralPanel.setPreferredSize(new Dimension(1280, 300));
|
||||
mControllerPanel.setPreferredSize(new Dimension(1280, 500));
|
||||
|
||||
mSplitPane = new JideSplitPane(JideSplitPane.VERTICAL_SPLIT);
|
||||
mSplitPane.setDividerSize(5);
|
||||
mSplitPane.add(mSpectralPanel);
|
||||
mSplitPane.add(mControllerPanel);
|
||||
|
||||
mBroadcastStatusVisible = SystemProperties.getInstance().get(PROPERTY_BROADCAST_STATUS_VISIBLE, false);
|
||||
|
||||
//Show broadcast status panel when user requests - disabled by default
|
||||
if(mBroadcastStatusVisible)
|
||||
{
|
||||
mSplitPane.add(getBroadcastStatusPanel());
|
||||
}
|
||||
|
||||
mMainGui.add(mSplitPane, "cell 0 0,span,grow");
|
||||
|
||||
/**
|
||||
* Menu items
|
||||
*/
|
||||
JMenuBar menuBar = new JMenuBar();
|
||||
mMainGui.setJMenuBar(menuBar);
|
||||
|
||||
JMenu fileMenu = new JMenu("File");
|
||||
menuBar.add(fileMenu);
|
||||
|
||||
JMenuItem logFilesMenu = new JMenuItem("Logs & Recordings");
|
||||
logFilesMenu.addActionListener(new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent arg0)
|
||||
{
|
||||
try
|
||||
{
|
||||
Desktop.getDesktop().open(getHomePath().toFile());
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
mLog.error("Couldn't open file explorer");
|
||||
|
||||
JOptionPane.showMessageDialog(mMainGui,
|
||||
"Can't launch file explorer - files are located at: " +
|
||||
getHomePath().toString(),
|
||||
"Can't launch file explorer",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
});
|
||||
fileMenu.add(logFilesMenu);
|
||||
|
||||
JMenuItem settingsMenu = new JMenuItem("Icon Manager");
|
||||
settingsMenu.addActionListener(new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent arg0)
|
||||
{
|
||||
mIconManager.showEditor(mMainGui);
|
||||
}
|
||||
});
|
||||
fileMenu.add(settingsMenu);
|
||||
|
||||
fileMenu.add(new JSeparator());
|
||||
|
||||
JMenuItem exitMenu = new JMenuItem("Exit");
|
||||
exitMenu.addActionListener(
|
||||
new ActionListener()
|
||||
{
|
||||
public void actionPerformed(ActionEvent event)
|
||||
{
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
fileMenu.add(exitMenu);
|
||||
|
||||
JMenu viewMenu = new JMenu("View");
|
||||
|
||||
viewMenu.add(new BroadcastStatusVisibleMenuItem(mControllerPanel));
|
||||
|
||||
menuBar.add(viewMenu);
|
||||
|
||||
JMenuItem screenCaptureItem = new JMenuItem("Screen Capture");
|
||||
|
||||
screenCaptureItem.setMnemonic(KeyEvent.VK_C);
|
||||
screenCaptureItem.setAccelerator(
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_C, ActionEvent.ALT_MASK));
|
||||
|
||||
screenCaptureItem.addActionListener(new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent arg0)
|
||||
{
|
||||
try
|
||||
{
|
||||
Robot robot = new Robot();
|
||||
|
||||
final BufferedImage image =
|
||||
robot.createScreenCapture(mMainGui.getBounds());
|
||||
|
||||
SystemProperties props = SystemProperties.getInstance();
|
||||
|
||||
Path capturePath = props.getApplicationFolder("screen_captures");
|
||||
|
||||
if(!Files.exists(capturePath))
|
||||
{
|
||||
try
|
||||
{
|
||||
Files.createDirectory(capturePath);
|
||||
}
|
||||
catch(IOException e)
|
||||
{
|
||||
mLog.error("Couldn't create 'screen_captures' "
|
||||
+ "subdirectory in the " +
|
||||
"SDRTrunk application directory", e);
|
||||
}
|
||||
}
|
||||
|
||||
String filename = TimeStamp.getTimeStamp("_") +
|
||||
"_screen_capture.png";
|
||||
|
||||
final Path captureFile = capturePath.resolve(filename);
|
||||
|
||||
EventQueue.invokeLater(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
ImageIO.write(image, "png",
|
||||
captureFile.toFile());
|
||||
}
|
||||
catch(IOException e)
|
||||
{
|
||||
mLog.error("Couldn't write screen capture to "
|
||||
+ "file [" + captureFile.toString() + "]", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
catch(AWTException e)
|
||||
{
|
||||
mLog.error("Exception while taking screen capture", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
menuBar.add(screenCaptureItem);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy constructor for broadcast status panel
|
||||
*/
|
||||
private BroadcastStatusPanel getBroadcastStatusPanel()
|
||||
{
|
||||
if(mBroadcastStatusPanel == null)
|
||||
{
|
||||
mBroadcastStatusPanel = new BroadcastStatusPanel(mBroadcastModel);
|
||||
mBroadcastStatusPanel.setPreferredSize(new Dimension(880, 70));
|
||||
mBroadcastStatusPanel.getTable().setEnabled(false);
|
||||
}
|
||||
|
||||
return mBroadcastStatusPanel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles visibility of the broadcast channels status panel at the bottom of the controller panel
|
||||
*/
|
||||
private void toggleBroadcastStatusPanelVisibility()
|
||||
{
|
||||
mBroadcastStatusVisible = !mBroadcastStatusVisible;
|
||||
|
||||
EventQueue.invokeLater(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
if(mBroadcastStatusVisible)
|
||||
{
|
||||
mSplitPane.add(getBroadcastStatusPanel());
|
||||
}
|
||||
else
|
||||
{
|
||||
mSplitPane.remove(getBroadcastStatusPanel());
|
||||
}
|
||||
|
||||
mMainGui.revalidate();
|
||||
}
|
||||
});
|
||||
|
||||
SystemProperties.getInstance().set(PROPERTY_BROADCAST_STATUS_VISIBLE, mBroadcastStatusVisible);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Loads the application properties file from the user's home directory,
|
||||
* creating the properties file for the first-time, if necessary
|
||||
*/
|
||||
private void loadProperties(Path homePath)
|
||||
{
|
||||
Path propsPath = homePath.resolve("SDRTrunk.properties");
|
||||
|
||||
if(!Files.exists(propsPath))
|
||||
{
|
||||
try
|
||||
{
|
||||
mLog.info("SDRTrunk - creating application properties file [" +
|
||||
propsPath.toAbsolutePath() + "]");
|
||||
|
||||
Files.createFile(propsPath);
|
||||
}
|
||||
catch(IOException e)
|
||||
{
|
||||
mLog.error("SDRTrunk - couldn't create application properties "
|
||||
+ "file [" + propsPath.toAbsolutePath(), e);
|
||||
}
|
||||
}
|
||||
|
||||
if(Files.exists(propsPath))
|
||||
{
|
||||
SystemProperties.getInstance().load(propsPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
mLog.error("SDRTrunk - couldn't find or recreate the SDRTrunk " +
|
||||
"application properties file");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets (or creates) the SDRTRunk application home directory.
|
||||
*
|
||||
* Note: the user can change this setting to allow log files and other
|
||||
* files to reside elsewhere on the file system.
|
||||
*/
|
||||
private Path getHomePath()
|
||||
{
|
||||
Path homePath = FileSystems.getDefault()
|
||||
.getPath(System.getProperty("user.home"), "SDRTrunk");
|
||||
|
||||
if(!Files.exists(homePath))
|
||||
{
|
||||
try
|
||||
{
|
||||
Files.createDirectory(homePath);
|
||||
|
||||
mLog.info("SDRTrunk - created application home directory [" +
|
||||
homePath.toString() + "]");
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
homePath = null;
|
||||
|
||||
mLog.error("SDRTrunk: exception while creating SDRTrunk home " +
|
||||
"directory in the user's home directory", e);
|
||||
}
|
||||
}
|
||||
|
||||
return homePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(TunerEvent event)
|
||||
{
|
||||
if(event.getEvent() == TunerEvent.Event.REQUEST_MAIN_SPECTRAL_DISPLAY)
|
||||
{
|
||||
mMainGui.setTitle(mTitle + " - " + event.getTuner().getName());
|
||||
}
|
||||
}
|
||||
|
||||
public class BroadcastStatusVisibleMenuItem extends JCheckBoxMenuItem
|
||||
{
|
||||
private ControllerPanel mControllerPanel;
|
||||
|
||||
public BroadcastStatusVisibleMenuItem(ControllerPanel controllerPanel)
|
||||
{
|
||||
super("Show Streaming Status");
|
||||
|
||||
mControllerPanel = controllerPanel;
|
||||
|
||||
setSelected(mBroadcastStatusPanel != null);
|
||||
|
||||
addActionListener(new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
toggleBroadcastStatusPanelVisibility();
|
||||
setSelected(mBroadcastStatusVisible);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user