#90 [WIP] on redesigning the channel processing gui components and backing model. Simplifies channel state by introducing a new Metadata class that tracks all metadata for all decoders.

This commit is contained in:
Denny
2017-01-14 11:21:53 -05:00
parent 6a9e522d77
commit 7115b4feb1
57 changed files with 1534 additions and 298 deletions

View File

@@ -0,0 +1,91 @@
/*******************************************************************************
* 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;
public class AliasedIdentifier
{
private String mIdentifier;
private Alias mAlias;
/**
* Identifier and corresponding optional alias
*/
public AliasedIdentifier()
{
}
/**
* Resets alias and value to null
*/
public void reset()
{
mIdentifier = null;
mAlias = null;
}
/**
* Identifier
*/
public String getIdentifier()
{
return mIdentifier;
}
/**
* Sets the identifier to the argument value
*/
public void setIdentifier(String identifier)
{
mIdentifier = identifier;
}
/**
* Indicates if there is a non-null, non-empty identifier
*/
public boolean hasIdentifier()
{
return mIdentifier != null && !mIdentifier.isEmpty();
}
/**
* Alias for the identifier.
*/
public Alias getAlias()
{
return mAlias;
}
/**
* Sets the alias to the argument
*/
public void setAlias(Alias alias)
{
mAlias = alias;
}
/**
* Indicates if there is an alias corresponding to the identifier
*/
public boolean hasAlias()
{
return mAlias != null;
}
}

View File

@@ -0,0 +1,62 @@
/*******************************************************************************
* 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;
public enum Attribute
{
CHANNEL_CONFIGURATION_LABEL_1,
CHANNEL_CONFIGURATION_LABEL_2,
CHANNEL_FREQUENCY,
CHANNEL_ID,
CHANNEL_STATE,
MESSAGE,
MESSAGE_TYPE,
NETWORK_ID_1,
NETWORK_ID_2,
PRIMARY_ADDRESS_FROM,
PRIMARY_ADDRESS_TO,
SECONDARY_ADDRESS_FROM,
SECONDARY_ADDRESS_TO,
//TODO: remove all attributes below here ********************
CHANNEL_NUMBER,
CHANNEL_NAME,
CHANNEL_SITE_NUMBER,
CHANNEL_SITE_NUMBER_ALIAS,
DESCRIPTION,
FROM_TALKGROUP,
FROM_TALKGROUP_ALIAS,
FROM_TALKGROUP_TYPE,
NAC,
SITE,
SITE_ALIAS,
SITE_NAME,
SOURCE,
SYSTEM,
SYSTEM_NAME,
TO_TALKGROUP,
TO_TALKGROUP_ALIAS,
TO_TALKGROUP_TYPE;
}

View File

@@ -0,0 +1,111 @@
/*******************************************************************************
* 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;
public class AttributeChangeRequest<T>
{
private Attribute mAttribute;
private T mValue;
private Alias mAlias;
/**
* Request to change the value of an attribute
* @param attribute to change
* @param value to change for the attribute
* @param alias (optional) for the value
*/
public AttributeChangeRequest(Attribute attribute, T value, Alias alias)
{
mAttribute = attribute;
mValue = value;
mAlias = alias;
}
/**
* Request to change the value of an attribute
* @param attribute to change
* @param value to change for the attribute
*/
public AttributeChangeRequest(Attribute attribute, T value)
{
this(attribute, value, null);
}
/**
* Attribute to change
*/
public Attribute getAttribute()
{
return mAttribute;
}
/**
* Value to set for the attribute
*/
public T getValue()
{
return mValue;
}
/**
* Indicates if this change request has a non-null value for the attribute
*/
public boolean hasValue()
{
return mValue != null;
}
/**
* Alias for the corresponding attribute value
*/
public Alias getAlias()
{
return mAlias;
}
/**
* Indicates if this change request contains an alias that corresponds to the attribute value
*/
public boolean hasAlias()
{
return mAlias != null;
}
public String getStringValue()
{
if(mValue instanceof String)
{
return (String)mValue;
}
return null;
}
public Long getLongValue()
{
if(mValue instanceof Long)
{
return (Long)mValue;
}
return null;
}
}

View File

