#90 [WIP] Adds support for attribute monitors to all of the decoder states. Updates color scheme in 'Now Playing' view for channel states. Wires selection listener for selected channel metadata to the Events and Messages views. Finalizes format for horizontal audio panels, font and coloration.

This commit is contained in:
Denny
2017-01-20 21:12:57 -05:00
parent ce47d2545d
commit 2d9c3c0aa4
25 changed files with 1511 additions and 1816 deletions

View File

@@ -25,6 +25,7 @@ import icon.IconManager;
import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import properties.SystemProperties;
import sample.Listener;
import settings.ColorSetting;
import settings.ColorSetting.ColorSettingName;
@@ -41,23 +42,27 @@ public class AudioChannelPanel extends JPanel
private static final long serialVersionUID = 1L;
private static final Logger mLog = LoggerFactory.getLogger(AudioChannelPanel.class);
public static final String PROPERTY_PREFIX = "audio.channel.panel.color.";
public static final String PROPERTY_COLOR_BACKGROUND = PROPERTY_PREFIX + "background";
public static final String PROPERTY_COLOR_LABEL = PROPERTY_PREFIX + "label";
public static final String PROPERTY_COLOR_MUTED = PROPERTY_PREFIX + "muted";
public static final String PROPERTY_COLOR_VALUE = PROPERTY_PREFIX + "value";
private Font mFont = new Font(Font.MONOSPACED, Font.PLAIN, 16);
private Color mBackgroundColor;
private Color mLabelColor;
private Color mDetailsColor;
private Color mMutedColor;
private Color mValueColor;
private IconManager mIconManager;
private SettingsManager mSettingsManager;
private AudioOutput mAudioOutput;
private JLabel mMutedLabel = new JLabel("M");
private JLabel mChannelName = new JLabel(" ");
private JLabel mToLabel = new JLabel("TO:");
private JLabel mTo = new JLabel("-----");
private JLabel mToAlias = new JLabel(" ");
private JLabel mMutedLabel = new JLabel("MUTED");
private JLabel mFromLabel = new JLabel("FROM:");
private JLabel mFrom = new JLabel("-----");
private JLabel mFromAlias = new JLabel(" ");
private JLabel mTo = new JLabel("-----");
private boolean mConfigured = false;
@@ -75,67 +80,36 @@ public class AudioChannelPanel extends JPanel
mAudioOutput.setMetadataListener(new AudioMetadataProcessor());
}
mLabelColor = mSettingsManager.getColorSetting(
ColorSettingName.CHANNEL_STATE_LABEL_DECODER).getColor();
mDetailsColor = mSettingsManager.getColorSetting(
ColorSettingName.CHANNEL_STATE_LABEL_DETAILS).getColor();
mBackgroundColor = SystemProperties.getInstance().get(PROPERTY_COLOR_BACKGROUND, Color.BLACK);
mLabelColor = SystemProperties.getInstance().get(PROPERTY_COLOR_LABEL, Color.LIGHT_GRAY);
mMutedColor = SystemProperties.getInstance().get(PROPERTY_COLOR_MUTED, Color.RED);
mValueColor = SystemProperties.getInstance().get(PROPERTY_COLOR_VALUE, Color.GREEN);
init();
}
private void init()
{
setLayout(new MigLayout("align center center, insets 0 0 0 0",
"[][][right][grow,fill][grow,fill][right][grow,fill][grow,fill]", ""));
setBackground(Color.BLACK);
setLayout(new MigLayout("align center center, insets 0 0 0 0", "[][][align right]0[grow,fill]", ""));
setBackground(mBackgroundColor);
mMutedLabel.setFont(mFont);
mMutedLabel.setForeground(Color.RED);
mMutedLabel.setForeground(mMutedColor);
mMutedLabel.setVisible(false);
add(mMutedLabel);
mChannelName = new JLabel(mAudioOutput != null ? mAudioOutput.getChannelName() : " ");
mChannelName.setFont(mFont);
mChannelName.setForeground(mDetailsColor);
mChannelName.setForeground(mLabelColor);
add(mChannelName);
mToLabel.setFont(mFont);
if(mAudioOutput != null)
{
mToLabel.setForeground(mLabelColor);
}
else
{
mToLabel.setForeground(getBackground());
}
add(mToLabel);
mTo.setFont(mFont);
mTo.setForeground(mLabelColor);
add(mTo);
mToAlias.setFont(mFont);
mToAlias.setForeground(mLabelColor);
mToAlias.setForeground(mValueColor);
add(mToAlias);
mFromLabel.setFont(mFont);
if(mAudioOutput != null)
{
mFromLabel.setForeground(mLabelColor);
}
else
{
mFromLabel.setForeground(getBackground());
}
add(mFromLabel);
mFrom.setFont(mFont);
mFrom.setForeground(mLabelColor);
add(mFrom);
mFromAlias.setFont(mFont);
mFromAlias.setForeground(mLabelColor);
add(mFromAlias);
mTo.setFont(mFont);
mTo.setForeground(mValueColor);
add(mTo);
}
@Override
@@ -175,7 +149,6 @@ public class AudioChannelPanel extends JPanel
*/
private void resetLabels()
{
updateLabel(mFrom, null, mFromAlias, null);
updateLabel(mTo, null, mToAlias, null);
mConfigured = false;
@@ -190,14 +163,15 @@ public class AudioChannelPanel extends JPanel
{
if(value != null)
{
valueLabel.setText(value);
if(alias != null)
{
aliasLabel.setIcon(mIconManager.getIcon(alias.getIconName(), 16));
valueLabel.setText(alias.getName());
aliasLabel.setIcon(mIconManager.getIcon(alias.getIconName(), 18));
}
else
{
valueLabel.setText(value);
aliasLabel.setIcon(null);
}
}
@@ -224,9 +198,6 @@ public class AudioChannelPanel extends JPanel
@Override
public void run()
{
updateLabel(mFrom, metadata.getPrimaryAddressFrom().getIdentifier(),
mFromAlias, metadata.getPrimaryAddressFrom().getAlias());
updateLabel(mTo, metadata.getPrimaryAddressTo().getIdentifier(),
mToAlias, metadata.getPrimaryAddressTo().getAlias());
@@ -249,14 +220,6 @@ public class AudioChannelPanel extends JPanel
switch(colorSetting.getColorSettingName())
{
case CHANNEL_STATE_LABEL_DECODER:
if(mFrom != null)
{
mFrom.setForeground(mLabelColor);
}
if(mFromAlias != null)
{
mFromAlias.setForeground(mLabelColor);
}
if(mTo != null)
{
mTo.setForeground(mLabelColor);
@@ -266,16 +229,6 @@ public class AudioChannelPanel extends JPanel
mToAlias.setForeground(mLabelColor);
}
break;
case CHANNEL_STATE_LABEL_DETAILS:
if(mFromLabel != null)
{
mFromLabel.setForeground(mDetailsColor);
}
if(mToLabel != null)
{
mToLabel.setForeground(mDetailsColor);
}
break;
default:
break;
}

View File

@@ -33,7 +33,8 @@ public class AudioChannelsPanel extends JPanel
public AudioChannelsPanel(IconManager iconManager, SettingsManager settingsManager, IAudioController controller)
{
setLayout(new MigLayout("insets 0 0 0 0", "[][grow,fill][][grow,fill]", "[grow,fill]"));
// setLayout(new MigLayout("insets 0 0 0 0", "[][grow,fill][][grow,fill]", "[grow,fill]"));
setLayout(new MigLayout("insets 0 0 0 0", "[][sg,grow,fill][][sg,grow,fill]", "[grow,fill]"));
setBackground(Color.BLACK);

View File

@@ -259,8 +259,15 @@ public abstract class AudioBroadcaster implements Listener<AudioRecording>
//Remove all pending audio recordings
while(!mAudioRecordingQueue.isEmpty())
{
AudioRecording recording = mAudioRecordingQueue.get(0);
recording.removePendingReplay();
try
{
AudioRecording recording = mAudioRecordingQueue.get(0);
recording.removePendingReplay();
}
catch(Exception e)
{
//Ignore
}
}
}
}

View File

@@ -0,0 +1,99 @@
/*******************************************************************************
* 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 channel.metadata;
import alias.Alias;
import alias.AliasList;
import alias.id.AliasIDType;
import sample.Listener;
import static alias.id.AliasIDType.*;
public class AliasedIntegerAttributeMonitor extends AttributeMonitor<Integer>
{
private static final AliasIDType[] VALID_ID_TYPES = {STATUS, LTR_NET_UID};
private AliasList mAliasList;
private AliasIDType mAliasIDType;
/**
* Provides monitoring of a String attribute's values with occurrence heuristics enabled and alias lookup with each
* change in the attribute's value.
*
* @param attribute to monitor
* @param listener to receive change requests
* @param aliasList to lookup alias from
* @param aliasIDType to determine correct alias lookup method in alias list
*/
public AliasedIntegerAttributeMonitor(Attribute attribute, Listener<AttributeChangeRequest> listener, AliasList aliasList,
AliasIDType aliasIDType)
{
super(attribute, listener);
if(!isValidIDType(aliasIDType))
{
throw new IllegalArgumentException("Alias ID Type [" + aliasIDType.name() + "] is not supported");
}
mAliasList = aliasList;
mAliasIDType = aliasIDType;
}
/**
* Indicates if the alias ID type is a supported/valid type for this monitor.
*/
public static boolean isValidIDType(AliasIDType type)
{
for(AliasIDType validType: VALID_ID_TYPES)
{
if(type == validType)
{
return true;
}
}
return false;
}
/**
* Lookup of the alias that corresponds to the value's alias ID type
*/
@Override
protected Alias getAlias()
{
Alias alias = null;
if(mAliasList != null)
{
if(hasValue())
{
switch(mAliasIDType)
{
case STATUS:
alias = mAliasList.getStatus(getValue());
break;
case LTR_NET_UID:
alias = mAliasList.getUniqueID(getValue());
break;
}
}
}
return alias;
}
}

View File

@@ -51,13 +51,15 @@ public class AttributeMonitor<T>
* different from the current value, has a higher occurrence count than the current value. If heuristics are
* disabled, then a change is emitted at each change in the value.
* @param t
*
* @return true if the value was changed after processing
*/
public void process(T t)
public boolean process(T t)
{
boolean changed = false;
if(t != null && !mIllegalValues.contains(t))
{
boolean changed = false;
if(mHeuristicsEnabled)
{
if(mOccurrenceCounts.containsKey(t))
@@ -103,6 +105,8 @@ public class AttributeMonitor<T>
mListener.receive(new AttributeChangeRequest(mAttribute, getValue(), getAlias()));
}
}
return changed;
}
/**

View File

@@ -18,11 +18,13 @@
******************************************************************************/
package channel.metadata;
import channel.state.State;
import controller.channel.Channel;
import sample.Listener;
import javax.swing.table.AbstractTableModel;
import java.awt.*;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -30,22 +32,28 @@ import java.util.Map;
public class ChannelMetadataModel extends AbstractTableModel implements Listener<MutableMetadataChangeEvent>
{
public static final int COLUMN_STATE = 0;
public static final int COLUMN_FREQUENCY = 1;
public static final int COLUMN_PRIMARY = 2;
public static final int COLUMN_SECONDARY = 3;
public static final int COLUMN_MESSAGE = 4;
public static final int COLUMN_NETWORK = 5;
public static final int COLUMN_CONFIGURATION = 6;
private final DecimalFormat FREQUENCY_FORMATTER = new DecimalFormat( "#.0000" );
private static final String[] COLUMNS =
{"State", "Frequency", "Primary", "Secondary", "Message", "Network", "Configuration"};
public static final int COLUMN_STATE = 0;
public static final int COLUMN_DECODER = 1;
public static final int COLUMN_CHANNEL = 2;
public static final int COLUMN_FREQUENCY = 3;
public static final int COLUMN_PRIMARY_FROM = 4;
public static final int COLUMN_PRIMARY_TO = 5;
public static final int COLUMN_SECONDARY_FROM = 6;
public static final int COLUMN_SECONDARY_TO = 7;
public static final int COLUMN_CONFIGURATION_NAME = 8;
public static final int COLUMN_MESSAGE = 9;
private static final String[] COLUMNS = {"State", "Decoder", "Channel", "Frequency", "Primary From", "Primary To",
"Secondary From", "Secondary To", "Channel Name", "Message"};
private List<MutableMetadata> mChannelMetadata = new ArrayList();
private Map<MutableMetadata,Channel> mMetadataChannelMap = new HashMap();
public void add(MutableMetadata metadata, Channel channel)
{
//Execute on the swing thread to avoid threading issues
EventQueue.invokeLater(new Runnable()
{
@Override
@@ -65,6 +73,7 @@ public class ChannelMetadataModel extends AbstractTableModel implements Listener
public void remove(MutableMetadata metadata)
{
//Execute on the swing thread to avoid threading issues
EventQueue.invokeLater(new Runnable()
{
@Override
@@ -82,6 +91,27 @@ public class ChannelMetadataModel extends AbstractTableModel implements Listener
});
}
/**
* Get the channel metadata at the specified model row index
*/
public Metadata getMetadata(int row)
{
if(row < mChannelMetadata.size())
{
return mChannelMetadata.get(row);
}
return null;
}
/**
* Returns the channel that matches the metadata or null
*/
public Channel getChannelFromMetadata(Metadata metadata)
{
return mMetadataChannelMap.get(metadata);
}
@Override
public int getRowCount()
{
@@ -103,7 +133,27 @@ public class ChannelMetadataModel extends AbstractTableModel implements Listener
@Override
public Class<?> getColumnClass(int columnIndex)
{
return MutableMetadata.class;
switch(columnIndex)
{
case COLUMN_STATE:
return State.class;
case COLUMN_DECODER:
case COLUMN_CHANNEL:
case COLUMN_FREQUENCY:
case COLUMN_MESSAGE:
case COLUMN_CONFIGURATION_NAME:
return String.class;
case COLUMN_PRIMARY_TO:
case COLUMN_PRIMARY_FROM:
case COLUMN_SECONDARY_TO:
case COLUMN_SECONDARY_FROM:
return MutableMetadata.class;
default:
return String.class;
}
}
@Override
@@ -111,7 +161,57 @@ public class ChannelMetadataModel extends AbstractTableModel implements Listener
{
if(rowIndex <= mChannelMetadata.size())
{
return mChannelMetadata.get(rowIndex);
Metadata metadata = mChannelMetadata.get(rowIndex);
switch(columnIndex)
{
case COLUMN_STATE:
return metadata.getState();
case COLUMN_DECODER:
if(metadata.hasPrimaryDecoderType())
{
return metadata.getPrimaryDecoderType().getShortDisplayString();
}
return null;
case COLUMN_CHANNEL:
return metadata.getChannelFrequencyLabel();
case COLUMN_FREQUENCY:
if(metadata.hasChannelFrequency())
{
return FREQUENCY_FORMATTER.format((double)metadata.getChannelFrequency() / 1E6d);
}
return null;
case COLUMN_MESSAGE:
if(metadata.hasMessageType() | metadata.hasMessage())
{
StringBuilder sb = new StringBuilder();
if(metadata.hasMessageType())
{
sb.append(metadata.getMessageType()).append(" ");
}
if(metadata.hasMessage())
{
sb.append(metadata.getMessage());
}
return sb.toString();
}
return null;
case COLUMN_CONFIGURATION_NAME:
return metadata.getChannelConfigurationLabel1();
case COLUMN_PRIMARY_TO:
case COLUMN_PRIMARY_FROM:
case COLUMN_SECONDARY_TO:
case COLUMN_SECONDARY_FROM:
return metadata;
default:
return String.class;
}
}
return null;
@@ -120,6 +220,7 @@ public class ChannelMetadataModel extends AbstractTableModel implements Listener
@Override
public void receive(MutableMetadataChangeEvent mutableMetadataChangeEvent)
{
//Execute on the swing thread to avoid threading issues
EventQueue.invokeLater(new Runnable()
{
@Override
@@ -132,13 +233,16 @@ public class ChannelMetadataModel extends AbstractTableModel implements Listener
switch(mutableMetadataChangeEvent.getAttribute())
{
case CHANNEL_CONFIGURATION_LABEL_1:
break;
case CHANNEL_CONFIGURATION_LABEL_2:
fireTableCellUpdated(rowIndex, COLUMN_CONFIGURATION);
fireTableCellUpdated(rowIndex, COLUMN_CONFIGURATION_NAME);
break;
case CHANNEL_FREQUENCY:
case CHANNEL_FREQUENCY_LABEL:
fireTableCellUpdated(rowIndex, COLUMN_FREQUENCY);
break;
case CHANNEL_FREQUENCY_LABEL:
fireTableCellUpdated(rowIndex, COLUMN_CHANNEL);
break;
case CHANNEL_STATE:
fireTableCellUpdated(rowIndex, COLUMN_STATE);
break;
@@ -146,17 +250,20 @@ public class ChannelMetadataModel extends AbstractTableModel implements Listener
case MESSAGE_TYPE:
fireTableCellUpdated(rowIndex, COLUMN_MESSAGE);
break;
case NETWORK_ID_1:
case NETWORK_ID_2:
fireTableCellUpdated(rowIndex, COLUMN_NETWORK);
break;
case PRIMARY_ADDRESS_FROM:
fireTableCellUpdated(rowIndex, COLUMN_PRIMARY_FROM);
break;
case PRIMARY_ADDRESS_TO:
fireTableCellUpdated(rowIndex, COLUMN_PRIMARY);
fireTableCellUpdated(rowIndex, COLUMN_PRIMARY_TO);
break;
case PRIMARY_DECODER_TYPE:
fireTableCellUpdated(rowIndex, COLUMN_DECODER);
break;
case SECONDARY_ADDRESS_FROM:
fireTableCellUpdated(rowIndex, COLUMN_SECONDARY_FROM);
break;
case SECONDARY_ADDRESS_TO:
fireTableCellUpdated(rowIndex, COLUMN_SECONDARY);
fireTableCellUpdated(rowIndex, COLUMN_SECONDARY_TO);
break;
}
}

View File

@@ -19,26 +19,39 @@
package channel.metadata;
import alias.Alias;
import channel.state.State;
import com.sun.xml.internal.ws.api.streaming.XMLStreamReaderFactory;
import controller.channel.Channel;
import controller.channel.ChannelProcessingManager;
import icon.IconManager;
import icon.IconTableModel;
import module.ProcessingChain;
import net.miginfocom.swing.MigLayout;
import properties.SystemProperties;
import sample.Broadcaster;
import sample.Listener;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.DefaultTableCellRenderer;
import java.awt.*;
import java.text.DecimalFormat;
public class ChannelMetadataPanel extends JPanel
public class ChannelMetadataPanel extends JPanel implements ListSelectionListener
{
private ChannelMetadataModel mChannelMetadataModel;
private static final String PROPERTY_PREFIX_BACKGROUND = "channel.metadata.panel.state.color.";
private static final String PROPERTY_PREFIX_FOREGROUND = "channel.metadata.panel.text.color.";
private ChannelProcessingManager mChannelProcessingManager;
private IconManager mIconManager;
private JTable mTable;
private Broadcaster<ProcessingChain> mSelectedProcessingChainBroadcaster = new Broadcaster<>();
public ChannelMetadataPanel(ChannelMetadataModel channelMetadataModel, IconManager iconManager)
/**
* Table view for currently decoding channel metadata
*/
public ChannelMetadataPanel(ChannelProcessingManager channelProcessingManager, IconManager iconManager)
{
mChannelMetadataModel = channelMetadataModel;
mIconManager = iconManager;
mChannelProcessingManager = channelProcessingManager;
init();
}
@@ -50,199 +63,165 @@ public class ChannelMetadataPanel extends JPanel
{
setLayout( new MigLayout( "insets 0 0 0 0", "[grow,fill]", "[grow,fill]") );
mTable = new JTable(mChannelMetadataModel);
mTable.setRowHeight(35);
mTable = new JTable(mChannelProcessingManager.getChannelMetadataModel());
mTable.getColumnModel().getColumn(ChannelMetadataModel.COLUMN_STATE).setCellRenderer(new StateCellRenderer());
DefaultTableCellRenderer renderer = (DefaultTableCellRenderer)mTable.getDefaultRenderer(String.class);
renderer.setHorizontalAlignment(SwingConstants.CENTER);
mTable.getColumnModel().getColumn(ChannelMetadataModel.COLUMN_FREQUENCY)
.setCellRenderer(new FrequencyCellRenderer());
mTable.getSelectionModel().addListSelectionListener(this);
mTable.getColumnModel().getColumn(ChannelMetadataModel.COLUMN_PRIMARY)
.setCellRenderer(new AliasedValueCellRenderer(Attribute.PRIMARY_ADDRESS_TO, Attribute.PRIMARY_ADDRESS_FROM));
mTable.getColumnModel().getColumn(ChannelMetadataModel.COLUMN_SECONDARY)
.setCellRenderer(new AliasedValueCellRenderer(Attribute.SECONDARY_ADDRESS_TO, Attribute.SECONDARY_ADDRESS_FROM));
mTable.getColumnModel().getColumn(ChannelMetadataModel.COLUMN_MESSAGE)
.setCellRenderer(new AliasedValueCellRenderer(Attribute.MESSAGE, Attribute.MESSAGE_TYPE));
mTable.getColumnModel().getColumn(ChannelMetadataModel.COLUMN_NETWORK)
.setCellRenderer(new AliasedValueCellRenderer(Attribute.NETWORK_ID_1, Attribute.NETWORK_ID_2));
mTable.getColumnModel().getColumn(ChannelMetadataModel.COLUMN_CONFIGURATION)
.setCellRenderer(new AliasedValueCellRenderer(Attribute.CHANNEL_CONFIGURATION_LABEL_1,
Attribute.CHANNEL_CONFIGURATION_LABEL_2));
mTable.getColumnModel().getColumn(ChannelMetadataModel.COLUMN_STATE)
.setCellRenderer(new ColoredStateCellRenderer());
mTable.getColumnModel().getColumn(ChannelMetadataModel.COLUMN_PRIMARY_TO)
.setCellRenderer(new AliasedValueCellRenderer(Attribute.PRIMARY_ADDRESS_TO));
mTable.getColumnModel().getColumn(ChannelMetadataModel.COLUMN_PRIMARY_FROM)
.setCellRenderer(new AliasedValueCellRenderer(Attribute.PRIMARY_ADDRESS_FROM));
mTable.getColumnModel().getColumn(ChannelMetadataModel.COLUMN_SECONDARY_TO)
.setCellRenderer(new AliasedValueCellRenderer(Attribute.SECONDARY_ADDRESS_TO));
mTable.getColumnModel().getColumn(ChannelMetadataModel.COLUMN_SECONDARY_FROM)
.setCellRenderer(new AliasedValueCellRenderer(Attribute.SECONDARY_ADDRESS_FROM));
JScrollPane scrollPane = new JScrollPane(mTable, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
add(scrollPane);
// new TableColumnWidthMonitor(mTable, PROPERTY_PREFIX, new int[] {15,15,15,15,25,25,25,25,15,40});
}
/**
* Adds a selection listener to the contained metadata JTable
*/
public void addListSelectionListener(ListSelectionListener listener)
@Override
public void valueChanged(ListSelectionEvent e)
{
mTable.getSelectionModel().addListSelectionListener(listener);
}
/**
* Removes the selection listener from the contained metadata JTable
*/
public void removeListSelectionListener(ListSelectionListener listener)
{
mTable.getSelectionModel().removeListSelectionListener(listener);
}
public class AliasedValueCellRenderer extends JPanel implements TableCellRenderer
{
private JLabel mLabel1;
private JLabel mAlias1;
private JLabel mLabel2;
private JLabel mAlias2;
private Attribute mAttribute1;
private Attribute mAttribute2;
public AliasedValueCellRenderer(Attribute attribute1, Attribute attribute2)
if(!mTable.getSelectionModel().getValueIsAdjusting())
{
mAttribute1 = attribute1;
mAttribute2 = attribute2;
ProcessingChain processingChain = null;
setLayout( new MigLayout( "insets 0 0 0 0", "[12][grow,fill]", "[grow,fill]0[grow,fill]") );
int selectedViewRow = mTable.getSelectedRow();
mAlias1 = new JLabel();
add(mAlias1);
mLabel1 = new JLabel("---");
mLabel1.setFont(mTable.getFont());
add(mLabel1,"wrap");
mAlias2 = new JLabel();
add(mAlias2);
mLabel2 = new JLabel("---");
mLabel2.setFont(mTable.getFont());
add(mLabel2,"wrap");
if(selectedViewRow >= 0)
{
int selectedModelRow = mTable.convertRowIndexToModel(selectedViewRow);
Metadata selectedMetadata = mChannelProcessingManager.getChannelMetadataModel()
.getMetadata(selectedModelRow);
if(selectedMetadata != null)
{
Channel selectedChannel = mChannelProcessingManager.getChannelMetadataModel()
.getChannelFromMetadata(selectedMetadata);
processingChain = mChannelProcessingManager.getProcessingChain(selectedChannel);
}
}
mSelectedProcessingChainBroadcaster.broadcast(processingChain);
}
}
/**
* Adds the listener to receive the processing chain associated with the metadata selected in the
* metadata table.
*/
public void addProcessingChainSelectionListener(Listener<ProcessingChain> listener)
{
mSelectedProcessingChainBroadcaster.addListener(listener);
}
public class AliasedValueCellRenderer extends DefaultTableCellRenderer
{
private Attribute mAttribute;
public AliasedValueCellRenderer(Attribute attribute)
{
assert(attribute != null);
mAttribute = attribute;
setHorizontalAlignment(JLabel.CENTER);
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column)
{
MutableMetadata metadata = (MutableMetadata)value;
JLabel label = (JLabel)super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if(mAttribute1 != null)
{
String value1 = metadata.getValue(mAttribute1);
mLabel1.setText(value1);
Metadata metadata = (Metadata)value;
String value1 = metadata.getValue(mAttribute);
Alias alias = metadata.getAlias(mAttribute);
Alias alias1 = metadata.getAlias(mAttribute1);
label.setText(alias != null ? alias.getName() : value1);
label.setIcon(alias != null ? mIconManager.getIcon(alias.getIconName(), IconManager.DEFAULT_ICON_SIZE) : null);
label.setForeground(alias != null ? alias.getDisplayColor() : table.getForeground());
if(alias1 != null)
{
mAlias1.setIcon(mIconManager.getIcon(alias1.getIconName(), IconManager.DEFAULT_ICON_SIZE));
mLabel1.setForeground(alias1.getDisplayColor());
}
else
{
mAlias1.setIcon(null);
mLabel1.setForeground(mTable.getForeground());
}
}
if(mAttribute2 != null)
{
String value2 = metadata.getValue(mAttribute2);
mLabel2.setText(value2);
Alias alias2 = metadata.getAlias(mAttribute2);
if(alias2 != null)
{
mAlias2.setIcon(mIconManager.getIcon(alias2.getIconName(), IconManager.DEFAULT_ICON_SIZE));
mLabel2.setForeground(alias2.getDisplayColor());
}
else
{
mAlias2.setIcon(null);
mLabel2.setForeground(mTable.getForeground());
}
}
setBackground(isSelected ? table.getSelectionBackground() : table.getBackground());
return this;
return label;
}
}
public class FrequencyCellRenderer extends JPanel implements TableCellRenderer
public class ColoredStateCellRenderer extends DefaultTableCellRenderer
{
private final DecimalFormat FREQUENCY_FORMATTER = new DecimalFormat( "#.000000" );
private JLabel mLabel1;
private JLabel mLabel2;
public FrequencyCellRenderer()
public ColoredStateCellRenderer()
{
setLayout( new MigLayout( "insets 0 0 0 0", "[grow,fill,align center]", "[grow,fill]0[grow,fill]") );
mLabel1 = new JLabel();
mLabel1.setFont(mTable.getFont());
add(mLabel1,"wrap");
mLabel2 = new JLabel();
mLabel2.setFont(mTable.getFont());
add(mLabel2);
setHorizontalAlignment(SwingConstants.CENTER);
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column)
{
MutableMetadata metadata = (MutableMetadata)value;
JLabel label = (JLabel)super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if(metadata.hasChannelFrequency())
Color background = table.getBackground();
Color foreground = table.getForeground();
if(value instanceof State)
{
mLabel1.setText(FREQUENCY_FORMATTER.format((double)metadata.getChannelFrequency() / 1E6d));
State state = (State)value;
label.setText(state.getDisplayValue());
switch(state)
{
case CALL:
background = SystemProperties.getInstance().get(PROPERTY_PREFIX_BACKGROUND + "call", Color.BLUE);
foreground = SystemProperties.getInstance().get(PROPERTY_PREFIX_FOREGROUND + "call", Color.YELLOW);
break;
case CONTROL:
background = SystemProperties.getInstance().get(PROPERTY_PREFIX_BACKGROUND + "control", Color.ORANGE);
foreground = SystemProperties.getInstance().get(PROPERTY_PREFIX_FOREGROUND + "control", Color.BLUE);
break;
case DATA:
background = SystemProperties.getInstance().get(PROPERTY_PREFIX_BACKGROUND + "data", Color.GREEN);
foreground = SystemProperties.getInstance().get(PROPERTY_PREFIX_FOREGROUND + "data", Color.BLUE);
break;
case ENCRYPTED:
background = SystemProperties.getInstance().get(PROPERTY_PREFIX_BACKGROUND + "encrypted", Color.MAGENTA);
foreground = SystemProperties.getInstance().get(PROPERTY_PREFIX_FOREGROUND + "encrypted", Color.WHITE);
break;
case FADE:
background = SystemProperties.getInstance().get(PROPERTY_PREFIX_BACKGROUND + "fade", Color.LIGHT_GRAY.BLUE);
foreground = SystemProperties.getInstance().get(PROPERTY_PREFIX_FOREGROUND + "fade", Color.YELLOW);
break;
case IDLE:
background = SystemProperties.getInstance().get(PROPERTY_PREFIX_BACKGROUND + "idle", Color.WHITE);
foreground = SystemProperties.getInstance().get(PROPERTY_PREFIX_FOREGROUND + "idle", Color.BLUE);
break;
case RESET:
background = SystemProperties.getInstance().get(PROPERTY_PREFIX_BACKGROUND + "reset", Color.PINK);
foreground = SystemProperties.getInstance().get(PROPERTY_PREFIX_FOREGROUND + "reset", Color.YELLOW);
break;
case TEARDOWN:
background = SystemProperties.getInstance().get(PROPERTY_PREFIX_BACKGROUND + "teardown", Color.DARK_GRAY);
foreground = SystemProperties.getInstance().get(PROPERTY_PREFIX_FOREGROUND + "teardown", Color.WHITE);
break;
}
}
else
{
mLabel1.setText(null);
setText("");
}
mLabel2.setText(metadata.getChannelFrequencyLabel());
setBackground(background);
setForeground(foreground);
setBackground(isSelected ? table.getSelectionBackground() : table.getBackground());
return this;
return label;
}
}
public class StateCellRenderer extends JPanel implements TableCellRenderer
{
private JLabel mLabel1;
public StateCellRenderer()
{
setLayout( new MigLayout( "insets 0 0 0 0", "[grow,fill,align center]", "[grow,fill,align center]") );
mLabel1 = new JLabel();
mLabel1.setFont(mTable.getFont());
add(mLabel1);
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column)
{
MutableMetadata metadata = (MutableMetadata)value;
mLabel1.setText(metadata.getState().getDisplayValue());
setBackground(isSelected ? table.getSelectionBackground() : table.getBackground());
return this;
}
}
}

View File

@@ -22,7 +22,6 @@ import com.jidesoft.swing.JideSplitPane;
import com.jidesoft.swing.JideTabbedPane;
import controller.channel.ChannelProcessingManager;
import icon.IconManager;
import icon.IconTableModel;
import module.decode.event.CallEventPanel;
import module.decode.event.MessageActivityPanel;
import net.miginfocom.swing.MigLayout;
@@ -30,6 +29,7 @@ import settings.SettingsManager;
import spectrum.ChannelSpectrumPanel;
import javax.swing.*;
import java.awt.*;
public class ChannelMetadataViewer extends JPanel
{
@@ -45,11 +45,10 @@ public class ChannelMetadataViewer extends JPanel
public ChannelMetadataViewer(ChannelProcessingManager channelProcessingManager, IconManager iconManager,
SettingsManager settingsManager)
{
mCallEventPanel = new CallEventPanel(iconManager, channelProcessingManager);
mCallEventPanel = new CallEventPanel(iconManager);
mMessageActivityPanel = new MessageActivityPanel(channelProcessingManager);
mChannelSpectrumPanel = new ChannelSpectrumPanel(settingsManager, channelProcessingManager);
mChannelMetadataPanel = new ChannelMetadataPanel(channelProcessingManager.getChannelMetadataModel(),
iconManager);
mChannelMetadataPanel = new ChannelMetadataPanel(channelProcessingManager, iconManager);
init();
}
@@ -59,49 +58,20 @@ public class ChannelMetadataViewer extends JPanel
setLayout( new MigLayout( "insets 0 0 0 0", "[grow,fill]", "[grow,fill]") );
JideTabbedPane tabbedPane = new JideTabbedPane();
tabbedPane.addTab("Details", new JPanel());
// tabbedPane.addTab("Details", new JPanel());
tabbedPane.addTab("Events", mCallEventPanel);
tabbedPane.addTab("Messages", mMessageActivityPanel);
tabbedPane.addTab("Spectrum", mChannelSpectrumPanel);
// tabbedPane.addTab("Spectrum", mChannelSpectrumPanel);
tabbedPane.setFont(this.getFont());
tabbedPane.setForeground(Color.BLACK);
JideSplitPane splitPane = new JideSplitPane(JideSplitPane.VERTICAL_SPLIT);
splitPane.setShowGripper(true);
splitPane.add(mChannelMetadataPanel);
splitPane.add(tabbedPane);
add(splitPane);
//TODO: move this change listener to the metadata table view
// /**
// * Change listener to enable/disable the channel spectrum display
// * only when the tab is visible, and a channel has been selected
// */
// mTabbedPane.addChangeListener(new ChangeListener()
// {
// @Override
// public void stateChanged(ChangeEvent event)
// {
// int index = mTabbedPane.getSelectedIndex();
//
// Component component = mTabbedPane.getComponentAt(index);
//
// if(component instanceof ChannelSpectrumPanel)
// {
// mChannelSpectrumPanel.setEnabled(true);
// }
// else
// {
// mChannelSpectrumPanel.setEnabled(false);
// }
// }
// });
//TODO: call, message and spectrum should listen to the metadata table now
//
//
// /* Register each of the components to receive channel events when the
// * channels are selected or change */
// mChannelModel.addListener(mCallEventPanel);
// mChannelModel.addListener(mChannelSpectrumPanel);
// mChannelModel.addListener(mMessageActivityPanel);
mChannelMetadataPanel.addProcessingChainSelectionListener(mCallEventPanel);
mChannelMetadataPanel.addProcessingChainSelectionListener(mMessageActivityPanel);
}
}

View File

@@ -18,30 +18,10 @@
******************************************************************************/
package channel.traffic;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledExecutorService;
import channel.state.DecoderStateEvent;
import channel.state.IDecoderStateEventListener;
import module.Module;
import module.decode.config.DecodeConfiguration;
import module.decode.event.CallEvent;
import module.decode.event.CallEvent.CallEventType;
import module.decode.event.ICallEventProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import record.config.RecordConfiguration;
import sample.Listener;
import source.config.SourceConfigTuner;
import source.tuner.TunerChannel;
import source.tuner.TunerChannel.Type;
import alias.Alias;
import alias.id.priority.Priority;
import channel.state.DecoderStateEvent;
import channel.state.IDecoderStateEventListener;
import controller.channel.Channel;
import controller.channel.Channel.ChannelType;
import controller.channel.ChannelEvent;
@@ -49,203 +29,211 @@ import controller.channel.ChannelEvent.Event;
import controller.channel.ChannelModel;
import controller.channel.ChannelProcessingManager;
import controller.channel.TrafficChannelEvent;
import module.Module;
import module.decode.config.DecodeConfiguration;
import module.decode.event.CallEvent;
import module.decode.event.CallEvent.CallEventType;
import module.decode.event.ICallEventProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import record.config.RecordConfiguration;
import sample.Listener;
import source.config.SourceConfigTuner;
import source.tuner.TunerChannel;
import source.tuner.TunerChannel.Type;
public class TrafficChannelManager extends Module
implements ICallEventProvider, IDecoderStateEventListener
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledExecutorService;
public class TrafficChannelManager extends Module implements ICallEventProvider, IDecoderStateEventListener
{
private final static Logger mLog = LoggerFactory.getLogger( TrafficChannelManager.class );
private final static Logger mLog = LoggerFactory.getLogger(TrafficChannelManager.class);
public static final String CHANNEL_START_REJECTED = "CHANNEL START REJECTED";
public static final String NO_TUNER_AVAILABLE = "NO TUNER AVAILABLE";
public static final String UNKNOWN_FREQUENCY = "UNKNOWN FREQUENCY";
private int mTrafficChannelPoolMaximumSize =
DecodeConfiguration.TRAFFIC_CHANNEL_LIMIT_DEFAULT;
private List<Channel> mTrafficChannelPool = new ArrayList<Channel>();
private Map<String,Channel> mTrafficChannelsInUse = new ConcurrentHashMap<String,Channel>();
private int mTrafficChannelPoolMaximumSize = DecodeConfiguration.TRAFFIC_CHANNEL_LIMIT_DEFAULT;
private List<Channel> mTrafficChannelPool = new ArrayList<Channel>();
private Map<String,Channel> mTrafficChannelsInUse = new ConcurrentHashMap<String,Channel>();
private DecoderStateEventListener mEventListener = new DecoderStateEventListener();
private Listener<CallEvent> mCallEventListener;
private DecoderStateEventListener mEventListener = new DecoderStateEventListener();
private Listener<CallEvent> mCallEventListener;
private ChannelModel mChannelModel;
private ChannelProcessingManager mChannelProcessingManager;
private DecodeConfiguration mDecodeConfiguration;
private RecordConfiguration mRecordConfiguration;
private String mSystem;
private String mSite;
private String mAliasListName;
private CallEvent mPreviousDoNotMonitorCallEvent;
private ChannelModel mChannelModel;
private ChannelProcessingManager mChannelProcessingManager;
private DecodeConfiguration mDecodeConfiguration;
private RecordConfiguration mRecordConfiguration;
private String mSystem;
private String mSite;
private String mAliasListName;
private CallEvent mPreviousDoNotMonitorCallEvent;
/**
* Monitors call events and allocates traffic decoder channels in response
* to traffic channel allocation call events. Manages a pool of reusable
* traffic channel allocations.
*
/**
* Monitors call events and allocates traffic decoder channels in response
* to traffic channel allocation call events. Manages a pool of reusable
* traffic channel allocations.
*
* @param channelModel containing channels currently in use
*
* @param channelProcessingManager
*
* @param decodeConfiguration - decoder configuration to use for each
* traffic channel allocation.
*
* @param recordConfiguration - recording options for each traffic channel
*
* @param decodeConfiguration - decoder configuration to use for each
* traffic channel allocation.
* @param recordConfiguration - recording options for each traffic channel
* @param system label to use to describe the system
*
* @param site label to use to describe the site
*
* @param aliasListName designated for the channel
*
* @param trafficChannelTimeout - millisecond call timer limit used when an
* end of call signalling event is not decoded.
*
* @param trafficChannelPoolSize - maximum number of allocated traffic channels
* in the pool
*/
public TrafficChannelManager( ChannelModel channelModel,
ChannelProcessingManager channelProcessingManager,
DecodeConfiguration decodeConfiguration,
RecordConfiguration recordConfiguration,
String system,
String site,
String aliasListName,
long trafficChannelTimeout,
int trafficChannelPoolSize )
{
mChannelModel = channelModel;
mChannelProcessingManager = channelProcessingManager;
mDecodeConfiguration = decodeConfiguration;
mRecordConfiguration = recordConfiguration;
mSystem = system;
mSite = site;
mAliasListName = aliasListName;
mTrafficChannelPoolMaximumSize = trafficChannelPoolSize;
}
@Override
public void dispose()
{
for( Channel trafficChannel: mTrafficChannelPool )
{
mChannelModel.broadcast( new ChannelEvent( trafficChannel, Event.REQUEST_DISABLE ) );
}
* @param trafficChannelTimeout - millisecond call timer limit used when an
* end of call signalling event is not decoded.
* @param trafficChannelPoolSize - maximum number of allocated traffic channels
* in the pool
*/
public TrafficChannelManager(ChannelModel channelModel,
ChannelProcessingManager channelProcessingManager,
DecodeConfiguration decodeConfiguration,
RecordConfiguration recordConfiguration,
String system,
String site,
String aliasListName,
long trafficChannelTimeout,
int trafficChannelPoolSize)
{
mChannelModel = channelModel;
mChannelProcessingManager = channelProcessingManager;
mDecodeConfiguration = decodeConfiguration;
mRecordConfiguration = recordConfiguration;
mSystem = system;
mSite = site;
mAliasListName = aliasListName;
mTrafficChannelPoolMaximumSize = trafficChannelPoolSize;
}
mTrafficChannelPool.clear();
mTrafficChannelsInUse.clear();
mCallEventListener = null;
mDecodeConfiguration = null;
mPreviousDoNotMonitorCallEvent = null;
}
@Override
public void dispose()
{
for(Channel trafficChannel : mTrafficChannelPool)
{
mChannelModel.broadcast(new ChannelEvent(trafficChannel, Event.REQUEST_DISABLE));
}
/**
* Provides a channel by either reusing an existing channel or constructing
* a new one, limited by the total number of constructed channels allowed.
*
* Note: you must enforce thread safety on the mTrafficChannelsInUse
* external to this method.
*
* @param channelNumber
* @param tunerChannel
* @return
*/
private Channel getChannel( String channelNumber, TunerChannel tunerChannel )
{
Channel channel = null;
if( !mTrafficChannelsInUse.containsKey( channelNumber ) )
{
for( Channel configuredChannel: mTrafficChannelPool )
{
if( !configuredChannel.getEnabled() )
{
channel = configuredChannel;
break;
}
}
if( channel == null && mTrafficChannelPool.size() < mTrafficChannelPoolMaximumSize )
{
channel = new Channel( "Traffic", ChannelType.TRAFFIC );
channel.setDecodeConfiguration( mDecodeConfiguration );
channel.setRecordConfiguration( mRecordConfiguration );
channel.setAliasListName( mAliasListName );
mChannelModel.addChannel( channel );
mTrafficChannelPool.add( channel );
}
mTrafficChannelPool.clear();
mTrafficChannelsInUse.clear();
mCallEventListener = null;
mDecodeConfiguration = null;
mPreviousDoNotMonitorCallEvent = null;
}
/**
* Provides a channel by either reusing an existing channel or constructing
* a new one, limited by the total number of constructed channels allowed.
*
* Note: you must enforce thread safety on the mTrafficChannelsInUse
* external to this method.
*
* @param channelNumber
* @param tunerChannel
* @return
*/
private Channel getChannel(String channelNumber, TunerChannel tunerChannel)
{
Channel channel = null;
if(!mTrafficChannelsInUse.containsKey(channelNumber))
{
for(Channel configuredChannel : mTrafficChannelPool)
{
if(!configuredChannel.getEnabled())
{
channel = configuredChannel;
break;
}
}
if(channel == null && mTrafficChannelPool.size() < mTrafficChannelPoolMaximumSize)
{
channel = new Channel("Traffic", ChannelType.TRAFFIC);
channel.setDecodeConfiguration(mDecodeConfiguration);
channel.setRecordConfiguration(mRecordConfiguration);
channel.setAliasListName(mAliasListName);
mChannelModel.addChannel(channel);
mTrafficChannelPool.add(channel);
}
/* If we have a configured channel, update metadata */
if( channel != null )
{
channel.setSourceConfiguration( new SourceConfigTuner( tunerChannel ) );
channel.setSystem( mSystem );
channel.setSite( mSite );
channel.setName( channelNumber );
if(channel != null)
{
channel.setSourceConfiguration(new SourceConfigTuner(tunerChannel));
channel.setSystem(mSystem);
channel.setSite(mSite);
channel.setName(channelNumber);
mChannelModel.broadcast( new ChannelEvent( channel, Event.NOTIFICATION_CONFIGURATION_CHANGE ) );
}
}
mChannelModel.broadcast(new ChannelEvent(channel, Event.NOTIFICATION_CONFIGURATION_CHANGE));
}
}
return channel;
}
/**
* Processes the event and creates a traffic channel is resources are
* available
*/
private void process( TrafficChannelAllocationEvent event )
{
CallEvent callEvent = event.getCallEvent();
return channel;
}
/**
* Processes the event and creates a traffic channel is resources are
* available
*/
private void process(TrafficChannelAllocationEvent event)
{
CallEvent callEvent = event.getCallEvent();
/* Check for duplicate events and suppress */
synchronized( mTrafficChannelsInUse )
{
if( mTrafficChannelsInUse.containsKey( callEvent.getChannel() ) )
{
return;
}
synchronized(mTrafficChannelsInUse)
{
if(mTrafficChannelsInUse.containsKey(callEvent.getChannel()))
{
return;
}
long frequency = callEvent.getFrequency();
long frequency = callEvent.getFrequency();
/* Check the from/to aliases for do not monitor priority */
if( isDoNotMonitor( callEvent ) )
{
callEvent.setCallEventType( CallEventType.CALL_DO_NOT_MONITOR );
if(isDoNotMonitor(callEvent))
{
callEvent.setCallEventType(CallEventType.CALL_DO_NOT_MONITOR);
if( isSameCallEvent( mPreviousDoNotMonitorCallEvent, callEvent ) )
{
return;
}
else
{
mPreviousDoNotMonitorCallEvent = callEvent;
}
}
else if( frequency > 0 )
{
Channel channel = getChannel( callEvent.getChannel(), new TunerChannel( Type.TRAFFIC,
frequency, mDecodeConfiguration.getDecoderType().getChannelBandwidth() ) );
if(isSameCallEvent(mPreviousDoNotMonitorCallEvent, callEvent))
{
return;
}
else
{
mPreviousDoNotMonitorCallEvent = callEvent;
}
}
else if(frequency > 0)
{
Channel channel = getChannel(callEvent.getChannel(), new TunerChannel(Type.TRAFFIC,
frequency, mDecodeConfiguration.getDecoderType().getChannelBandwidth()));
if( channel != null )
{
TrafficChannelEvent trafficChannelEvent =
new TrafficChannelEvent( this, channel, Event.REQUEST_ENABLE, callEvent );
//Request to enable the channel
mChannelModel.broadcast( trafficChannelEvent );
if(channel != null)
{
TrafficChannelEvent trafficChannelEvent =
new TrafficChannelEvent(this, channel, Event.REQUEST_ENABLE, callEvent);
if( channel.getEnabled() )
{
mTrafficChannelsInUse.put( callEvent.getChannel(), channel );
}
else
{
callEvent.setCallEventType( CallEventType.CALL_DETECT );
//Request to enable the channel
mChannelModel.broadcast(trafficChannelEvent);
if(channel.getEnabled())
{
mTrafficChannelsInUse.put(callEvent.getChannel(), channel);
}
else
{
callEvent.setCallEventType(CallEventType.CALL_DETECT);
String details = callEvent.getDetails();
@@ -255,15 +243,14 @@ public class TrafficChannelManager extends Module
}
else if(!details.contains(CHANNEL_START_REJECTED))
{
callEvent.setDetails(new StringBuilder(CHANNEL_START_REJECTED)
.append(" : ")
.append(callEvent.getDetails()).toString());
callEvent.setDetails(new StringBuilder(CHANNEL_START_REJECTED).append(" : ")
.append(callEvent.getDetails()).toString());
}
}
}
else
{
callEvent.setCallEventType( CallEventType.CALL_DETECT );
}
}
else
{
callEvent.setCallEventType(CallEventType.CALL_DETECT);
String details = callEvent.getDetails();
@@ -273,15 +260,14 @@ public class TrafficChannelManager extends Module
}
else if(!details.contains(NO_TUNER_AVAILABLE))
{
callEvent.setDetails(new StringBuilder(NO_TUNER_AVAILABLE)
.append(" : ")
.append(callEvent.getDetails()).toString());
callEvent.setDetails(new StringBuilder(NO_TUNER_AVAILABLE).append(" : ")
.append(callEvent.getDetails()).toString());
}
}
}
else
{
callEvent.setCallEventType( CallEventType.CALL_DETECT );
}
}
else
{
callEvent.setCallEventType(CallEventType.CALL_DETECT);
String details = callEvent.getDetails();
@@ -291,187 +277,171 @@ public class TrafficChannelManager extends Module
}
else if(!details.contains(UNKNOWN_FREQUENCY))
{
callEvent.setDetails(new StringBuilder(UNKNOWN_FREQUENCY)
.append(" : ")
.append(callEvent.getDetails()).toString());
callEvent.setDetails(new StringBuilder(UNKNOWN_FREQUENCY).append(" : ")
.append(callEvent.getDetails()).toString());
}
}
}
final Listener<CallEvent> listener = mCallEventListener;
if( listener != null )
{
listener.receive( callEvent );
}
}
}
final Listener<CallEvent> listener = mCallEventListener;
/**
* Compares the call type, channel and to fields for equivalence and the
* from field for either both null, or equivalence.
*
* @param e1
* @param e2
* @return
*/
public static boolean isSameCallEvent( CallEvent e1, CallEvent e2 )
{
if( e1 == null || e2 == null )
{
return false;
}
if(listener != null)
{
listener.receive(callEvent);
}
}
}
if( e1.getCallEventType() != e2.getCallEventType() )
{
return false;
}
/**
* Compares the call type, channel and to fields for equivalence and the
* from field for either both null, or equivalence.
*
* @param e1
* @param e2
* @return
*/
public static boolean isSameCallEvent(CallEvent e1, CallEvent e2)
{
if(e1 == null || e2 == null)
{
return false;
}
if( e1.getChannel() == null ||
e2.getChannel() == null ||
!e1.getChannel().contentEquals( e2.getChannel() ) )
{
return false;
}
if( e1.getToID() == null ||
e2.getToID() == null ||
!e1.getToID().contentEquals( e2.getToID() ) )
{
return false;
}
if(e1.getCallEventType() != e2.getCallEventType())
{
return false;
}
if( e1.getFromID() == null || e2.getFromID() == null )
{
if( e1.getFromID() == null && e2.getFromID() == null )
{
return true;
}
else
{
return false;
}
}
else if( e1.getFromID().contentEquals( e2.getFromID() ) )
{
return true;
}
return false;
}
/**
* Checks for aliases that contain a do not follow/process priority.
*
* @param event
* @return - true if there is an alias that has a do not process alias id
*/
private boolean isDoNotMonitor( CallEvent event )
{
Alias to = event.getToIDAlias();
if(e1.getChannel() == null || e2.getChannel() == null || !e1.getChannel().contentEquals(e2.getChannel()))
{
return false;
}
if( to != null &&
to.hasCallPriority() &&
to.getCallPriority() == Priority.DO_NOT_MONITOR )
{
return true;
}
Alias from = event.getFromIDAlias();
if(e1.getToID() == null || e2.getToID() == null || !e1.getToID().contentEquals(e2.getToID()))
{
return false;
}
if( from != null &&
from.hasCallPriority() &&
from.getCallPriority() == Priority.DO_NOT_MONITOR )
{
return true;
}
return false;
}
if(e1.getFromID() == null || e2.getFromID() == null)
{
return (e1.getFromID() == null && e2.getFromID() == null);
}
else if(e1.getFromID().contentEquals(e2.getFromID()))
{
return true;
}
@Override
public Listener<DecoderStateEvent> getDecoderStateListener()
{
return mEventListener;
}
return false;
}
@Override
public void addCallEventListener( Listener<CallEvent> listener )
{
mCallEventListener = listener;
}
/**
* Checks for aliases that contain a do not follow/process priority.
*
* @param event
* @return - true if there is an alias that has a do not process alias id
*/
private boolean isDoNotMonitor(CallEvent event)
{
Alias to = event.getToIDAlias();
@Override
public void removeCallEventListener( Listener<CallEvent> listener )
{
mCallEventListener = null;
}
if(to != null && to.hasCallPriority() && to.getCallPriority() == Priority.DO_NOT_MONITOR)
{
return true;
}
@Override
public void reset()
{
}
@Override
public void start( ScheduledExecutorService executor )
{
}
Alias from = event.getFromIDAlias();
@Override
public void stop()
{
if( !mTrafficChannelsInUse.isEmpty() )
{
List<String> channels = new ArrayList<>();
if(from != null && from.hasCallPriority() && from.getCallPriority() == Priority.DO_NOT_MONITOR)
{
return true;
}
return false;
}
@Override
public Listener<DecoderStateEvent> getDecoderStateListener()
{
return mEventListener;
}
@Override
public void addCallEventListener(Listener<CallEvent> listener)
{
mCallEventListener = listener;
}
@Override
public void removeCallEventListener(Listener<CallEvent> listener)
{
mCallEventListener = null;
}
@Override
public void reset()
{
}
@Override
public void start(ScheduledExecutorService executor)
{
}
@Override
public void stop()
{
if(!mTrafficChannelsInUse.isEmpty())
{
List<String> channels = new ArrayList<>();
/* Copy the keyset so we don't get concurrent modification of the map */
channels.addAll( mTrafficChannelsInUse.keySet() );
for( String channel: channels )
{
callEnd( channel );
}
}
}
channels.addAll(mTrafficChannelsInUse.keySet());
/**
* Callback used by the TrafficChannelStatusListener class to signal the
* end of a an allocated traffic channel call event
*
* @param channelNumber - channel number from the call event that signaled
* the start of a traffic channel allocation
*/
public void callEnd( String channelNumber )
{
synchronized( mTrafficChannelsInUse )
{
if( channelNumber != null && mTrafficChannelsInUse.containsKey( channelNumber ) )
{
Channel channel = mTrafficChannelsInUse.get( channelNumber );
for(String channel : channels)
{
callEnd(channel);
}
}
}
mChannelModel.broadcast( new ChannelEvent( channel, Event.REQUEST_DISABLE ) );
mTrafficChannelsInUse.remove( channelNumber );
}
}
}
/**
* Wrapper class for the decoder state event listener interface to catch
* traffic channel allocation requests
*/
public class DecoderStateEventListener implements Listener<DecoderStateEvent>
{
@Override
public void receive( DecoderStateEvent event )
{
switch( event.getEvent() )
{
case TRAFFIC_CHANNEL_ALLOCATION:
process( (TrafficChannelAllocationEvent)event );
break;
default:
break;
}
}
}
/**
* Callback used by the TrafficChannelStatusListener class to signal the
* end of a an allocated traffic channel call event
*
* @param channelNumber - channel number from the call event that signaled
* the start of a traffic channel allocation
*/
public void callEnd(String channelNumber)
{
synchronized(mTrafficChannelsInUse)
{
if(channelNumber != null && mTrafficChannelsInUse.containsKey(channelNumber))
{
Channel channel = mTrafficChannelsInUse.get(channelNumber);
mChannelModel.broadcast(new ChannelEvent(channel, Event.REQUEST_DISABLE));
mTrafficChannelsInUse.remove(channelNumber);
}
}
}
/**
* Wrapper class for the decoder state event listener interface to catch
* traffic channel allocation requests
*/
public class DecoderStateEventListener implements Listener<DecoderStateEvent>
{
@Override
public void receive(DecoderStateEvent event)
{
switch(event.getEvent())
{
case TRAFFIC_CHANNEL_ALLOCATION:
process((TrafficChannelAllocationEvent) event);
break;
default:
break;
}
}
}
}

View File

@@ -31,6 +31,7 @@ import message.Message;
import module.Module;
import module.ProcessingChain;
import module.decode.DecoderFactory;
import module.decode.DecoderType;
import module.decode.event.MessageActivityModel;
import module.log.EventLogManager;
import org.slf4j.Logger;
@@ -41,6 +42,8 @@ import sample.Listener;
import source.Source;
import source.SourceException;
import source.SourceManager;
import source.SourceType;
import source.config.SourceConfigTuner;
import java.util.HashMap;
import java.util.List;
@@ -184,8 +187,7 @@ public class ChannelProcessingManager implements ChannelEventListener
{
channel.setEnabled(false);
mChannelModel.broadcast(
new ChannelEvent(channel, Event.NOTIFICATION_ENABLE_REJECTED));
mChannelModel.broadcast(new ChannelEvent(channel, Event.NOTIFICATION_ENABLE_REJECTED));
return;
}
@@ -224,31 +226,20 @@ public class ChannelProcessingManager implements ChannelEventListener
}
//Inject channel metadata that will be inserted into audio packets for recorder manager and streaming
StringBuilder sb = new StringBuilder();
processingChain.getChannelState().getMutableMetadata().receive(
new AttributeChangeRequest<String>(Attribute.CHANNEL_CONFIGURATION_LABEL_1, channel.getName()));
if(channel.getSystem() != null)
if(channel.getSourceConfiguration().getSourceType() == SourceType.TUNER)
{
sb.append(channel.getSystem());
long frequency = ((SourceConfigTuner)channel.getSourceConfiguration()).getFrequency();
processingChain.getChannelState().getMutableMetadata().receive(
new AttributeChangeRequest<Long>(Attribute.CHANNEL_FREQUENCY, frequency));
}
if(channel.getSite() != null)
{
if(sb.length() > 0)
{
sb.append(" - ");
}
sb.append(channel.getSite());
}
if(sb.length() > 0)
{
processingChain.getChannelState().getMutableMetadata()
.receive(new AttributeChangeRequest<String>(Attribute.CHANNEL_CONFIGURATION_LABEL_1, sb.toString()));
}
processingChain.getChannelState().getMutableMetadata()
.receive(new AttributeChangeRequest<String>(Attribute.CHANNEL_CONFIGURATION_LABEL_2, channel.getName()));
processingChain.getChannelState().getMutableMetadata().receive(
new AttributeChangeRequest<DecoderType>(Attribute.PRIMARY_DECODER_TYPE,
channel.getDecodeConfiguration().getDecoderType()));
}
/* Setup event logging */

View File

@@ -19,10 +19,14 @@
package module.decode.event;
import alias.Alias;
import gui.SDRTrunk;
import icon.IconManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import java.awt.*;
/**
* Custom renderer for JTable cells that contain Alias objects. Renders the
@@ -32,6 +36,7 @@ import javax.swing.table.DefaultTableCellRenderer;
public class CallEventAliasCellRenderer extends DefaultTableCellRenderer
{
private static final long serialVersionUID = 1L;
private final static Logger mLog = LoggerFactory.getLogger(CallEventAliasCellRenderer.class);
private IconManager mIconManager;
@@ -41,35 +46,26 @@ public class CallEventAliasCellRenderer extends DefaultTableCellRenderer
mIconManager = iconManager;
}
public void setValue(Object obj)
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
if(obj != null && obj instanceof Alias)
JLabel label = (JLabel)super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if(value instanceof Alias)
{
Alias alias = (Alias) obj;
Alias alias = (Alias)value;
setText(alias.getName());
ImageIcon icon = getIcon(alias, IconManager.DEFAULT_ICON_SIZE);
if(icon != null)
{
setIcon(icon);
}
label.setText(alias.getName());
label.setForeground(alias.getDisplayColor());
label.setIcon(mIconManager.getIcon(alias.getIconName(), IconManager.DEFAULT_ICON_SIZE));
}
else
{
setText(" ");
setIcon(null);
}
}
private ImageIcon getIcon(Alias alias, int height)
{
if(mIconManager != null && alias != null)
{
return mIconManager.getIcon(alias.getIconName(), height);
label.setText("");
label.setForeground(table.getForeground());
label.setIcon(null);
}
return null;
return label;
}
}

View File

@@ -1,38 +1,38 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014,2015 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 module.decode.event;
import alias.Alias;
import module.decode.event.CallEvent.CallEventType;
import sample.Listener;
import javax.swing.table.AbstractTableModel;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import javax.swing.table.AbstractTableModel;
import module.decode.event.CallEvent.CallEventType;
import sample.Listener;
public class CallEventModel extends AbstractTableModel implements Listener<CallEvent>
{
private static final long serialVersionUID = 1L;
private static DecimalFormat mFrequencyFormatter = new DecimalFormat( "0.000000" );
private static DecimalFormat mFrequencyFormatter = new DecimalFormat("0.000000");
public static final int TIME = 0;
public static final int EVENT = 1;
public static final int FROM_ID = 2;
@@ -43,168 +43,179 @@ public class CallEventModel extends AbstractTableModel implements Listener<CallE
public static final int FREQUENCY = 7;
public static final int DETAILS = 8;
protected int mMaxMessages = 500;
protected int mMaxMessages = 500;
protected List<CallEvent> mEvents = new ArrayList<CallEvent>();
protected List<CallEvent> mEvents = new ArrayList<CallEvent>();
protected String[] mHeaders = new String[] { "Time",
"Event",
"From",
"Alias",
"To",
"Alias",
"Channel",
"Frequency",
"Details" };
protected String[] mHeaders = new String[]{"Time",
"Event",
"From",
"Alias",
"To",
"Alias",
"Channel",
"Frequency",
"Details"};
private SimpleDateFormat mSDFTime = new SimpleDateFormat( "HH:mm:ss" );
public CallEventModel()
{
}
public void dispose()
{
mEvents.clear();
}
public void reset()
{
mEvents.clear();
fireTableDataChanged();
}
public int getMaxMessageCount()
{
return mMaxMessages;
}
private SimpleDateFormat mSDFTime = new SimpleDateFormat("HH:mm:ss");
public void setMaxMessageCount( int count )
{
mMaxMessages = count;
}
public CallEventModel()
{
}
/**
* Adds, updates or deletes the event from the model. Producers can send
* the same call event multiple times to indicate that information in the
* event is updated. Producers can also mark the event as invalid and the
* event will be removed from the model.
*/
public void receive( final CallEvent event )
{
if( event.isValid() )
{
if( !mEvents.contains( event ) )
{
mEvents.add( 0, event );
fireTableRowsInserted( 0, 0 );
public void dispose()
{
mEvents.clear();
}
prune();
}
else
{
int row = mEvents.indexOf( event );
fireTableRowsUpdated( row, row );
}
}
else
{
if( mEvents.contains( event ) )
{
int row = mEvents.indexOf( event );
mEvents.remove( event );
fireTableRowsDeleted( row, row );
}
}
}
private void prune()
{
while( mEvents.size() > mMaxMessages )
{
int index = mEvents.size() - 1;
mEvents.remove( index );
fireTableRowsDeleted( index, index );
}
}
public void reset()
{
mEvents.clear();
@Override
fireTableDataChanged();
}
public int getMaxMessageCount()
{
return mMaxMessages;
}
public void setMaxMessageCount(int count)
{
mMaxMessages = count;
}
/**
* Adds, updates or deletes the event from the model. Producers can send
* the same call event multiple times to indicate that information in the
* event is updated. Producers can also mark the event as invalid and the
* event will be removed from the model.
*/
public void receive(final CallEvent event)
{
if(event.isValid())
{
if(!mEvents.contains(event))
{
mEvents.add(0, event);
fireTableRowsInserted(0, 0);
prune();
}
else
{
int row = mEvents.indexOf(event);
fireTableRowsUpdated(row, row);
}
}
else
{
if(mEvents.contains(event))
{
int row = mEvents.indexOf(event);
mEvents.remove(event);
fireTableRowsDeleted(row, row);
}
}
}
private void prune()
{
while(mEvents.size() > mMaxMessages)
{
int index = mEvents.size() - 1;
mEvents.remove(index);
fireTableRowsDeleted(index, index);
}
}
@Override
public int getRowCount()
{
return mEvents.size();
return mEvents.size();
}
@Override
@Override
public int getColumnCount()
{
return mHeaders.length;
return mHeaders.length;
}
public String getColumnName( int column )
{
return mHeaders[ column ];
}
@Override
public Object getValueAt( int rowIndex, int columnIndex )
public String getColumnName(int column)
{
synchronized( mEvents )
{
switch( columnIndex )
{
case TIME:
StringBuilder sb = new StringBuilder();
sb.append( mSDFTime.format(
mEvents.get( rowIndex ).getEventStartTime() ) );
if( mEvents.get( rowIndex ).getEventEndTime() != 0 )
{
sb.append( " - " );
sb.append( mSDFTime.format(
mEvents.get( rowIndex ).getEventEndTime() ) );
}
else if( mEvents.get( rowIndex )
.getCallEventType() == CallEventType.CALL )
{
sb.append( " - In Progress" );
}
return sb.toString();
case EVENT:
return mEvents.get( rowIndex ).getCallEventType();
case FROM_ID:
return mEvents.get( rowIndex ).getFromID();
case FROM_ALIAS:
return mEvents.get( rowIndex ).getFromIDAlias();
case TO_ID:
return mEvents.get( rowIndex ).getToID();
case TO_ALIAS:
return mEvents.get( rowIndex ).getToIDAlias();
case CHANNEL:
return mEvents.get( rowIndex ).getChannel();
case FREQUENCY:
long frequency = mEvents.get( rowIndex ).getFrequency();
if( frequency != 0 )
{
return mFrequencyFormatter.format( (double)frequency / 1E6d );
}
else
{
return null;
}
case DETAILS:
return mEvents.get( rowIndex ).getDetails();
}
}
return null;
return mHeaders[column];
}
@Override
public Object getValueAt(int rowIndex, int columnIndex)
{
synchronized(mEvents)
{
switch(columnIndex)
{
case TIME:
StringBuilder sb = new StringBuilder();
sb.append(mSDFTime.format(
mEvents.get(rowIndex).getEventStartTime()));
if(mEvents.get(rowIndex).getEventEndTime() != 0)
{
sb.append(" - ");
sb.append(mSDFTime.format(
mEvents.get(rowIndex).getEventEndTime()));
}
else if(mEvents.get(rowIndex)
.getCallEventType() == CallEventType.CALL)
{
sb.append(" - In Progress");
}
return sb.toString();
case EVENT:
return mEvents.get(rowIndex).getCallEventType();
case FROM_ID:
return mEvents.get(rowIndex).getFromID();
case FROM_ALIAS:
return mEvents.get(rowIndex).getFromIDAlias();
case TO_ID:
return mEvents.get(rowIndex).getToID();
case TO_ALIAS:
return mEvents.get(rowIndex).getToIDAlias();
case CHANNEL:
return mEvents.get(rowIndex).getChannel();
case FREQUENCY:
long frequency = mEvents.get(rowIndex).getFrequency();
if(frequency != 0)
{
return mFrequencyFormatter.format((double) frequency / 1E6d);
}
else
{
return null;
}
case DETAILS:
return mEvents.get(rowIndex).getDetails();
}
}
return null;
}
@Override
public Class<?> getColumnClass(int columnIndex)
{
if(columnIndex == FROM_ALIAS || columnIndex == TO_ALIAS)
{
return Alias.class;
}
return super.getColumnClass(columnIndex);
}
}

View File

@@ -18,112 +18,58 @@
******************************************************************************/
package module.decode.event;
import controller.channel.Channel;
import controller.channel.ChannelEvent;
import controller.channel.ChannelEvent.Event;
import controller.channel.ChannelEventListener;
import controller.channel.ChannelProcessingManager;
import icon.IconManager;
import module.ProcessingChain;
import net.miginfocom.swing.MigLayout;
import sample.Listener;
import javax.swing.*;
import java.awt.*;
public class CallEventPanel extends JPanel implements ChannelEventListener
public class CallEventPanel extends JPanel implements Listener<ProcessingChain>
{
private static final long serialVersionUID = 1L;
private JTable mTable;
private CallEventModel mEmptyCallEventModel = new CallEventModel();
private JScrollPane mEmptyScroller;
private Channel mDisplayedChannel;
private CallEventAliasCellRenderer mRenderer;
private ChannelProcessingManager mChannelProcessingManager;
public CallEventPanel(IconManager iconManager, ChannelProcessingManager channelProcessingManager)
/**
* View for call event table
* @param iconManager to display alias icons in table rows
*/
public CallEventPanel(IconManager iconManager)
{
mChannelProcessingManager = channelProcessingManager;
setLayout(new MigLayout("insets 0 0 0 0", "[grow,fill]", "[grow,fill]"));
setLayout(new MigLayout("insets 0 0 0 0 ", "[grow,fill]", "[grow,fill]"));
JTable table = new JTable(new CallEventModel());
table.setAutoCreateRowSorter(true);
table.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
mTable = new JTable(mEmptyCallEventModel);
mTable.setAutoCreateRowSorter(true);
mTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
mRenderer = new CallEventAliasCellRenderer(iconManager);
table.getColumnModel().getColumn(CallEventModel.FROM_ALIAS).setCellRenderer(mRenderer);
table.getColumnModel().getColumn(CallEventModel.TO_ALIAS).setCellRenderer(mRenderer);
mEmptyScroller = new JScrollPane(table);
mEmptyScroller = new JScrollPane(mTable);
add(mEmptyScroller);
}
@Override
public void channelChanged(final ChannelEvent event)
public void receive(ProcessingChain processingChain)
{
if(event.getEvent() == Event.NOTIFICATION_SELECTION_CHANGE && event.getChannel().isSelected())
EventQueue.invokeLater(new Runnable()
{
if(mDisplayedChannel == null || (mDisplayedChannel != null && mDisplayedChannel != event.getChannel()))
@Override
public void run()
{
ProcessingChain chain = mChannelProcessingManager.getProcessingChain(event.getChannel());
mTable.setModel(processingChain != null ? processingChain.getCallEventModel() : mEmptyCallEventModel);
if(chain != null)
if(processingChain != null)
{
final CallEventModel model = chain.getCallEventModel();
if(model != null)
{
EventQueue.invokeLater(new Runnable()
{
@Override
public void run()
{
removeAll();
JTable table = new JTable(model);
table.setAutoCreateRowSorter(true);
table.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
table.getColumnModel().getColumn(CallEventModel.FROM_ALIAS)
.setCellRenderer(mRenderer);
table.getColumnModel().getColumn(CallEventModel.TO_ALIAS)
.setCellRenderer(mRenderer);
add(new JScrollPane(table));
mDisplayedChannel = event.getChannel();
revalidate();
repaint();
}
});
}
mTable.getColumnModel().getColumn(CallEventModel.FROM_ALIAS).setCellRenderer(mRenderer);
mTable.getColumnModel().getColumn(CallEventModel.TO_ALIAS).setCellRenderer(mRenderer);
}
}
}
else if(event.getEvent() == Event.NOTIFICATION_PROCESSING_STOP || event.getEvent() == Event.REQUEST_DISABLE)
{
if(mDisplayedChannel != null && mDisplayedChannel == event.getChannel())
{
mDisplayedChannel = null;
EventQueue.invokeLater(new Runnable()
{
@Override
public void run()
{
removeAll();
add(mEmptyScroller);
revalidate();
repaint();
}
});
}
}
});
}
}

View File

@@ -32,6 +32,7 @@ import module.ProcessingChain;
import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sample.Listener;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
@@ -42,7 +43,7 @@ import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class MessageActivityPanel extends JPanel implements ChannelEventListener
public class MessageActivityPanel extends JPanel implements Listener<ProcessingChain>
{
private static final long serialVersionUID = 1L;
@@ -50,10 +51,7 @@ public class MessageActivityPanel extends JPanel implements ChannelEventListener
private static MessageActivityModel EMPTY_MODEL = new MessageActivityModel();
private JTable mMessageTable;
private Channel mDisplayedChannel;
private MessageActivityModel mDisplayedModel = EMPTY_MODEL;
private JTable mTable = new JTable(EMPTY_MODEL);
private MessageManagementPanel mManagementPanel = new MessageManagementPanel();
@@ -67,37 +65,20 @@ public class MessageActivityPanel extends JPanel implements ChannelEventListener
add(mManagementPanel, "span,growx");
mMessageTable = new JTable(mDisplayedModel);
add(new JScrollPane(mMessageTable), "span,grow");
add(new JScrollPane(mTable), "span,grow");
}
@Override
public void channelChanged(ChannelEvent event)
public void receive(ProcessingChain processingChain)
{
boolean changed = false;
if(event.getEvent() == Event.NOTIFICATION_SELECTION_CHANGE &&
event.getChannel().isSelected())
EventQueue.invokeLater(new Runnable()
{
if(mDisplayedChannel == null || (mDisplayedChannel != null && mDisplayedChannel != event.getChannel()))
@Override
public void run()
{
mDisplayedChannel = event.getChannel();
mTable.setModel(processingChain != null ? processingChain.getMessageActivityModel() : EMPTY_MODEL);
ProcessingChain chain = mChannelProcessingManager.getProcessingChain(mDisplayedChannel);
if(chain != null)
{
mDisplayedModel = chain.getMessageActivityModel();
}
else
{
mDisplayedModel = EMPTY_MODEL;
}
mMessageTable.setModel(mDisplayedModel);
if(mDisplayedChannel != null)
if(processingChain != null)
{
mManagementPanel.enableButtons();
}
@@ -105,31 +86,68 @@ public class MessageActivityPanel extends JPanel implements ChannelEventListener
{
mManagementPanel.disableButtons();
}
changed = true;
}
}
else if(event.getEvent() == Event.NOTIFICATION_PROCESSING_STOP || event.getEvent() == Event.REQUEST_DISABLE)
{
if(mDisplayedChannel != null && mDisplayedChannel == event.getChannel())
{
mDisplayedChannel = null;
mMessageTable.setModel(EMPTY_MODEL);
mManagementPanel.disableButtons();
changed = true;
}
}
if(changed)
{
revalidate();
repaint();
}
});
}
// @Override
// public void channelChanged(ChannelEvent event)
// {
// boolean changed = false;
//
// if(event.getEvent() == Event.NOTIFICATION_SELECTION_CHANGE &&
// event.getChannel().isSelected())
// {
// if(mDisplayedChannel == null || (mDisplayedChannel != null && mDisplayedChannel != event.getChannel()))
// {
// mDisplayedChannel = event.getChannel();
//
// ProcessingChain chain = mChannelProcessingManager.getProcessingChain(mDisplayedChannel);
//
// if(chain != null)
// {
// mDisplayedModel = chain.getMessageActivityModel();
// }
// else
// {
// mDisplayedModel = EMPTY_MODEL;
// }
//
// mMessageTable.setModel(mDisplayedModel);
//
// if(mDisplayedChannel != null)
// {
// mManagementPanel.enableButtons();
// }
// else
// {
// mManagementPanel.disableButtons();
// }
//
// changed = true;
// }
// }
// else if(event.getEvent() == Event.NOTIFICATION_PROCESSING_STOP || event.getEvent() == Event.REQUEST_DISABLE)
// {
// if(mDisplayedChannel != null && mDisplayedChannel == event.getChannel())
// {
// mDisplayedChannel = null;
//
// mMessageTable.setModel(EMPTY_MODEL);
//
// mManagementPanel.disableButtons();
//
// changed = true;
// }
// }
//
// if(changed)
// {
// revalidate();
// repaint();
// }
// }
public class MessageManagementPanel extends JPanel
{
private static final long serialVersionUID = 1L;
@@ -184,8 +202,7 @@ public class MessageActivityPanel extends JPanel implements ChannelEventListener
@Override
public void mouseClicked(MouseEvent arg0)
{
if(SwingUtilities.isLeftMouseButton(arg0) &&
arg0.getClickCount() == 2)
if(SwingUtilities.isLeftMouseButton(arg0) && arg0.getClickCount() == 2)
{
slider.setValue(500); //default
}
@@ -208,24 +225,13 @@ public class MessageActivityPanel extends JPanel implements ChannelEventListener
}
});
if(mDisplayedModel != null)
{
slider.setValue(mDisplayedModel.getMaxMessageCount());
}
else
{
slider.setValue(500);
}
slider.setValue(((MessageActivityModel)mTable.getModel()).getMaxMessageCount());
slider.addChangeListener(new ChangeListener()
{
@Override
public void stateChanged(ChangeEvent arg0)
{
if(mDisplayedModel != null)
{
mDisplayedModel.setMaxMessageCount(slider.getValue());
}
((MessageActivityModel)mTable.getModel()).setMaxMessageCount(slider.getValue());
}
});
@@ -239,10 +245,7 @@ public class MessageActivityPanel extends JPanel implements ChannelEventListener
@Override
public void actionPerformed(ActionEvent e)
{
if(mDisplayedModel != null)
{
mDisplayedModel.clear();
}
((MessageActivityModel)mTable.getModel()).clear();
}
});
}
@@ -261,61 +264,46 @@ public class MessageActivityPanel extends JPanel implements ChannelEventListener
@Override
public void actionPerformed(ActionEvent arg0)
{
if(mDisplayedChannel == null)
final JFrame editor = new JFrame();
editor.setTitle("Message Filter Editor");
editor.setSize(600, 400);
editor.setLocationRelativeTo(MessageFilterButton.this);
editor.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
editor.setLayout(new MigLayout("", "[grow,fill]",
"[grow,fill][][]"));
@SuppressWarnings("unchecked")
FilterSet<Message> filter = (FilterSet<Message>) ((MessageActivityModel)mTable.getModel()).getMessageFilter();
FilterEditorPanel<Message> panel = new FilterEditorPanel<Message>(filter);
JScrollPane scroller = new JScrollPane(panel);
scroller.setViewportView(panel);
editor.add(scroller, "wrap");
editor.add(new JLabel("Right-click to select/deselect all nodes"), "wrap");
JButton close = new JButton("Close");
close.addActionListener(new ActionListener()
{
JOptionPane.showMessageDialog(MessageFilterButton.this,
"Please enable and select a decoding channel to "
+ "adjust the channel's message display filter");
}
else
{
if(mDisplayedModel != null)
@Override
public void actionPerformed(ActionEvent e)
{
final JFrame editor = new JFrame();
editor.setTitle("Message Filter Editor");
editor.setSize(600, 400);
editor.setLocationRelativeTo(MessageFilterButton.this);
editor.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
editor.setLayout(new MigLayout("", "[grow,fill]",
"[grow,fill][][]"));
@SuppressWarnings("unchecked")
FilterSet<Message> filter = (FilterSet<Message>)
mDisplayedModel.getMessageFilter();
FilterEditorPanel<Message> panel =
new FilterEditorPanel<Message>(filter);
JScrollPane scroller = new JScrollPane(panel);
scroller.setViewportView(panel);
editor.add(scroller, "wrap");
editor.add(new JLabel("Right-click to select/deselect "
+ "all nodes"), "wrap");
JButton close = new JButton("Close");
close.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
editor.dispose();
}
});
editor.add(close);
EventQueue.invokeLater(new Runnable()
{
public void run()
{
editor.setVisible(true);
}
});
editor.dispose();
}
}
});
editor.add(close);
EventQueue.invokeLater(new Runnable()
{
public void run()
{
editor.setVisible(true);
}
});
}
});
}

