mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-14 01:27:34 -05:00
#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:
91
src/channel/metadata/AliasedIdentifier.java
Normal file
91
src/channel/metadata/AliasedIdentifier.java
Normal 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;
|
||||
}
|
||||
}
|
||||
62
src/channel/metadata/Attribute.java
Normal file
62
src/channel/metadata/Attribute.java
Normal 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;
|
||||
}
|
||||
111
src/channel/metadata/AttributeChangeRequest.java
Normal file
111
src/channel/metadata/AttributeChangeRequest.java
Normal 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;
|
||||
}
|
||||
}
|
||||
139
src/channel/metadata/ChannelMetadataModel.java
Normal file
139
src/channel/metadata/ChannelMetadataModel.java
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
237
src/channel/metadata/ChannelMetadataPanel.java
Normal file
237
src/channel/metadata/ChannelMetadataPanel.java
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
61
src/channel/metadata/ChannelMetadataViewer.java
Normal file
61
src/channel/metadata/ChannelMetadataViewer.java
Normal 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);
|
||||
}
|
||||
}
|
||||
463
src/channel/metadata/Metadata.java
Normal file
463
src/channel/metadata/Metadata.java
Normal 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;
|
||||
}
|
||||
}
|
||||
53
src/channel/metadata/MetadataChangeEvent.java
Normal file
53
src/channel/metadata/MetadataChangeEvent.java
Normal 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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user