@@ -0,0 +1,139 @@
/*******************************************************************************
* 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 controller.channel.Channel;
import sample.Listener;
import javax.swing.table.AbstractTableModel;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ChannelMetadataModel extends AbstractTableModel implements Listener<MetadataChangeEvent>
{
public static final int COLUMN_STATE = 0;
public static final int COLUMN_PRIMARY = 1;
public static final int COLUMN_SECONDARY = 2;
public static final int COLUMN_MESSAGE = 3;
public static final int COLUMN_NETWORK = 4;
public static final int COLUMN_FREQUENCY = 5;
public static final int COLUMN_CONFIGURATION = 6;
private static final String[] COLUMNS =
{"State", "Primary", "Secondary", "Message", "Network", "Frequency", "Configuration"};
private List<Metadata> mChannelMetadata = new ArrayList();
private Map<Metadata,Channel> mMetadataChannelMap = new HashMap();
public void add(Metadata metadata, Channel channel)
{
mChannelMetadata.add(metadata);
mMetadataChannelMap.put(metadata, channel);
int index = mChannelMetadata.indexOf(metadata);
fireTableRowsInserted(index, index);
metadata.addListener(this);
}
public void remove(Metadata metadata)
{
metadata.removeListener(this);
int index = mChannelMetadata.indexOf(metadata);
mChannelMetadata.remove(metadata);
mMetadataChannelMap.remove(metadata);
fireTableRowsDeleted(index, index);
}
@Override
public int getRowCount()
{
return mChannelMetadata.size();
}
@Override
public int getColumnCount()
{
return COLUMNS.length;
}
@Override
public String getColumnName(int column)
{
return COLUMNS[column];
}
@Override
public Class<?> getColumnClass(int columnIndex)
{
return Metadata.class;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex)
{
return mChannelMetadata.get(rowIndex);
}
@Override
public void receive(MetadataChangeEvent metadataChangeEvent)
{
int rowIndex = mChannelMetadata.indexOf(metadataChangeEvent.getMetadata());
if(rowIndex >= 0)
{
switch(metadataChangeEvent.getAttribute())
{
case CHANNEL_CONFIGURATION_LABEL_1:
case CHANNEL_CONFIGURATION_LABEL_2:
fireTableCellUpdated(rowIndex, COLUMN_CONFIGURATION);
break;
case CHANNEL_FREQUENCY:
case CHANNEL_ID:
fireTableCellUpdated(rowIndex, COLUMN_FREQUENCY);
break;
case CHANNEL_STATE:
fireTableCellUpdated(rowIndex, COLUMN_STATE);
break;
case MESSAGE:
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:
case PRIMARY_ADDRESS_TO:
fireTableCellUpdated(rowIndex, COLUMN_PRIMARY);
break;
case SECONDARY_ADDRESS_FROM:
case SECONDARY_ADDRESS_TO:
fireTableCellUpdated(rowIndex, COLUMN_SECONDARY);
break;
}
}
}
}

View File

@@ -0,0 +1,237 @@
/*******************************************************************************
* 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 icon.IconTableModel;
import net.miginfocom.swing.MigLayout;
import javax.swing.*;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
import java.text.DecimalFormat;
public class ChannelMetadataPanel extends JPanel
{
private ChannelMetadataModel mChannelMetadataModel;
private IconTableModel mIconTableModel;
private JTable mTable;
public ChannelMetadataPanel(ChannelMetadataModel channelMetadataModel, IconTableModel iconTableModel)
{
mChannelMetadataModel = channelMetadataModel;
mIconTableModel = iconTableModel;
init();
}
/**
* Initializes the panel
*/
private void init()
{
setLayout( new MigLayout( "", "[grow,fill]", "[grow,fill]") );
mTable = new JTable(mChannelMetadataModel);
mTable.getColumnModel().getColumn(ChannelMetadataModel.COLUMN_STATE).setCellRenderer(new StateCellRenderer());
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_FREQUENCY)
.setCellRenderer(new FrequencyCellRenderer());
mTable.getColumnModel().getColumn(ChannelMetadataModel.COLUMN_CONFIGURATION)
.setCellRenderer(new AliasedValueCellRenderer(Attribute.CHANNEL_CONFIGURATION_LABEL_1,
Attribute.CHANNEL_CONFIGURATION_LABEL_2));
JScrollPane scrollPane = new JScrollPane(mTable, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
add(scrollPane);
}
/**
* Adds a selection listener to the contained metadata JTable
*/
public void addListSelectionListener(ListSelectionListener listener)
{
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 mLabel2;
private Attribute mAttribute1;
private Attribute mAttribute2;
public AliasedValueCellRenderer(Attribute attribute1, Attribute attribute2)
{
attribute1 = attribute1;
attribute2 = attribute2;
setLayout( new MigLayout( "", "[grow,fill]", "[grow,fill][grow,fill]") );
mLabel1 = new JLabel();
add(mLabel1,"wrap");
mLabel2 = new JLabel();
add(mLabel2,"wrap");
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column)
{
Metadata metadata = (Metadata)value;
if(mAttribute1 != null)
{
String value1 = metadata.getValue(mAttribute1);
mLabel1.setText(value1);
Alias alias1 = metadata.getAlias(mAttribute1);
if(alias1 != null)
{
mLabel1.setIcon(mIconTableModel.getIcon(alias1.getIconName()).getIcon());
mLabel1.setForeground(alias1.getDisplayColor());
}
else
{
mLabel1.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)
{
mLabel2.setIcon(mIconTableModel.getIcon(alias2.getIconName()).getIcon());
mLabel2.setForeground(alias2.getDisplayColor());
}
else
{
mLabel2.setIcon(null);
mLabel2.setForeground(mTable.getForeground());
}
}
setBackground(isSelected ? table.getSelectionBackground() : table.getBackground());
return this;
}
}
public static class FrequencyCellRenderer extends JPanel implements TableCellRenderer
{
private static final DecimalFormat FREQUENCY_FORMATTER = new DecimalFormat( "#.0000" );
private JLabel mLabel1;
private JLabel mLabel2;
public FrequencyCellRenderer()
{
setLayout( new MigLayout( "", "[grow,fill]", "[grow,fill][grow,fill]") );
mLabel1 = new JLabel();
add(mLabel1,"wrap");
mLabel2 = new JLabel();
add(mLabel2,"wrap");
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column)
{
Metadata metadata = (Metadata)value;
if(metadata.hasChannelFrequency())
{
mLabel1.setText(FREQUENCY_FORMATTER.format((double)metadata.getChannelFrequency() / 1E6d));
}
else
{
mLabel1.setText(null);
}
mLabel2.setText(metadata.getChannelID());
setBackground(isSelected ? table.getSelectionBackground() : table.getBackground());
return this;
}
}
public static class StateCellRenderer extends JPanel implements TableCellRenderer
{
private static final DecimalFormat FREQUENCY_FORMATTER = new DecimalFormat( "#.0000" );
private JLabel mLabel1;
public StateCellRenderer()
{
setLayout( new MigLayout( "", "[grow,fill,align center]", "[grow,fill,align center]") );
mLabel1 = new JLabel();
add(mLabel1);
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column)
{
Metadata metadata = (Metadata)value;
mLabel1.setText(metadata.getState().getDisplayValue());
setBackground(isSelected ? table.getSelectionBackground() : table.getBackground());
return this;
}
}
}