View File

@@ -20,6 +20,8 @@ package module.decode.fleetsync2;
import alias.Alias;
import alias.AliasList;
import alias.id.AliasIDType;
import channel.metadata.AliasedStringAttributeMonitor;
import channel.metadata.Attribute;
import channel.metadata.AttributeChangeRequest;
import channel.state.DecoderState;
@@ -39,20 +41,20 @@ public class Fleetsync2DecoderState extends DecoderState
private TreeSet<String> mIdents = new TreeSet<String>();
private TreeSet<String> mEmergencyIdents = new TreeSet<String>();
private String mFrom;
private Alias mFromAlias;
private String mTo;
private Alias mToAlias;
private AliasedStringAttributeMonitor mFromAttribute;
private AliasedStringAttributeMonitor mToAttribute;
private String mMessage;
private String mMessageType;
private long mFrequency;
public Fleetsync2DecoderState(AliasList aliasList)
{
super(aliasList);
mFromAttribute = new AliasedStringAttributeMonitor(Attribute.SECONDARY_ADDRESS_FROM,
getAttributeChangeRequestListener(), getAliasList(), AliasIDType.FLEETSYNC);
mToAttribute = new AliasedStringAttributeMonitor(Attribute.SECONDARY_ADDRESS_TO,
getAttributeChangeRequestListener(), getAliasList(), AliasIDType.FLEETSYNC);
}
@Override
@@ -99,10 +101,8 @@ public class Fleetsync2DecoderState extends DecoderState
*/
public void resetState()
{
mFrom = null;
mFromAlias = null;
mTo = null;
mToAlias = null;
mFromAttribute.reset();
mToAttribute.reset();
mMessage = null;
mMessageType = null;
}
@@ -118,14 +118,14 @@ public class Fleetsync2DecoderState extends DecoderState
{
State state = State.CALL;
setFromID(fleetsync.getFromID());
mFromAttribute.process(fleetsync.getFromID());
mIdents.add(fleetsync.getFromID());
FleetsyncMessageType type = fleetsync.getMessageType();
if(type != FleetsyncMessageType.ANI)
{
setToID(fleetsync.getToID());
mToAttribute.process(fleetsync.getToID());
mIdents.add(fleetsync.getToID());
}
@@ -175,46 +175,6 @@ public class Fleetsync2DecoderState extends DecoderState
}
}
public String getFromID()
{
return mFrom;
}
public Alias getFromIDAlias()
{
return mFromAlias;
}
public void setFromID(String from)
{
if(!StringUtils.isEqual(mFrom, from))
{
mFrom = from;
mFromAlias = hasAliasList() ? getAliasList().getFleetsyncAlias(mFrom) : null;
broadcast(new AttributeChangeRequest<String>(Attribute.SECONDARY_ADDRESS_FROM, mFrom, mFromAlias));
}
}
public String getToID()
{
return mTo;
}
public Alias getToIDAlias()
{
return mToAlias;
}
public void setToID(String to)
{
if(!StringUtils.isEqual(mTo, to))
{
mTo = to;
mToAlias = hasAliasList() ? getAliasList().getFleetsyncAlias(mTo) : null;
broadcast(new AttributeChangeRequest<String>(Attribute.SECONDARY_ADDRESS_TO, mTo, mToAlias));
}
}
public String getMessage()
{
return mMessage;

View File

@@ -20,6 +20,8 @@ package module.decode.lj1200;
import alias.Alias;
import alias.AliasList;
import alias.id.AliasIDType;
import channel.metadata.AliasedStringAttributeMonitor;
import channel.metadata.Attribute;
import channel.metadata.AttributeChangeRequest;
import channel.state.DecoderState;
@@ -45,12 +47,14 @@ public class LJ1200DecoderState extends DecoderState
private Set<String> mAddresses = new TreeSet<String>();
private String mAddress;
private Alias mAddressAlias;
private AliasedStringAttributeMonitor mAddressAttribute;
public LJ1200DecoderState(AliasList aliasList)
{
super(aliasList);
mAddressAttribute = new AliasedStringAttributeMonitor(Attribute.SECONDARY_ADDRESS_TO,
getAttributeChangeRequestListener(), getAliasList(), AliasIDType.LOJACK);
}
@Override
@@ -69,16 +73,6 @@ public class LJ1200DecoderState extends DecoderState
{
}
public String getAddress()
{
return mAddress;
}
public Alias getAddressAlias()
{
return mAddressAlias;
}
@Override
public void receive(Message message)
{
@@ -88,10 +82,10 @@ public class LJ1200DecoderState extends DecoderState
if(lj.isValid())
{
setAddress(lj.getAddress());
setAddressAlias(lj.getTransponderAlias());
String address = lj.getAddress();
mAddresses.add(mAddress);
mAddressAttribute.process(address);
mAddresses.add(address);
broadcast(LJ1200CallEvent.getLJ1200Event(lj));
@@ -104,21 +98,6 @@ public class LJ1200DecoderState extends DecoderState
}
}
private void setAddress(String address)
{
if(!StringUtils.isEqual(mAddress, address))
{
mAddress = address;
broadcast(new AttributeChangeRequest<String>(Attribute.SECONDARY_ADDRESS_TO, mAddress, mAddressAlias));
}
}
private void setAddressAlias(Alias alias)
{
mAddressAlias = alias;
broadcast(new AttributeChangeRequest<String>(Attribute.SECONDARY_ADDRESS_TO, mAddress, mAddressAlias));
}
@Override
public String getActivitySummary()
{
@@ -163,8 +142,7 @@ public class LJ1200DecoderState extends DecoderState
private void resetState()
{
mAddress = null;
mAddressAlias = null;
mAddressAttribute.reset();
}
@Override

View File

@@ -19,6 +19,9 @@ package module.decode.ltrnet;
import alias.Alias;
import alias.AliasList;
import alias.id.AliasIDType;
import channel.metadata.AliasedIntegerAttributeMonitor;
import channel.metadata.AliasedStringAttributeMonitor;
import channel.metadata.Attribute;
import channel.metadata.AttributeChangeRequest;
import channel.state.DecoderState;
@@ -57,10 +60,9 @@ public class LTRNetDecoderState extends DecoderState
new HashMap<Integer,Long>();
private HashMap<Integer,String> mActiveCalls = new HashMap<Integer,String>();
private String mToTalkgroup;
private Alias mToTalkgroupAlias;
private String mFromTalkgroup;
private Alias mFromTalkgroupAlias;
private AliasedStringAttributeMonitor mToAttribute;
private AliasedIntegerAttributeMonitor mFromUIDAttribute;
private AliasedStringAttributeMonitor mESNAttribute;
private String mMessage;
private String mMessageType;
private int mChannelNumber;
@@ -69,6 +71,16 @@ public class LTRNetDecoderState extends DecoderState
public LTRNetDecoderState(AliasList aliasList)
{
super(aliasList);
mToAttribute = new AliasedStringAttributeMonitor(Attribute.PRIMARY_ADDRESS_TO,
getAttributeChangeRequestListener(), getAliasList(), AliasIDType.TALKGROUP);
mToAttribute.addIllegalValue("0-00-000");
mFromUIDAttribute = new AliasedIntegerAttributeMonitor(Attribute.PRIMARY_ADDRESS_TO,
getAttributeChangeRequestListener(), getAliasList(), AliasIDType.LTR_NET_UID);
mESNAttribute = new AliasedStringAttributeMonitor(Attribute.SECONDARY_ADDRESS_FROM,
getAttributeChangeRequestListener(), getAliasList(), AliasIDType.ESN);
}
@Override
@@ -204,8 +216,7 @@ public class LTRNetDecoderState extends DecoderState
broadcast(mCurrentCallEvent);
}
setFromTalkgroup(String.valueOf(uniqueID));
setFromTalkgroupAlias(ltr.getRadioUniqueIDAlias());
mFromUIDAttribute.process(uniqueID);
break;
case ID_SITE:
String siteID = ltr.getSiteID();
@@ -243,8 +254,7 @@ public class LTRNetDecoderState extends DecoderState
}
setMessageType("ESN");
setFromTalkgroup(ltr.getESN());
setFromTalkgroupAlias(ltr.getESNAlias());
mESNAttribute.process(ltr.getESN());
broadcast(new DecoderStateEvent(this, Event.DECODE, State.DATA));
@@ -272,8 +282,7 @@ public class LTRNetDecoderState extends DecoderState
mUniqueIDs.add(uniqueid);
setMessageType("REGISTER UID");
setToTalkgroup(String.valueOf(uniqueid));
setToTalkgroupAlias(ltr.getRadioUniqueIDAlias());
mFromUIDAttribute.process(uniqueid);
if(getCurrentLTRCallEvent() == null)
{
@@ -609,10 +618,11 @@ public class LTRNetDecoderState extends DecoderState
if(isValidTalkgroup(talkgroup))
{
mToAttribute.process(talkgroup);
final LTRCallEvent current = getCurrentLTRCallEvent();
/* If this is a new call or the talkgroup is different from the current
* call, create a new call event */
//If this is a new call or the talkgroup is different from the current call, create a new call event
if(current == null || isDifferentTalkgroup(talkgroup))
{
/* Invalidate the current call */
@@ -622,22 +632,18 @@ public class LTRNetDecoderState extends DecoderState
broadcast(current);
}
setToTalkgroup(message.getTalkgroupID());
/* A talkgroup must be seen at least once before it will be added
* to the mTalkgroups list that is used in the activity summary,
* so that we don't pollute the summary with one-off error talkgroups */
if(mTalkgroupsFirstHeard.contains(mToTalkgroup))
if(mTalkgroupsFirstHeard.contains(talkgroup))
{
mTalkgroups.add(mToTalkgroup);
mTalkgroups.add(talkgroup);
}
else
{
mTalkgroupsFirstHeard.add(mToTalkgroup);
mTalkgroupsFirstHeard.add(talkgroup);
}
setToTalkgroupAlias(message.getTalkgroupIDAlias());
CallEvent callEvent = new LTRCallEvent.Builder(DecoderType.LTR_NET, CallEventType.CALL)
.aliasList(getAliasList())
.channel(String.valueOf(message.getChannel()))
@@ -704,71 +710,13 @@ public class LTRNetDecoderState extends DecoderState
mCurrentCallEvent = null;
mToTalkgroup = null;
mToTalkgroupAlias = null;
mToAttribute.reset();
mESNAttribute.reset();
mFromUIDAttribute.reset();
mMessage = null;
mMessageType = null;
}
public String getToTalkgroup()
{
return mToTalkgroup;
}
public void setToTalkgroup(String toTalkgroup)
{
if(!StringUtils.isEqual(mToTalkgroup, toTalkgroup))
{
mToTalkgroup = toTalkgroup;
broadcast(new AttributeChangeRequest<String>(Attribute.PRIMARY_ADDRESS_TO, mToTalkgroup, mToTalkgroupAlias));
}
}
public Alias getToTalkgroupAlias()
{
return mToTalkgroupAlias;
}
public void setToTalkgroupAlias(Alias alias)
{
if(mToTalkgroupAlias == null || (alias != null && mToTalkgroupAlias != alias))
{
mToTalkgroupAlias = alias;
broadcast(new AttributeChangeRequest<String>(Attribute.PRIMARY_ADDRESS_TO, mToTalkgroup, mToTalkgroupAlias));
}
}
public String getFromTalkgroup()
{
return mFromTalkgroup;
}
public void setFromTalkgroup(String fromTalkgroup)
{
if(!StringUtils.isEqual(mFromTalkgroup, fromTalkgroup))
{
mFromTalkgroup = fromTalkgroup;
broadcast(new AttributeChangeRequest<String>(Attribute.PRIMARY_ADDRESS_FROM, mFromTalkgroup,
mFromTalkgroupAlias));
}
}
public Alias getFromTalkgroupAlias()
{
return mFromTalkgroupAlias;
}
public void setFromTalkgroupAlias(Alias alias)
{
if(mFromTalkgroupAlias == null || (alias != null && alias != mFromTalkgroupAlias))
{
mFromTalkgroupAlias = alias;
broadcast(new AttributeChangeRequest<String>(Attribute.PRIMARY_ADDRESS_FROM, mFromTalkgroup,
mFromTalkgroupAlias));
}
}
public String getMessage()
{
return mMessage;

View File

@@ -20,6 +20,8 @@ package module.decode.ltrstandard;
import alias.Alias;
import alias.AliasList;
import alias.id.AliasIDType;
import channel.metadata.AliasedStringAttributeMonitor;
import channel.metadata.Attribute;
import channel.metadata.AttributeChangeRequest;
import channel.state.DecoderState;
@@ -56,14 +58,16 @@ public class LTRStandardDecoderState extends DecoderState
private Set<String> mTalkgroupsFirstHeard = new HashSet<>();
private Set<String> mTalkgroups = new TreeSet<>();
private String mTalkgroup;
private Alias mTalkgroupAlias;
private AliasedStringAttributeMonitor mTalkgroupAttribute;
private long mFrequency;
private LCNTracker mLCNTracker = new LCNTracker();
public LTRStandardDecoderState(AliasList aliasList)
{
super(aliasList);
mTalkgroupAttribute = new AliasedStringAttributeMonitor(Attribute.PRIMARY_ADDRESS_TO,
getAttributeChangeRequestListener(), getAliasList(), AliasIDType.TALKGROUP);
}
@Override
@@ -134,11 +138,9 @@ public class LTRStandardDecoderState extends DecoderState
if(mLCNTracker.isCurrentChannel(channel))
{
setTalkgroup(start.getToID());
processTalkgroup(mTalkgroup);
setTalkgroupAlias(start.getToIDAlias());
String talkgroup = start.getToID();
mTalkgroupAttribute.process(talkgroup);
processTalkgroup(talkgroup);
}
}
@@ -156,11 +158,9 @@ public class LTRStandardDecoderState extends DecoderState
if(mLCNTracker.isCurrentChannel(repeater))
{
setTalkgroup(end.getToID());
processTalkgroup(mTalkgroup);
setTalkgroupAlias(end.getToIDAlias());
String talkgroup = end.getToID();
mTalkgroupAttribute.process(talkgroup);
processTalkgroup(talkgroup);
LTRCallEvent event = mActiveCalls.remove(repeater);
@@ -231,36 +231,7 @@ public class LTRStandardDecoderState extends DecoderState
mActiveCalls.clear();
mTalkgroup = null;
mTalkgroupAlias = null;
}
public String getTalkgroup()
{
return mTalkgroup;
}
private void setTalkgroup(String talkgroup)
{
if(!StringUtils.isEqual(mTalkgroup, talkgroup))
{
mTalkgroup = talkgroup;
broadcast(new AttributeChangeRequest<String>(Attribute.PRIMARY_ADDRESS_TO, mTalkgroup, mTalkgroupAlias));
}
}
public Alias getTalkgroupAlias()
{
return mTalkgroupAlias;
}
private void setTalkgroupAlias(Alias alias)
{
if(mTalkgroupAlias == null || (alias != null && mTalkgroupAlias != alias))
{
mTalkgroupAlias = alias;
broadcast(new AttributeChangeRequest<String>(Attribute.PRIMARY_ADDRESS_TO, mTalkgroup, mTalkgroupAlias));
}
mTalkgroupAttribute.reset();
}
public boolean hasChannelNumber()

View File

@@ -20,6 +20,8 @@ package module.decode.mdc1200;
import alias.Alias;
import alias.AliasList;
import alias.id.AliasIDType;
import channel.metadata.AliasedStringAttributeMonitor;
import channel.metadata.Attribute;
import channel.metadata.AttributeChangeRequest;
import channel.state.DecoderState;
@@ -39,16 +41,16 @@ public class MDCDecoderState extends DecoderState
private TreeSet<String> mIdents = new TreeSet<String>();
private TreeSet<String> mEmergencyIdents = new TreeSet<String>();
private String mFrom;
private Alias mFromAlias;
private String mTo;
private Alias mToAlias;
private AliasedStringAttributeMonitor mFromAttribute;
private String mMessage;
private String mMessageType;
public MDCDecoderState(AliasList aliasList)
{
super(aliasList);
mFromAttribute = new AliasedStringAttributeMonitor(Attribute.SECONDARY_ADDRESS_FROM,
getAttributeChangeRequestListener(), getAliasList(), AliasIDType.MDC1200);
}
@Override
@@ -78,10 +80,7 @@ public class MDCDecoderState extends DecoderState
private void resetState()
{
mFrom = null;
mFromAlias = null;
mTo = null;
mToAlias = null;
mFromAttribute.reset();
mMessage = null;
mMessageType = null;
}
@@ -100,8 +99,7 @@ public class MDCDecoderState extends DecoderState
mEmergencyIdents.add(mdc.getUnitID());
}
setFrom(mdc.getFromID());
setFromAlias(mdc.getFromIDAlias());
mFromAttribute.process(mdc.getFromID());
MDCMessageType type = mdc.getMessageType();
@@ -145,62 +143,6 @@ public class MDCDecoderState extends DecoderState
}
}
public String getFrom()
{
return mFrom;
}
public void setFrom(String from)
{
if(!StringUtils.isEqual(mFrom, from))
{
mFrom = from;
broadcast(new AttributeChangeRequest<String>(Attribute.SECONDARY_ADDRESS_FROM, mFrom, mFromAlias));
}
}
public Alias getFromAlias()
{
return mFromAlias;
}
public void setFromAlias(Alias alias)
{
if(mFromAlias == null || (alias != null && mFromAlias != alias))
{
mFromAlias = alias;
broadcast(new AttributeChangeRequest<String>(Attribute.SECONDARY_ADDRESS_FROM, mFrom, mFromAlias));
}
}
public String getTo()
{
return mTo;
}
public void setTo(String to)
{
if(!StringUtils.isEqual(mTo, to))
{
mTo = to;
broadcast(new AttributeChangeRequest<String>(Attribute.SECONDARY_ADDRESS_TO, mTo, mToAlias));
}
}
public Alias getToAlias()
{
return mToAlias;
}
public void setToAlias(Alias alias)
{
if(mToAlias == null || (alias != null && mToAlias != alias))
{
mToAlias = alias;
broadcast(new AttributeChangeRequest<String>(Attribute.SECONDARY_ADDRESS_TO, mTo, mToAlias));
}
}
public String getMessage()
{
return mMessage;

View File

@@ -20,6 +20,8 @@ package module.decode.mpt1327;
import alias.Alias;
import alias.AliasList;
import alias.id.AliasIDType;
import channel.metadata.AliasedStringAttributeMonitor;
import channel.metadata.Attribute;
import channel.metadata.AttributeChangeRequest;
import channel.state.ChangeChannelTimeoutEvent;
@@ -56,8 +58,8 @@ public class MPT1327DecoderState extends DecoderState
private HashMap<String,ArrayList<String>> mGroups = new HashMap<String,ArrayList<String>>();
private String mSite;
private String mFromTalkgroup;
private String mToTalkgroup;
private AliasedStringAttributeMonitor mFromAttribute;
private AliasedStringAttributeMonitor mToAttribute;
private int mChannelNumber;
private ChannelType mChannelType;
@@ -73,6 +75,10 @@ public class MPT1327DecoderState extends DecoderState
mChannelMap = channelMap;
mChannelType = channelType;
mCallTimeout = callTimeout;
mFromAttribute = new AliasedStringAttributeMonitor(Attribute.PRIMARY_ADDRESS_FROM,
getAttributeChangeRequestListener(), getAliasList(), AliasIDType.MPT1327);
mToAttribute = new AliasedStringAttributeMonitor(Attribute.PRIMARY_ADDRESS_TO,
getAttributeChangeRequestListener(), getAliasList(), AliasIDType.MPT1327);
}
@Override
@@ -277,7 +283,7 @@ public class MPT1327DecoderState extends DecoderState
broadcast(mCurrentCallEvent);
}
setToTalkgroup(mpt.getToID());
mToAttribute.process(mpt.getToID());
broadcast(new DecoderStateEvent(this, Event.START, State.CALL));
}
@@ -298,8 +304,8 @@ public class MPT1327DecoderState extends DecoderState
private void resetState()
{
mFromTalkgroup = null;
mToTalkgroup = null;
mFromAttribute.reset();
mToAttribute.reset();
/**
* If this is a standard channel, reset the fade timeout to the default
@@ -359,67 +365,6 @@ public class MPT1327DecoderState extends DecoderState
mChannelMap = channelMap;
}
public String getFromTalkgroup()
{
return mFromTalkgroup;
}
/**
* Set the talkgroup. This is used primarily for traffic channels since
* the talkgroup will already have been identified prior to the traffic
* channel being created.
*/
public void setFromTalkgroup(String fromTalkgroup)
{
if(!StringUtils.isEqual(mFromTalkgroup, fromTalkgroup))
{
mFromTalkgroup = fromTalkgroup;
broadcast(new AttributeChangeRequest<String>(Attribute.PRIMARY_ADDRESS_FROM, mFromTalkgroup,
getFromTalkgroupAlias()));
}
}
public Alias getFromTalkgroupAlias()
{
if(hasAliasList())
{
return getAliasList().getMPT1327Alias(mFromTalkgroup);
}
return null;
}
public String getToTalkgroup()
{
return mToTalkgroup;
}
/**
* Set the talkgroup. This is used primarily for traffic channels since
* the talkgroup will already have been identified prior to the traffic
* channel being created.
*/
public void setToTalkgroup(String toTalkgroup)
{
if(!StringUtils.isEqual(mToTalkgroup, toTalkgroup))
{
mToTalkgroup = toTalkgroup;
broadcast(new AttributeChangeRequest<String>(Attribute.PRIMARY_ADDRESS_TO, mToTalkgroup,
getToTalkgroupAlias()));
}
}
public Alias getToTalkgroupAlias()
{
if(hasAliasList())
{
return getAliasList().getMPT1327Alias(mToTalkgroup);
}
return null;
}
public int getChannelNumber()
{
return mChannelNumber;
@@ -588,6 +533,8 @@ public class MPT1327DecoderState extends DecoderState
TrafficChannelAllocationEvent allocationEvent =
(TrafficChannelAllocationEvent) event;
broadcast(new AttributeChangeRequest<String>(Attribute.CHANNEL_CONFIGURATION_LABEL_1, "TRAFFIC"));
String channel = allocationEvent.getCallEvent().getChannel();
if(channel != null)
@@ -606,8 +553,8 @@ public class MPT1327DecoderState extends DecoderState
broadcast(new AttributeChangeRequest<Long>(Attribute.CHANNEL_FREQUENCY,
allocationEvent.getCallEvent().getFrequency()));
setFromTalkgroup(allocationEvent.getCallEvent().getFromID());
setToTalkgroup(allocationEvent.getCallEvent().getToID());
mFromAttribute.process(allocationEvent.getCallEvent().getFromID());
mToAttribute.process(allocationEvent.getCallEvent().getToID());
}
}
break;

View File

@@ -3669,8 +3669,9 @@ public class P25DecoderState extends DecoderState
{
if(event instanceof TrafficChannelAllocationEvent)
{
TrafficChannelAllocationEvent allocationEvent =
(TrafficChannelAllocationEvent) event;
TrafficChannelAllocationEvent allocationEvent = (TrafficChannelAllocationEvent) event;
broadcast(new AttributeChangeRequest<String>(Attribute.CHANNEL_CONFIGURATION_LABEL_1, "TRAFFIC"));
mCurrentCallEvent = (P25CallEvent) allocationEvent.getCallEvent();

View File

@@ -20,6 +20,8 @@ package module.decode.passport;
import alias.Alias;
import alias.AliasList;
import alias.id.AliasIDType;
import channel.metadata.AliasedStringAttributeMonitor;
import channel.metadata.Attribute;
import channel.metadata.AttributeChangeRequest;
import channel.state.DecoderState;
@@ -32,7 +34,6 @@ import module.decode.event.CallEvent;
import module.decode.event.CallEvent.CallEventType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import util.StringUtils;
import java.util.ArrayList;
import java.util.Collections;
@@ -53,10 +54,8 @@ public class PassportDecoderState extends DecoderState
private HashMap<Integer,String> mSiteLCNs = new HashMap<Integer,String>();
private HashMap<Integer,String> mNeighborLCNs = new HashMap<Integer,String>();
private String mTalkgroup;
private Alias mTalkgroupAlias;
private String mMobileID;
private Alias mMobileIDAlias;
private AliasedStringAttributeMonitor mFromMobileIDAttribute;
private AliasedStringAttributeMonitor mToTalkgroupAttribute;
private int mChannelNumber;
private int mSiteNumber;
private PassportBand mSiteBand;
@@ -66,6 +65,11 @@ public class PassportDecoderState extends DecoderState
public PassportDecoderState(AliasList aliasList)
{
super(aliasList);
mFromMobileIDAttribute = new AliasedStringAttributeMonitor(Attribute.PRIMARY_ADDRESS_FROM,
getAttributeChangeRequestListener(), getAliasList(), AliasIDType.MIN);
mToTalkgroupAttribute = new AliasedStringAttributeMonitor(Attribute.PRIMARY_ADDRESS_TO,
getAttributeChangeRequestListener(), getAliasList(), AliasIDType.TALKGROUP);
}
@Override
@@ -146,7 +150,7 @@ public class PassportDecoderState extends DecoderState
/* Call on this channel */
if(passport.getLCN() == mChannelNumber)
{
setTalkgroup(talkgroup);
mToTalkgroupAttribute.process(talkgroup);
PassportCallEvent current = getCurrentCallEvent();
@@ -207,7 +211,7 @@ public class PassportDecoderState extends DecoderState
String.valueOf(passport.getTalkgroupID());
logTalkgroup(endTalkgroup);
setTalkgroup(endTalkgroup);
mToTalkgroupAttribute.process(endTalkgroup);
broadcast(new DecoderStateEvent(this,
Event.END, State.CALL));
@@ -234,11 +238,11 @@ public class PassportDecoderState extends DecoderState
{
setChannelNumber(passport.getLCN());
}
/* Data call on this channel */
if(passport.getLCN() == mChannelNumber)
{
setTalkgroup(dataTalkgroup);
mToTalkgroupAttribute.process(dataTalkgroup);
PassportCallEvent current = getCurrentCallEvent();
@@ -299,7 +303,7 @@ public class PassportDecoderState extends DecoderState
String.valueOf(passport.getTalkgroupID());
logTalkgroup(dataEndTalkgroup);
setTalkgroup(dataEndTalkgroup);
mToTalkgroupAttribute.process(dataEndTalkgroup);
broadcast(new DecoderStateEvent(this,
Event.END, State.DATA));
@@ -321,7 +325,7 @@ public class PassportDecoderState extends DecoderState
mMobileIDs.add(min);
}
setMobileID(min);
mFromMobileIDAttribute.process(min);
final CallEvent current = getCurrentCallEvent();
@@ -519,10 +523,8 @@ public class PassportDecoderState extends DecoderState
private void resetState()
{
mTalkgroup = null;
mTalkgroupAlias = null;
mMobileID = null;
mMobileIDAlias = null;
mToTalkgroupAttribute.reset();
mFromMobileIDAttribute.reset();
}
public int getChannelNumber()
@@ -568,48 +570,6 @@ public class PassportDecoderState extends DecoderState
}
}
public String getTalkgroup()
{
return mTalkgroup;
}
public void setTalkgroup(String talkgroup)
{
if(!StringUtils.isEqual(mTalkgroup, talkgroup))
{
mTalkgroup = talkgroup;
mTalkgroupAlias = hasAliasList() ? getAliasList().getTalkgroupAlias(getTalkgroup()) : null;
broadcast(new AttributeChangeRequest<String>(Attribute.PRIMARY_ADDRESS_TO, getTalkgroup(),
getTalkgroupAlias()));
}
}
public Alias getTalkgroupAlias()
{
return mTalkgroupAlias;
}
public String getMobileID()
{
return mMobileID;
}
public void setMobileID(String id)
{
if(!StringUtils.isEqual(mMobileID, id))
{
mMobileID = id;
mMobileIDAlias = hasAliasList() ? getAliasList().getMobileIDNumberAlias(getMobileID()) : null;
broadcast(new AttributeChangeRequest<String>(Attribute.PRIMARY_ADDRESS_FROM, getMobileID(),
getMobileIDAlias()));
}
}
public Alias getMobileIDAlias()
{
return mMobileIDAlias;
}
@Override
public void receiveDecoderStateEvent(DecoderStateEvent event)
{

View File

@@ -20,6 +20,8 @@ package module.decode.tait;
import alias.Alias;
import alias.AliasList;
import alias.id.AliasIDType;
import channel.metadata.AliasedStringAttributeMonitor;
import channel.metadata.Attribute;
import channel.metadata.AttributeChangeRequest;
import channel.state.DecoderState;
@@ -42,18 +44,19 @@ public class Tait1200DecoderState extends DecoderState
{
private TreeSet<String> mIdents = new TreeSet<String>();
private String mFrom;
private Alias mFromAlias;
private String mTo;
private Alias mToAlias;
private AliasedStringAttributeMonitor mFromAttribute;
private AliasedStringAttributeMonitor mToAttribute;
private String mMessage;
private String mMessageType;
public Tait1200DecoderState(AliasList aliasList)
{
super(aliasList);
mFromAttribute = new AliasedStringAttributeMonitor(Attribute.SECONDARY_ADDRESS_FROM,
getAttributeChangeRequestListener(), getAliasList(), AliasIDType.TALKGROUP);
mToAttribute = new AliasedStringAttributeMonitor(Attribute.SECONDARY_ADDRESS_TO,
getAttributeChangeRequestListener(), getAliasList(), AliasIDType.TALKGROUP);
}
@Override
@@ -82,10 +85,8 @@ public class Tait1200DecoderState extends DecoderState
private void resetState()
{
mFrom = null;
mFromAlias = null;
mTo = null;
mToAlias = null;
mFromAttribute.reset();
mToAttribute.reset();
mMessage = null;
mMessageType = null;
}
@@ -97,12 +98,10 @@ public class Tait1200DecoderState extends DecoderState
{
Tait1200GPSMessage gps = (Tait1200GPSMessage) message;
setFromID(gps.getFromID());
setFromIDAlias(gps.getFromIDAlias());
mFromAttribute.process(gps.getFromID());
mIdents.add(gps.getFromID());
setToID(gps.getToID());
setToIDAlias(gps.getToIDAlias());
mToAttribute.process(gps.getToID());
mIdents.add(gps.getToID());
GeoPosition position = gps.getGPSLocation();
@@ -123,13 +122,10 @@ public class Tait1200DecoderState extends DecoderState
else if(message instanceof Tait1200ANIMessage)
{
Tait1200ANIMessage ani = (Tait1200ANIMessage) message;
setFromID(ani.getFromID());
setFromIDAlias(ani.getFromIDAlias());
mFromAttribute.process(ani.getFromID());
mIdents.add(ani.getFromID());
setToID(ani.getToID());
setToIDAlias(ani.getToIDAlias());
mToAttribute.process(ani.getToID());
mIdents.add(ani.getToID());
setMessage(null);
@@ -202,62 +198,6 @@ public class Tait1200DecoderState extends DecoderState
}
}
public String getFromID()
{
return mFrom;
}
public void setFromID(String from)
{
if(!StringUtils.isEqual(mFrom, from))
{
mFrom = from;
broadcast(new AttributeChangeRequest<String>(Attribute.SECONDARY_ADDRESS_FROM, getFromID(), getFromIDAlias()));
}
}
public Alias getFromIDAlias()
{
return mFromAlias;
}
public void setFromIDAlias(Alias alias)
{
if(mFromAlias == null || (alias != null && mFromAlias != alias))
{
mFromAlias = alias;
broadcast(new AttributeChangeRequest<String>(Attribute.SECONDARY_ADDRESS_FROM, getFromID(), getFromIDAlias()));
}
}
public String getToID()
{
return mTo;
}
public void setToID(String to)
{
if(!StringUtils.isEqual(mTo, to))
{
mTo = to;
broadcast(new AttributeChangeRequest<String>(Attribute.SECONDARY_ADDRESS_TO, getToID(), getToIDAlias()));
}
}
public Alias getToIDAlias()
{
return mToAlias;
}
public void setToIDAlias(Alias alias)
{
if(mToAlias == null || (alias != null && mToAlias != alias))
{
mToAlias = alias;
broadcast(new AttributeChangeRequest<String>(Attribute.SECONDARY_ADDRESS_TO, getToID(), getToIDAlias()));
}
}
public String getMessage()
{
return mMessage;

View File

@@ -1,22 +1,26 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 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 properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.awt.*;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@@ -30,9 +34,6 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* SystemProperties - provides an isolated instance of properties for the
* application
@@ -40,301 +41,325 @@ import org.slf4j.LoggerFactory;
public class SystemProperties
{
private final static Logger mLog =
LoggerFactory.getLogger( SystemProperties.class );
private final static Logger mLog =
LoggerFactory.getLogger(SystemProperties.class);
private static String sDEFAULT_APP_ROOT = "SDRTrunk";
private static String sPROPERTIES_FILENAME = "SDRTrunk.properties";
private static SystemProperties mInstance;
private static Properties mProperties;
private Path mPropertiesPath;
private String mApplicationName;
private SystemProperties()
{
mProperties = new Properties();
}
/**
* Returns a SINGLETON instance of the application properties set
* @return
*/
public static SystemProperties getInstance()
{
if( mInstance == null )
{
mInstance = new SystemProperties();
}
return mInstance;
}
private static String sDEFAULT_APP_ROOT = "SDRTrunk";
private static String sPROPERTIES_FILENAME = "SDRTrunk.properties";
/**
* Saves any currently changed settings to the application properties file
*/
public void save()
{
Path propsPath =
getApplicationRootPath().resolve( sPROPERTIES_FILENAME );
private static SystemProperties mInstance;
private static Properties mProperties;
private Path mPropertiesPath;
private String mApplicationName;
OutputStream out = null;
try
{
out = new FileOutputStream( propsPath.toString() );
private SystemProperties()
{
mProperties = new Properties();
}
String comments =
"SDRTrunk - SDR Trunking Decoder Application Settings";
mProperties.store( out, comments );
}
catch( Exception e )
{
mLog.error( "SystemProperties - exception while saving " +
"application properties", e );
}
finally
{
if( out != null )
{
try
/**
* Returns a SINGLETON instance of the application properties set
*
* @return
*/
public static SystemProperties getInstance()
{
if(mInstance == null)
{
mInstance = new SystemProperties();
}
return mInstance;
}
/**
* Saves any currently changed settings to the application properties file
*/
public void save()
{
Path propsPath =
getApplicationRootPath().resolve(sPROPERTIES_FILENAME);
OutputStream out = null;
try
{
out = new FileOutputStream(propsPath.toString());
String comments =
"SDRTrunk - SDR Trunking Decoder Application Settings";
mProperties.store(out, comments);
}
catch(Exception e)
{
mLog.error("SystemProperties - exception while saving " +
"application properties", e);
}
finally
{
if(out != null)
{
try
{
out.close();
out.close();
}
catch ( IOException e )
catch(IOException e)
{
}
}
}
}
}
}
}
/**
* Application root directory. Normally returns "SDRTRunk" from the user's
* home directory, unless that has been changed to another location on the
* file system by the user.
*/
public Path getApplicationRootPath()
{
Path retVal = null;
String root = get( "root.directory", sDEFAULT_APP_ROOT );
if( root.equalsIgnoreCase( sDEFAULT_APP_ROOT ) )
{
retVal = Paths.get(
System.getProperty( "user.home" ), sDEFAULT_APP_ROOT );
}
else
{
retVal = Paths.get( root );
}
return retVal;
}
public Path getApplicationFolder( String folder )
{
Path retVal = getApplicationRootPath().resolve( folder );
if( !Files.exists( retVal ) )
{
try
{
Files.createDirectory( retVal );
}
catch ( IOException e )
{
mLog.error( "SystemProperties - exception while creating " +
"app folder [" + folder + "]", e );
}
}
return retVal;
}
public void logCurrentSettings()
{
if( mPropertiesPath == null )
{
mLog.info( "SystemProperties - no properties file loaded - using defaults" );
}
else
{
mLog.info( "SystemProperties - application properties loaded [" + mPropertiesPath.toString() + "]" );
}
}
/**
* Loads the properties file into this properties set
* @param file
*/
public void load( Path propertiesPath )
{
if( propertiesPath != null )
{
mPropertiesPath = propertiesPath;
InputStream in = null;
/**
* Application root directory. Normally returns "SDRTRunk" from the user's
* home directory, unless that has been changed to another location on the
* file system by the user.
*/
public Path getApplicationRootPath()
{
Path retVal = null;
String root = get("root.directory", sDEFAULT_APP_ROOT);
if(root.equalsIgnoreCase(sDEFAULT_APP_ROOT))
{
retVal = Paths.get(
System.getProperty("user.home"), sDEFAULT_APP_ROOT);
}
else
{
retVal = Paths.get(root);
}
return retVal;
}
public Path getApplicationFolder(String folder)
{
Path retVal = getApplicationRootPath().resolve(folder);
if(!Files.exists(retVal))
{
try
{
in = new FileInputStream( propertiesPath.toString() );
Files.createDirectory(retVal);
}
catch ( FileNotFoundException e )
catch(IOException e)
{
mLog.error( "SDRTrunk - exception while opening inputstream on " +
"application properties file", e );
mLog.error("SystemProperties - exception while creating " +
"app folder [" + folder + "]", e);
}
}
return retVal;
}
public void logCurrentSettings()
{
if(mPropertiesPath == null)
{
mLog.info("SystemProperties - no properties file loaded - using defaults");
}
else
{
mLog.info("SystemProperties - application properties loaded [" + mPropertiesPath.toString() + "]");
}
}
/**
* Loads the properties file into this properties set
*
* @param file
*/
public void load(Path propertiesPath)
{
if(propertiesPath != null)
{
mPropertiesPath = propertiesPath;
InputStream in = null;
try
{
in = new FileInputStream(propertiesPath.toString());
}
catch(FileNotFoundException e)
{
mLog.error("SDRTrunk - exception while opening inputstream on " +
"application properties file", e);
}
if( in != null )
{
try
if(in != null)
{
try
{
mProperties.load( in );
mProperties.load(in);
}
catch ( IOException e )
catch(IOException e)
{
mLog.error( "SDRTrunk - exception while loading properties " +
"inputstream into SystemProperties", e );
mLog.error("SDRTrunk - exception while loading properties " +
"inputstream into SystemProperties", e);
}
finally
{
try
finally
{
try
{
in.close();
in.close();
}
catch ( IOException e )
catch(IOException e)
{
}
}
}
}
mLog.info( "SystemProperties - loaded [" +
propertiesPath.toString() + "]" );
}
}
}
}
public String getApplicationName()
{
if(mApplicationName == null)
{
StringBuilder sb = new StringBuilder();
mLog.info("SystemProperties - loaded [" +
propertiesPath.toString() + "]");
}
sb.append( "sdrtrunk" );
public String getApplicationName()
{
if(mApplicationName == null)
{
StringBuilder sb = new StringBuilder();
try(BufferedReader reader = new BufferedReader(
new InputStreamReader( this.getClass()
.getResourceAsStream( "/sdrtrunk-version" ) ) ) )
{
String version = reader.readLine();
sb.append("sdrtrunk");
if( version != null )
{
sb.append( " V" );
sb.append( version );
}
}
catch( Exception e )
{
mLog.error( "Couldn't read sdrtrunk version from application jar file" );
}
try(BufferedReader reader = new BufferedReader(
new InputStreamReader(this.getClass()
.getResourceAsStream("/sdrtrunk-version"))))
{
String version = reader.readLine();
mApplicationName = sb.toString();
}
if(version != null)
{
sb.append(" V");
sb.append(version);
}
}
catch(Exception e)
{
mLog.error("Couldn't read sdrtrunk version from application jar file");
}
return mApplicationName;
}
mApplicationName = sb.toString();
}
/**
* Returns the value of the property, or null if the property doesn't exist
*/
private String get( String key )
{
return mProperties.getProperty( key );
}
return mApplicationName;
}
/**
* Returns the value of the property, or the defaultValue if the
* property doesn't exist
*/
public String get( String key, String defaultValue )
{
String value = get( key );
if( value != null )
{
return value;
}
/**
* Returns the value of the property, or null if the property doesn't exist
*/
private String get(String key)
{
return mProperties.getProperty(key);
}
set( key, defaultValue );
return defaultValue;
}
/**
* Returns the value of the property, or the defaultValue if the
* property doesn't exist
*/
public boolean get( String key, boolean defaultValue )
{
String value = get( key );
if( value != null )
{
try
{
boolean stored = Boolean.parseBoolean( value );
return stored;
}
catch( Exception e )
{
//Do nothing, we couldn't parse the stored value
}
}
/**
* Returns the value of the property, or the defaultValue if the
* property doesn't exist
*/
public String get(String key, String defaultValue)
{
String value = get(key);
set( key, String.valueOf( defaultValue ) );
return defaultValue;
}
/**
* Returns the value of the property, or the defaultValue if the
* property doesn't exist
*/
public int get( String key, int defaultValue )
{
String value = get( key );
if( value != null )
{
try
{
int stored = Integer.parseInt( value );
return stored;
}
catch( Exception e )
{
//Do nothing, we couldn't parse the stored value
}
}
if(value != null)
{
return value;
}
set( key, String.valueOf( defaultValue ) );
return defaultValue;
}
set(key, defaultValue);
return defaultValue;
}
/**
* Returns the value of the property, or the defaultValue if the
* property doesn't exist
*/
public boolean get(String key, boolean defaultValue)
{
String value = get(key);
if(value != null)
{
try
{
boolean stored = Boolean.parseBoolean(value);
return stored;
}
catch(Exception e)
{
//Do nothing, we couldn't parse the stored value
}
}
set(key, String.valueOf(defaultValue));
return defaultValue;
}
/**
* Returns the value of the property, or the defaultValue if the
* property doesn't exist
*/
public int get(String key, int defaultValue)
{
String value = get(key);
if(value != null)
{
try
{
int stored = Integer.parseInt(value);
return stored;
}
catch(Exception e)
{
//Do nothing, we couldn't parse the stored value
}
}
set(key, String.valueOf(defaultValue));
return defaultValue;
}
/**
* Sets (overrides) the property key with the new value
*/
public void set(String key, String value)
{
mProperties.setProperty(key, value);
save();
}
/**
* Gets the named color property, storing the default value in properties file if it doesn't exist.
*
* @param key identifying the color property
* @param defaultColor to use for creating the property if it doesn't exist
* @return named color
*/
public Color get(String key, Color defaultColor)
{
return new Color(get(key, defaultColor.getRGB()), true);
}
/**
* Creates a new color instance with the RGB values from color argument and translucency (alpha) argument
* @param color containing RGB values
* @param alpha desired translucency/alpha value
* @return new color with adjusted alpha value
*/
public static Color getTranslucent(Color color, int alpha)
{
return new Color(color.getRed(), color.getGreen(), color.getBlue(), alpha);
}
/**
* Sets (overrides) the property key with the new value
*/
public void set( String key, String value )
{
mProperties.setProperty( key, value );
save();
}
}

View File

@@ -135,6 +135,7 @@ public class SettingsManager implements Listener<TunerConfigurationEvent>
return setting;
}
/**
* Fetches the current setting and applies the parameter(s) to it. Creates
* the setting if it does not exist