View File

@@ -0,0 +1,61 @@
/*******************************************************************************
* 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 com.jidesoft.swing.JideSplitPane;
import com.jidesoft.swing.JideTabbedPane;
import icon.IconTableModel;
import net.miginfocom.swing.MigLayout;
import javax.swing.*;
public class ChannelMetadataViewer extends JPanel
{
private ChannelMetadataModel mChannelMetadataModel;
private IconTableModel mIconTableModel;
/**
* GUI panel that combines the currently decoding channels metadata table and viewers for channel details,
* messages, events, and spectral view.
*/
public ChannelMetadataViewer(ChannelMetadataModel channelMetadataModel, IconTableModel iconTableModel)
{
mChannelMetadataModel = channelMetadataModel;
mIconTableModel = iconTableModel;
}
private void init()
{
setLayout( new MigLayout( "", "[grow,fill]", "[grow,fill]") );
ChannelMetadataPanel channelMetadataPanel = new ChannelMetadataPanel(mChannelMetadataModel, mIconTableModel);
JideTabbedPane tabbedPane = new JideTabbedPane();
tabbedPane.addTab("Details", new JPanel());
tabbedPane.addTab("Events", new JPanel());
tabbedPane.addTab("Messages", new JPanel());
tabbedPane.addTab("Spectrum", new JPanel());
JideSplitPane splitPane = new JideSplitPane(JideSplitPane.VERTICAL_SPLIT);
splitPane.add(channelMetadataPanel);
splitPane.add(tabbedPane);
add(splitPane);
}
}

View File

@@ -0,0 +1,463 @@
/*******************************************************************************
* 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 channel.state.State;
import sample.Broadcaster;
import sample.Listener;
public class Metadata implements Listener<AttributeChangeRequest>
{
private State mState = State.IDLE;
private String mChannelConfigurationLabel1;
private String mChannelConfigurationLabel2;
private String mChannelID;
private long mChannelFrequency;
private AliasedIdentifier mNetworkID1 = new AliasedIdentifier();
private AliasedIdentifier mNetworkID2 = new AliasedIdentifier();
//Temporal attributes
private String mMessage;
private String mMessageType;
private AliasedIdentifier mPrimaryAddressFrom = new AliasedIdentifier();
private AliasedIdentifier mPrimaryAddressTo = new AliasedIdentifier();
private AliasedIdentifier mSecondaryAddressFrom = new AliasedIdentifier();
private AliasedIdentifier mSecondaryAddressTo = new AliasedIdentifier();
private Broadcaster<MetadataChangeEvent> mMetadataChangeEventBroadcaster = new Broadcaster<>();
/**
* Channel metadata. Contains all attributes that reflect the state and current attribute values for a channel
* that is currently decoding. This metadata is intended to support any decoding channel gui components to
* graphically convey the current state of a decoding channel.
*/
public Metadata()
{
}
/**
* Sets the state of this metadata
*/
public void setState(State state)
{
mState = state;
broadcast(Attribute.CHANNEL_STATE);
}
/**
* Request to change an attribute value for this metadata. This is the primary method for updating all attributes
* in this metadata set.
*/
@Override
public void receive(AttributeChangeRequest request)
{
switch(request.getAttribute())
{
case CHANNEL_CONFIGURATION_LABEL_1:
mChannelConfigurationLabel1 = request.getStringValue();
broadcast(Attribute.CHANNEL_CONFIGURATION_LABEL_1);
break;
case CHANNEL_CONFIGURATION_LABEL_2:
mChannelConfigurationLabel2 = request.getStringValue();
broadcast(Attribute.CHANNEL_CONFIGURATION_LABEL_2);
break;
case CHANNEL_FREQUENCY:
if(request.hasValue())
{
mChannelFrequency = request.getLongValue();
}
else
{
mChannelFrequency = 0;
}
broadcast(Attribute.CHANNEL_FREQUENCY);
break;
case CHANNEL_ID:
mChannelID = request.getStringValue();
broadcast(Attribute.CHANNEL_ID);
break;
case MESSAGE:
mMessage = request.getStringValue();
broadcast(Attribute.MESSAGE);
break;
case MESSAGE_TYPE:
mMessageType = request.getStringValue();
broadcast(Attribute.MESSAGE_TYPE);
break;
case NETWORK_ID_1:
mNetworkID1.setIdentifier(request.getStringValue());
mNetworkID1.setAlias(request.getAlias());
broadcast(Attribute.NETWORK_ID_1);
break;
case NETWORK_ID_2:
mNetworkID2.setIdentifier(request.getStringValue());
mNetworkID2.setAlias(request.getAlias());
broadcast(Attribute.NETWORK_ID_2);
break;
case PRIMARY_ADDRESS_FROM:
mPrimaryAddressFrom.setIdentifier(request.getStringValue());
mPrimaryAddressFrom.setAlias(request.getAlias());
broadcast(Attribute.PRIMARY_ADDRESS_FROM);
break;
case PRIMARY_ADDRESS_TO:
mPrimaryAddressTo.setIdentifier(request.getStringValue());
mPrimaryAddressTo.setAlias(request.getAlias());
broadcast(Attribute.PRIMARY_ADDRESS_TO);
break;
case SECONDARY_ADDRESS_FROM:
mSecondaryAddressFrom.setIdentifier(request.getStringValue());
mSecondaryAddressFrom.setAlias(request.getAlias());
broadcast(Attribute.SECONDARY_ADDRESS_FROM);
break;
case SECONDARY_ADDRESS_TO:
mSecondaryAddressTo.setIdentifier(request.getStringValue());
mSecondaryAddressTo.setAlias(request.getAlias());
broadcast(Attribute.SECONDARY_ADDRESS_TO);
break;
default:
throw new IllegalArgumentException("Unrecognized Metadata Attribute: " +
request.getAttribute().name());
}
}
/**
* Broadcasts to registered listeners that an attribute has changed for this metadata
*/
private void broadcast(Attribute attribute)
{
mMetadataChangeEventBroadcaster.broadcast(new MetadataChangeEvent(this, attribute));
}
/**
* Adds the listener to receive metadata change events for this channel metadata
*/
public void addListener(Listener<MetadataChangeEvent> listener)
{
mMetadataChangeEventBroadcaster.addListener(listener);
}
/**
* Removes the listener from receiving metadata change events for this channel metadata
*/
public void removeListener(Listener<MetadataChangeEvent> listener)
{
mMetadataChangeEventBroadcaster.removeListener(listener);
}
/**
* Resets temporal attributes to null value. This only resets attributes that have a non-ull value in order to
* limit the number of change events that are produced.
*/
public void resetTemporalAttributes()
{
if(hasMessage())
{
mMessage = null;
broadcast(Attribute.MESSAGE);
}
if(hasMessageType())
{
mMessageType = null;
broadcast(Attribute.MESSAGE_TYPE);
}
if(mPrimaryAddressFrom.hasIdentifier())
{
mPrimaryAddressFrom.reset();
broadcast(Attribute.PRIMARY_ADDRESS_FROM);
}
if(mPrimaryAddressTo.hasIdentifier())
{
mPrimaryAddressTo.reset();
broadcast(Attribute.PRIMARY_ADDRESS_TO);
}
if(mSecondaryAddressFrom.hasIdentifier())
{
mSecondaryAddressFrom.reset();
broadcast(Attribute.SECONDARY_ADDRESS_FROM);
}
if(mSecondaryAddressTo.hasIdentifier())
{
mSecondaryAddressTo.reset();
broadcast(Attribute.SECONDARY_ADDRESS_TO);
}
}
/**
* Resets all attributes to empty values
*/
public void resetAllAttributes()
{
resetTemporalAttributes();
if(hasChannelConfigurationLabel1())
{
mChannelConfigurationLabel1 = null;
broadcast(Attribute.CHANNEL_CONFIGURATION_LABEL_1);
}
if(hasChannelConfigurationLabel2())
{
mChannelConfigurationLabel2 = null;
broadcast(Attribute.CHANNEL_CONFIGURATION_LABEL_2);
}
if(hasChannelID())
{
mChannelID = null;
broadcast(Attribute.CHANNEL_ID);
}
if(hasChannelFrequency())
{
mChannelFrequency = 0;
broadcast(Attribute.CHANNEL_FREQUENCY);
}
if(mNetworkID1.hasIdentifier())
{
mNetworkID1.reset();
broadcast(Attribute.NETWORK_ID_1);
}
if(mNetworkID2.hasIdentifier())
{
mNetworkID2.reset();
broadcast(Attribute.NETWORK_ID_2);
}
}
/**
* Returns the alias associated with the attribute or null
*/
public Alias getAlias(Attribute attribute)
{
switch(attribute)
{
case NETWORK_ID_1:
return getNetworkID1().getAlias();
case NETWORK_ID_2:
return getNetworkID2().getAlias();
case PRIMARY_ADDRESS_FROM:
return getPrimaryAddressFrom().getAlias();
case PRIMARY_ADDRESS_TO:
return getPrimaryAddressTo().getAlias();
case SECONDARY_ADDRESS_FROM:
return getSecondaryAddressFrom().getAlias();
case SECONDARY_ADDRESS_TO:
return getSecondaryAddressTo().getAlias();
}
return null;
}
/**
* Returns the string value for the specified attribute or null
*/
public String getValue(Attribute attribute)
{
switch(attribute)
{
case CHANNEL_CONFIGURATION_LABEL_1:
return mChannelConfigurationLabel1;
case CHANNEL_CONFIGURATION_LABEL_2:
return mChannelConfigurationLabel2;
case CHANNEL_ID:
return mChannelID;
case CHANNEL_STATE:
return mState.getDisplayValue();
case MESSAGE:
return mMessage;
case MESSAGE_TYPE:
return mMessageType;
case NETWORK_ID_1:
return mNetworkID1.getIdentifier();
case NETWORK_ID_2:
return mNetworkID2.getIdentifier();
case PRIMARY_ADDRESS_FROM:
return mPrimaryAddressFrom.getIdentifier();
case PRIMARY_ADDRESS_TO:
return mPrimaryAddressTo.getIdentifier();
case SECONDARY_ADDRESS_FROM:
return mSecondaryAddressFrom.getIdentifier();
case SECONDARY_ADDRESS_TO:
return mPrimaryAddressTo.getIdentifier();
}
return null;
}
/**
* Current channel state
*/
public State getState()
{
return mState;
}
/**
* System name from the channel configuration
*/
public String getChannelConfigurationLabel1()
{
return mChannelConfigurationLabel1;
}
/**
* Indicates if there is a non-null, non-empty channel configuration system value
*/
public boolean hasChannelConfigurationLabel1()
{
return mChannelConfigurationLabel1 != null && !mChannelConfigurationLabel1.isEmpty();
}
/**
* Site name from the channel configuration
*/
public String getChannelConfigurationLabel2()
{
return mChannelConfigurationLabel2;
}
/**
* Indicates if there is a non-null, non-empty channel configuration site value
*/
public boolean hasChannelConfigurationLabel2()
{
return mChannelConfigurationLabel2 != null && !mChannelConfigurationLabel2.isEmpty();
}
/**
* Channel ID or Channel Number
*/
public String getChannelID()
{
return mChannelID;
}
/**
* Indicates if there is a non-null, non-empty channel identifier value
*/
public boolean hasChannelID()
{
return mChannelID != null && !mChannelID.isEmpty();
}
/**
* Channel frequency
*/
public long getChannelFrequency()
{
return mChannelFrequency;
}
/**
* Indicates if there is a non-zero channel frequency value
*/
public boolean hasChannelFrequency()
{
return mChannelFrequency > 0;
}
/**
* Network Identifier 1
*/
public AliasedIdentifier getNetworkID1()
{
return mNetworkID1;
}
/**
* Network Identifier 2
*/
public AliasedIdentifier getNetworkID2()
{
return mNetworkID2;
}
/**
* Message
*/
public String getMessage()
{
return mMessage;
}
/**
* Indicates if there is a non-null, non-empty message value
*/
public boolean hasMessage()
{
return mMessage != null && !mMessage.isEmpty();
}
/**
* Message and Decoder type
*/
public String getMessageType()
{
return mMessageType;
}
/**
* Indicates if there is a non-null, non-empty message and decoder type value
*/
public boolean hasMessageType()
{
return mMessageType != null && !mMessageType.isEmpty();
}
/**
* Primary FROM Address
*/
public AliasedIdentifier getPrimaryAddressFrom()
{
return mPrimaryAddressFrom;
}
/**
* Primary TO Address
*/
public AliasedIdentifier getPrimaryAddressTo()
{
return mPrimaryAddressTo;
}
/**
* Secondary FROM Address
*/
public AliasedIdentifier getSecondaryAddressFrom()
{
return mSecondaryAddressFrom;
}
/**
* Secondary TO Address
*/
public AliasedIdentifier getSecondaryAddressTo()
{
return mSecondaryAddressTo;
}
}

View File

@@ -0,0 +1,53 @@
/*******************************************************************************
* 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;
public class MetadataChangeEvent
{
private Metadata mMetadata;
private Attribute mAttribute;
/**
* Channel metadata changed attribute event
*
* @param metadata where the change occurred
* @param attribute that changed
*/
public MetadataChangeEvent(Metadata metadata, Attribute attribute)
{
mMetadata = metadata;
mAttribute = attribute;
}
/**
* Channel metadata where the change occurred
*/
public Metadata getMetadata()
{
return mMetadata;
}
/**
* Channel metadata attribute that has changed
*/
public Attribute getAttribute()
{
return mAttribute;
}
}