mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-14 01:27:34 -05:00
#90 [WIP] GUI is functioning again and the new channels table is showing calls and the audio panel is now horizontal. Lots of gui tweaks still to do.
This commit is contained in:
@@ -23,6 +23,8 @@ import audio.output.AudioOutput;
|
|||||||
import channel.metadata.Metadata;
|
import channel.metadata.Metadata;
|
||||||
import icon.IconManager;
|
import icon.IconManager;
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import sample.Listener;
|
import sample.Listener;
|
||||||
import settings.ColorSetting;
|
import settings.ColorSetting;
|
||||||
import settings.ColorSetting.ColorSettingName;
|
import settings.ColorSetting.ColorSettingName;
|
||||||
@@ -37,8 +39,9 @@ public class AudioChannelPanel extends JPanel
|
|||||||
implements Listener<AudioEvent>, SettingChangeListener
|
implements Listener<AudioEvent>, SettingChangeListener
|
||||||
{
|
{
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
private static final Logger mLog = LoggerFactory.getLogger(AudioChannelPanel.class);
|
||||||
|
|
||||||
private Font mFont = new Font(Font.MONOSPACED, Font.PLAIN, 12);
|
private Font mFont = new Font(Font.MONOSPACED, Font.PLAIN, 16);
|
||||||
private Color mLabelColor;
|
private Color mLabelColor;
|
||||||
private Color mDetailsColor;
|
private Color mDetailsColor;
|
||||||
|
|
||||||
@@ -49,12 +52,12 @@ public class AudioChannelPanel extends JPanel
|
|||||||
private JLabel mChannelName = new JLabel(" ");
|
private JLabel mChannelName = new JLabel(" ");
|
||||||
private JLabel mToLabel = new JLabel("TO:");
|
private JLabel mToLabel = new JLabel("TO:");
|
||||||
private JLabel mTo = new JLabel("-----");
|
private JLabel mTo = new JLabel("-----");
|
||||||
private JLabel mToAlias = new JLabel("");
|
private JLabel mToAlias = new JLabel(" ");
|
||||||
|
|
||||||
private JLabel mMutedLabel = new JLabel(" ");
|
private JLabel mMutedLabel = new JLabel("MUTED");
|
||||||
private JLabel mFromLabel = new JLabel("FROM:");
|
private JLabel mFromLabel = new JLabel("FROM:");
|
||||||
private JLabel mFrom = new JLabel("-----");
|
private JLabel mFrom = new JLabel("-----");
|
||||||
private JLabel mFromAlias = new JLabel("");
|
private JLabel mFromAlias = new JLabel(" ");
|
||||||
|
|
||||||
private boolean mConfigured = false;
|
private boolean mConfigured = false;
|
||||||
|
|
||||||
@@ -82,9 +85,15 @@ public class AudioChannelPanel extends JPanel
|
|||||||
|
|
||||||
private void init()
|
private void init()
|
||||||
{
|
{
|
||||||
setLayout(new MigLayout("insets 0 0 0 0", "[][right][][grow,fill]", "[]0[]0[grow,fill]"));
|
setLayout(new MigLayout("align center center, insets 0 0 0 0",
|
||||||
|
"[][][right][grow,fill][grow,fill][right][grow,fill][grow,fill]", ""));
|
||||||
setBackground(Color.BLACK);
|
setBackground(Color.BLACK);
|
||||||
|
|
||||||
|
mMutedLabel.setFont(mFont);
|
||||||
|
mMutedLabel.setForeground(Color.RED);
|
||||||
|
mMutedLabel.setVisible(false);
|
||||||
|
add(mMutedLabel);
|
||||||
|
|
||||||
mChannelName = new JLabel(mAudioOutput != null ? mAudioOutput.getChannelName() : " ");
|
mChannelName = new JLabel(mAudioOutput != null ? mAudioOutput.getChannelName() : " ");
|
||||||
mChannelName.setFont(mFont);
|
mChannelName.setFont(mFont);
|
||||||
mChannelName.setForeground(mDetailsColor);
|
mChannelName.setForeground(mDetailsColor);
|
||||||
@@ -107,11 +116,7 @@ public class AudioChannelPanel extends JPanel
|
|||||||
|
|
||||||
mToAlias.setFont(mFont);
|
mToAlias.setFont(mFont);
|
||||||
mToAlias.setForeground(mLabelColor);
|
mToAlias.setForeground(mLabelColor);
|
||||||
add(mToAlias, "wrap");
|
add(mToAlias);
|
||||||
|
|
||||||
mMutedLabel.setFont(mFont);
|
|
||||||
mMutedLabel.setForeground(Color.RED);
|
|
||||||
add(mMutedLabel);
|
|
||||||
|
|
||||||
mFromLabel.setFont(mFont);
|
mFromLabel.setFont(mFont);
|
||||||
if(mAudioOutput != null)
|
if(mAudioOutput != null)
|
||||||
@@ -130,8 +135,7 @@ public class AudioChannelPanel extends JPanel
|
|||||||
|
|
||||||
mFromAlias.setFont(mFont);
|
mFromAlias.setFont(mFont);
|
||||||
mFromAlias.setForeground(mLabelColor);
|
mFromAlias.setForeground(mLabelColor);
|
||||||
add(mFromAlias, "wrap");
|
add(mFromAlias);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -156,7 +160,7 @@ public class AudioChannelPanel extends JPanel
|
|||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
mMutedLabel.setText(mAudioOutput.isMuted() ? "M" : " ");
|
mMutedLabel.setVisible(mAudioOutput.isMuted());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
@@ -171,8 +175,8 @@ public class AudioChannelPanel extends JPanel
|
|||||||
*/
|
*/
|
||||||
private void resetLabels()
|
private void resetLabels()
|
||||||
{
|
{
|
||||||
updateLabel(mFromLabel, null, mFromAlias, null);
|
updateLabel(mFrom, null, mFromAlias, null);
|
||||||
updateLabel(mToLabel, null, mToAlias, null);
|
updateLabel(mTo, null, mToAlias, null);
|
||||||
|
|
||||||
mConfigured = false;
|
mConfigured = false;
|
||||||
}
|
}
|
||||||
@@ -190,7 +194,7 @@ public class AudioChannelPanel extends JPanel
|
|||||||
|
|
||||||
if(alias != null)
|
if(alias != null)
|
||||||
{
|
{
|
||||||
aliasLabel.setIcon(mIconManager.getIcon(alias.getIconName(), IconManager.DEFAULT_ICON_SIZE));
|
aliasLabel.setIcon(mIconManager.getIcon(alias.getIconName(), 16));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -220,10 +224,10 @@ public class AudioChannelPanel extends JPanel
|
|||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
updateLabel(mFromLabel, metadata.getPrimaryAddressFrom().getIdentifier(),
|
updateLabel(mFrom, metadata.getPrimaryAddressFrom().getIdentifier(),
|
||||||
mFromAlias, metadata.getPrimaryAddressFrom().getAlias());
|
mFromAlias, metadata.getPrimaryAddressFrom().getAlias());
|
||||||
|
|
||||||
updateLabel(mToLabel, metadata.getPrimaryAddressTo().getIdentifier(),
|
updateLabel(mTo, metadata.getPrimaryAddressTo().getIdentifier(),
|
||||||
mToAlias, metadata.getPrimaryAddressTo().getAlias());
|
mToAlias, metadata.getPrimaryAddressTo().getAlias());
|
||||||
|
|
||||||
mConfigured = true;
|
mConfigured = true;
|
||||||
|
|||||||
@@ -33,15 +33,17 @@ public class AudioChannelsPanel extends JPanel
|
|||||||
|
|
||||||
public AudioChannelsPanel(IconManager iconManager, SettingsManager settingsManager, IAudioController controller)
|
public AudioChannelsPanel(IconManager iconManager, SettingsManager settingsManager, IAudioController controller)
|
||||||
{
|
{
|
||||||
setLayout(new MigLayout("insets 0 0 0 0", "[grow,fill]", "[]0[]"));
|
setLayout(new MigLayout("insets 0 0 0 0", "[][grow,fill][][grow,fill]", "[grow,fill]"));
|
||||||
|
|
||||||
setBackground(Color.BLACK);
|
setBackground(Color.BLACK);
|
||||||
|
|
||||||
List<AudioOutput> outputs = controller.getAudioOutputs();
|
List<AudioOutput> outputs = controller.getAudioOutputs();
|
||||||
|
|
||||||
|
addSeparator();
|
||||||
|
|
||||||
for(int x = 0; x < outputs.size(); x++)
|
for(int x = 0; x < outputs.size(); x++)
|
||||||
{
|
{
|
||||||
add(new AudioChannelPanel(iconManager, settingsManager, outputs.get(x)), "wrap");
|
add(new AudioChannelPanel(iconManager, settingsManager, outputs.get(x)), "growx");
|
||||||
|
|
||||||
if(x < outputs.size() - 1)
|
if(x < outputs.size() - 1)
|
||||||
{
|
{
|
||||||
@@ -54,14 +56,14 @@ public class AudioChannelsPanel extends JPanel
|
|||||||
if(outputs.size() == 1)
|
if(outputs.size() == 1)
|
||||||
{
|
{
|
||||||
addSeparator();
|
addSeparator();
|
||||||
add(new AudioChannelPanel(iconManager, settingsManager, null), "wrap");
|
add(new AudioChannelPanel(iconManager, settingsManager, null), "growx");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addSeparator()
|
private void addSeparator()
|
||||||
{
|
{
|
||||||
JSeparator separator = new JSeparator(JSeparator.HORIZONTAL);
|
JSeparator separator = new JSeparator(JSeparator.VERTICAL);
|
||||||
separator.setBackground(Color.DARK_GRAY);
|
separator.setBackground(Color.DARK_GRAY);
|
||||||
add(separator, "span,growx");
|
add(separator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,9 +45,9 @@ public class AudioPanel extends JPanel implements Listener<AudioEvent>
|
|||||||
private static final Logger mLog = LoggerFactory.getLogger(AudioPanel.class);
|
private static final Logger mLog = LoggerFactory.getLogger(AudioPanel.class);
|
||||||
|
|
||||||
private static ImageIcon MUTED_ICON = IconManager.getScaledIcon(
|
private static ImageIcon MUTED_ICON = IconManager.getScaledIcon(
|
||||||
new ImageIcon("images/audio_muted.png"), 38);
|
new ImageIcon("images/audio_muted.png"), 20);
|
||||||
private static ImageIcon UNMUTED_ICON = IconManager.getScaledIcon(
|
private static ImageIcon UNMUTED_ICON = IconManager.getScaledIcon(
|
||||||
new ImageIcon("images/audio_unmuted.png"), 38);
|
new ImageIcon("images/audio_unmuted.png"), 20);
|
||||||
|
|
||||||
private IconManager mIconManager;
|
private IconManager mIconManager;
|
||||||
private SettingsManager mSettingsManager;
|
private SettingsManager mSettingsManager;
|
||||||
|
|||||||
@@ -100,7 +100,11 @@ public class AliasedIdentifier
|
|||||||
AliasedIdentifier copy = new AliasedIdentifier();
|
AliasedIdentifier copy = new AliasedIdentifier();
|
||||||
|
|
||||||
copy.setAlias(mAlias);
|
copy.setAlias(mAlias);
|
||||||
copy.setIdentifier(new String(mIdentifier));
|
|
||||||
|
if(mIdentifier != null)
|
||||||
|
{
|
||||||
|
copy.setIdentifier(new String(mIdentifier));
|
||||||
|
}
|
||||||
|
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import controller.channel.Channel;
|
|||||||
import sample.Listener;
|
import sample.Listener;
|
||||||
|
|
||||||
import javax.swing.table.AbstractTableModel;
|
import javax.swing.table.AbstractTableModel;
|
||||||
|
import java.awt.*;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -30,41 +31,55 @@ import java.util.Map;
|
|||||||
public class ChannelMetadataModel extends AbstractTableModel implements Listener<MutableMetadataChangeEvent>
|
public class ChannelMetadataModel extends AbstractTableModel implements Listener<MutableMetadataChangeEvent>
|
||||||
{
|
{
|
||||||
public static final int COLUMN_STATE = 0;
|
public static final int COLUMN_STATE = 0;
|
||||||
public static final int COLUMN_PRIMARY = 1;
|
public static final int COLUMN_FREQUENCY = 1;
|
||||||
public static final int COLUMN_SECONDARY = 2;
|
public static final int COLUMN_PRIMARY = 2;
|
||||||
public static final int COLUMN_MESSAGE = 3;
|
public static final int COLUMN_SECONDARY = 3;
|
||||||
public static final int COLUMN_NETWORK = 4;
|
public static final int COLUMN_MESSAGE = 4;
|
||||||
public static final int COLUMN_FREQUENCY = 5;
|
public static final int COLUMN_NETWORK = 5;
|
||||||
public static final int COLUMN_CONFIGURATION = 6;
|
public static final int COLUMN_CONFIGURATION = 6;
|
||||||
|
|
||||||
private static final String[] COLUMNS =
|
private static final String[] COLUMNS =
|
||||||
{"State", "Primary", "Secondary", "Message", "Network", "Frequency", "Configuration"};
|
{"State", "Frequency", "Primary", "Secondary", "Message", "Network", "Configuration"};
|
||||||
|
|
||||||
private List<MutableMetadata> mChannelMetadata = new ArrayList();
|
private List<MutableMetadata> mChannelMetadata = new ArrayList();
|
||||||
private Map<MutableMetadata,Channel> mMetadataChannelMap = new HashMap();
|
private Map<MutableMetadata,Channel> mMetadataChannelMap = new HashMap();
|
||||||
|
|
||||||
public void add(MutableMetadata metadata, Channel channel)
|
public void add(MutableMetadata metadata, Channel channel)
|
||||||
{
|
{
|
||||||
mChannelMetadata.add(metadata);
|
EventQueue.invokeLater(new Runnable()
|
||||||
mMetadataChannelMap.put(metadata, channel);
|
{
|
||||||
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
mChannelMetadata.add(metadata);
|
||||||
|
mMetadataChannelMap.put(metadata, channel);
|
||||||
|
|
||||||
int index = mChannelMetadata.indexOf(metadata);
|
int index = mChannelMetadata.indexOf(metadata);
|
||||||
|
|
||||||
fireTableRowsInserted(index, index);
|
fireTableRowsInserted(index, index);
|
||||||
|
|
||||||
metadata.addListener(this);
|
metadata.addListener(ChannelMetadataModel.this);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void remove(MutableMetadata metadata)
|
public void remove(MutableMetadata metadata)
|
||||||
{
|
{
|
||||||
metadata.removeListener(this);
|
EventQueue.invokeLater(new Runnable()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
metadata.removeListener(ChannelMetadataModel.this);
|
||||||
|
|
||||||
int index = mChannelMetadata.indexOf(metadata);
|
int index = mChannelMetadata.indexOf(metadata);
|
||||||
|
|
||||||
mChannelMetadata.remove(metadata);
|
mChannelMetadata.remove(metadata);
|
||||||
mMetadataChannelMap.remove(metadata);
|
mMetadataChannelMap.remove(metadata);
|
||||||
|
|
||||||
fireTableRowsDeleted(index, index);
|
fireTableRowsDeleted(index, index);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -94,46 +109,58 @@ public class ChannelMetadataModel extends AbstractTableModel implements Listener
|
|||||||
@Override
|
@Override
|
||||||
public Object getValueAt(int rowIndex, int columnIndex)
|
public Object getValueAt(int rowIndex, int columnIndex)
|
||||||
{
|
{
|
||||||
return mChannelMetadata.get(rowIndex);
|
if(rowIndex <= mChannelMetadata.size())
|
||||||
|
{
|
||||||
|
return mChannelMetadata.get(rowIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void receive(MutableMetadataChangeEvent mutableMetadataChangeEvent)
|
public void receive(MutableMetadataChangeEvent mutableMetadataChangeEvent)
|
||||||
{
|
{
|
||||||
int rowIndex = mChannelMetadata.indexOf(mutableMetadataChangeEvent.getMetadata());
|
EventQueue.invokeLater(new Runnable()
|
||||||
|
|
||||||
if(rowIndex >= 0)
|
|
||||||
{
|
{
|
||||||
switch(mutableMetadataChangeEvent.getAttribute())
|
@Override
|
||||||
|
public void run()
|
||||||
{
|
{
|
||||||
case CHANNEL_CONFIGURATION_LABEL_1:
|
int rowIndex = mChannelMetadata.indexOf(mutableMetadataChangeEvent.getMetadata());
|
||||||
case CHANNEL_CONFIGURATION_LABEL_2:
|
|
||||||
fireTableCellUpdated(rowIndex, COLUMN_CONFIGURATION);
|
if(rowIndex >= 0)
|
||||||
break;
|
{
|
||||||
case CHANNEL_FREQUENCY:
|
switch(mutableMetadataChangeEvent.getAttribute())
|
||||||
case CHANNEL_FREQUENCY_LABEL:
|
{
|
||||||
fireTableCellUpdated(rowIndex, COLUMN_FREQUENCY);
|
case CHANNEL_CONFIGURATION_LABEL_1:
|
||||||
break;
|
case CHANNEL_CONFIGURATION_LABEL_2:
|
||||||
case CHANNEL_STATE:
|
fireTableCellUpdated(rowIndex, COLUMN_CONFIGURATION);
|
||||||
fireTableCellUpdated(rowIndex, COLUMN_STATE);
|
break;
|
||||||
break;
|
case CHANNEL_FREQUENCY:
|
||||||
case MESSAGE:
|
case CHANNEL_FREQUENCY_LABEL:
|
||||||
case MESSAGE_TYPE:
|
fireTableCellUpdated(rowIndex, COLUMN_FREQUENCY);
|
||||||
fireTableCellUpdated(rowIndex, COLUMN_MESSAGE);
|
break;
|
||||||
break;
|
case CHANNEL_STATE:
|
||||||
case NETWORK_ID_1:
|
fireTableCellUpdated(rowIndex, COLUMN_STATE);
|
||||||
case NETWORK_ID_2:
|
break;
|
||||||
fireTableCellUpdated(rowIndex, COLUMN_NETWORK);
|
case MESSAGE:
|
||||||
break;
|
case MESSAGE_TYPE:
|
||||||
case PRIMARY_ADDRESS_FROM:
|
fireTableCellUpdated(rowIndex, COLUMN_MESSAGE);
|
||||||
case PRIMARY_ADDRESS_TO:
|
break;
|
||||||
fireTableCellUpdated(rowIndex, COLUMN_PRIMARY);
|
case NETWORK_ID_1:
|
||||||
break;
|
case NETWORK_ID_2:
|
||||||
case SECONDARY_ADDRESS_FROM:
|
fireTableCellUpdated(rowIndex, COLUMN_NETWORK);
|
||||||
case SECONDARY_ADDRESS_TO:
|
break;
|
||||||
fireTableCellUpdated(rowIndex, COLUMN_SECONDARY);
|
case PRIMARY_ADDRESS_FROM:
|
||||||
break;
|
case PRIMARY_ADDRESS_TO:
|
||||||
|
fireTableCellUpdated(rowIndex, COLUMN_PRIMARY);
|
||||||
|
break;
|
||||||
|
case SECONDARY_ADDRESS_FROM:
|
||||||
|
case SECONDARY_ADDRESS_TO:
|
||||||
|
fireTableCellUpdated(rowIndex, COLUMN_SECONDARY);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
package channel.metadata;
|
package channel.metadata;
|
||||||
|
|
||||||
import alias.Alias;
|
import alias.Alias;
|
||||||
|
import icon.IconManager;
|
||||||
import icon.IconTableModel;
|
import icon.IconTableModel;
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
|
|
||||||
@@ -31,13 +32,13 @@ import java.text.DecimalFormat;
|
|||||||
public class ChannelMetadataPanel extends JPanel
|
public class ChannelMetadataPanel extends JPanel
|
||||||
{
|
{
|
||||||
private ChannelMetadataModel mChannelMetadataModel;
|
private ChannelMetadataModel mChannelMetadataModel;
|
||||||
private IconTableModel mIconTableModel;
|
private IconManager mIconManager;
|
||||||
private JTable mTable;
|
private JTable mTable;
|
||||||
|
|
||||||
public ChannelMetadataPanel(ChannelMetadataModel channelMetadataModel, IconTableModel iconTableModel)
|
public ChannelMetadataPanel(ChannelMetadataModel channelMetadataModel, IconManager iconManager)
|
||||||
{
|
{
|
||||||
mChannelMetadataModel = channelMetadataModel;
|
mChannelMetadataModel = channelMetadataModel;
|
||||||
mIconTableModel = iconTableModel;
|
mIconManager = iconManager;
|
||||||
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
@@ -47,12 +48,16 @@ public class ChannelMetadataPanel extends JPanel
|
|||||||
*/
|
*/
|
||||||
private void init()
|
private void init()
|
||||||
{
|
{
|
||||||
setLayout( new MigLayout( "", "[grow,fill]", "[grow,fill]") );
|
setLayout( new MigLayout( "insets 0 0 0 0", "[grow,fill]", "[grow,fill]") );
|
||||||
|
|
||||||
mTable = new JTable(mChannelMetadataModel);
|
mTable = new JTable(mChannelMetadataModel);
|
||||||
|
mTable.setRowHeight(35);
|
||||||
|
|
||||||
mTable.getColumnModel().getColumn(ChannelMetadataModel.COLUMN_STATE).setCellRenderer(new StateCellRenderer());
|
mTable.getColumnModel().getColumn(ChannelMetadataModel.COLUMN_STATE).setCellRenderer(new StateCellRenderer());
|
||||||
|
|
||||||
|
mTable.getColumnModel().getColumn(ChannelMetadataModel.COLUMN_FREQUENCY)
|
||||||
|
.setCellRenderer(new FrequencyCellRenderer());
|
||||||
|
|
||||||
mTable.getColumnModel().getColumn(ChannelMetadataModel.COLUMN_PRIMARY)
|
mTable.getColumnModel().getColumn(ChannelMetadataModel.COLUMN_PRIMARY)
|
||||||
.setCellRenderer(new AliasedValueCellRenderer(Attribute.PRIMARY_ADDRESS_TO, Attribute.PRIMARY_ADDRESS_FROM));
|
.setCellRenderer(new AliasedValueCellRenderer(Attribute.PRIMARY_ADDRESS_TO, Attribute.PRIMARY_ADDRESS_FROM));
|
||||||
|
|
||||||
@@ -65,9 +70,6 @@ public class ChannelMetadataPanel extends JPanel
|
|||||||
mTable.getColumnModel().getColumn(ChannelMetadataModel.COLUMN_NETWORK)
|
mTable.getColumnModel().getColumn(ChannelMetadataModel.COLUMN_NETWORK)
|
||||||
.setCellRenderer(new AliasedValueCellRenderer(Attribute.NETWORK_ID_1, Attribute.NETWORK_ID_2));
|
.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)
|
mTable.getColumnModel().getColumn(ChannelMetadataModel.COLUMN_CONFIGURATION)
|
||||||
.setCellRenderer(new AliasedValueCellRenderer(Attribute.CHANNEL_CONFIGURATION_LABEL_1,
|
.setCellRenderer(new AliasedValueCellRenderer(Attribute.CHANNEL_CONFIGURATION_LABEL_1,
|
||||||
Attribute.CHANNEL_CONFIGURATION_LABEL_2));
|
Attribute.CHANNEL_CONFIGURATION_LABEL_2));
|
||||||
@@ -76,6 +78,7 @@ public class ChannelMetadataPanel extends JPanel
|
|||||||
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
||||||
|
|
||||||
add(scrollPane);
|
add(scrollPane);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -97,21 +100,29 @@ public class ChannelMetadataPanel extends JPanel
|
|||||||
public class AliasedValueCellRenderer extends JPanel implements TableCellRenderer
|
public class AliasedValueCellRenderer extends JPanel implements TableCellRenderer
|
||||||
{
|
{
|
||||||
private JLabel mLabel1;
|
private JLabel mLabel1;
|
||||||
|
private JLabel mAlias1;
|
||||||
private JLabel mLabel2;
|
private JLabel mLabel2;
|
||||||
|
private JLabel mAlias2;
|
||||||
|
|
||||||
private Attribute mAttribute1;
|
private Attribute mAttribute1;
|
||||||
private Attribute mAttribute2;
|
private Attribute mAttribute2;
|
||||||
|
|
||||||
public AliasedValueCellRenderer(Attribute attribute1, Attribute attribute2)
|
public AliasedValueCellRenderer(Attribute attribute1, Attribute attribute2)
|
||||||
{
|
{
|
||||||
attribute1 = attribute1;
|
mAttribute1 = attribute1;
|
||||||
attribute2 = attribute2;
|
mAttribute2 = attribute2;
|
||||||
|
|
||||||
setLayout( new MigLayout( "", "[grow,fill]", "[grow,fill][grow,fill]") );
|
setLayout( new MigLayout( "insets 0 0 0 0", "[12][grow,fill]", "[grow,fill]0[grow,fill]") );
|
||||||
|
|
||||||
mLabel1 = new JLabel();
|
mAlias1 = new JLabel();
|
||||||
|
add(mAlias1);
|
||||||
|
mLabel1 = new JLabel("---");
|
||||||
|
mLabel1.setFont(mTable.getFont());
|
||||||
add(mLabel1,"wrap");
|
add(mLabel1,"wrap");
|
||||||
mLabel2 = new JLabel();
|
mAlias2 = new JLabel();
|
||||||
|
add(mAlias2);
|
||||||
|
mLabel2 = new JLabel("---");
|
||||||
|
mLabel2.setFont(mTable.getFont());
|
||||||
add(mLabel2,"wrap");
|
add(mLabel2,"wrap");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,12 +141,12 @@ public class ChannelMetadataPanel extends JPanel
|
|||||||
|
|
||||||
if(alias1 != null)
|
if(alias1 != null)
|
||||||
{
|
{
|
||||||
mLabel1.setIcon(mIconTableModel.getIcon(alias1.getIconName()).getIcon());
|
mAlias1.setIcon(mIconManager.getIcon(alias1.getIconName(), IconManager.DEFAULT_ICON_SIZE));
|
||||||
mLabel1.setForeground(alias1.getDisplayColor());
|
mLabel1.setForeground(alias1.getDisplayColor());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mLabel1.setIcon(null);
|
mAlias1.setIcon(null);
|
||||||
mLabel1.setForeground(mTable.getForeground());
|
mLabel1.setForeground(mTable.getForeground());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -149,12 +160,12 @@ public class ChannelMetadataPanel extends JPanel
|
|||||||
|
|
||||||
if(alias2 != null)
|
if(alias2 != null)
|
||||||
{
|
{
|
||||||
mLabel2.setIcon(mIconTableModel.getIcon(alias2.getIconName()).getIcon());
|
mAlias2.setIcon(mIconManager.getIcon(alias2.getIconName(), IconManager.DEFAULT_ICON_SIZE));
|
||||||
mLabel2.setForeground(alias2.getDisplayColor());
|
mLabel2.setForeground(alias2.getDisplayColor());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mLabel2.setIcon(null);
|
mAlias2.setIcon(null);
|
||||||
mLabel2.setForeground(mTable.getForeground());
|
mLabel2.setForeground(mTable.getForeground());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -165,21 +176,23 @@ public class ChannelMetadataPanel extends JPanel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class FrequencyCellRenderer extends JPanel implements TableCellRenderer
|
public class FrequencyCellRenderer extends JPanel implements TableCellRenderer
|
||||||
{
|
{
|
||||||
private static final DecimalFormat FREQUENCY_FORMATTER = new DecimalFormat( "#.0000" );
|
private final DecimalFormat FREQUENCY_FORMATTER = new DecimalFormat( "#.000000" );
|
||||||
|
|
||||||
private JLabel mLabel1;
|
private JLabel mLabel1;
|
||||||
private JLabel mLabel2;
|
private JLabel mLabel2;
|
||||||
|
|
||||||
public FrequencyCellRenderer()
|
public FrequencyCellRenderer()
|
||||||
{
|
{
|
||||||
setLayout( new MigLayout( "", "[grow,fill]", "[grow,fill][grow,fill]") );
|
setLayout( new MigLayout( "insets 0 0 0 0", "[grow,fill,align center]", "[grow,fill]0[grow,fill]") );
|
||||||
|
|
||||||
mLabel1 = new JLabel();
|
mLabel1 = new JLabel();
|
||||||
|
mLabel1.setFont(mTable.getFont());
|
||||||
add(mLabel1,"wrap");
|
add(mLabel1,"wrap");
|
||||||
mLabel2 = new JLabel();
|
mLabel2 = new JLabel();
|
||||||
add(mLabel2,"wrap");
|
mLabel2.setFont(mTable.getFont());
|
||||||
|
add(mLabel2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -205,17 +218,16 @@ public class ChannelMetadataPanel extends JPanel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class StateCellRenderer extends JPanel implements TableCellRenderer
|
public class StateCellRenderer extends JPanel implements TableCellRenderer
|
||||||
{
|
{
|
||||||
private static final DecimalFormat FREQUENCY_FORMATTER = new DecimalFormat( "#.0000" );
|
|
||||||
|
|
||||||
private JLabel mLabel1;
|
private JLabel mLabel1;
|
||||||
|
|
||||||
public StateCellRenderer()
|
public StateCellRenderer()
|
||||||
{
|
{
|
||||||
setLayout( new MigLayout( "", "[grow,fill,align center]", "[grow,fill,align center]") );
|
setLayout( new MigLayout( "insets 0 0 0 0", "[grow,fill,align center]", "[grow,fill,align center]") );
|
||||||
|
|
||||||
mLabel1 = new JLabel();
|
mLabel1 = new JLabel();
|
||||||
|
mLabel1.setFont(mTable.getFont());
|
||||||
add(mLabel1);
|
add(mLabel1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,12 +49,14 @@ public class ChannelMetadataViewer extends JPanel
|
|||||||
mMessageActivityPanel = new MessageActivityPanel(channelProcessingManager);
|
mMessageActivityPanel = new MessageActivityPanel(channelProcessingManager);
|
||||||
mChannelSpectrumPanel = new ChannelSpectrumPanel(settingsManager, channelProcessingManager);
|
mChannelSpectrumPanel = new ChannelSpectrumPanel(settingsManager, channelProcessingManager);
|
||||||
mChannelMetadataPanel = new ChannelMetadataPanel(channelProcessingManager.getChannelMetadataModel(),
|
mChannelMetadataPanel = new ChannelMetadataPanel(channelProcessingManager.getChannelMetadataModel(),
|
||||||
iconManager.getModel());
|
iconManager);
|
||||||
|
|
||||||
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void init()
|
private void init()
|
||||||
{
|
{
|
||||||
setLayout( new MigLayout( "", "[grow,fill]", "[grow,fill]") );
|
setLayout( new MigLayout( "insets 0 0 0 0", "[grow,fill]", "[grow,fill]") );
|
||||||
|
|
||||||
JideTabbedPane tabbedPane = new JideTabbedPane();
|
JideTabbedPane tabbedPane = new JideTabbedPane();
|
||||||
tabbedPane.addTab("Details", new JPanel());
|
tabbedPane.addTab("Details", new JPanel());
|
||||||
@@ -65,6 +67,7 @@ public class ChannelMetadataViewer extends JPanel
|
|||||||
JideSplitPane splitPane = new JideSplitPane(JideSplitPane.VERTICAL_SPLIT);
|
JideSplitPane splitPane = new JideSplitPane(JideSplitPane.VERTICAL_SPLIT);
|
||||||
splitPane.add(mChannelMetadataPanel);
|
splitPane.add(mChannelMetadataPanel);
|
||||||
splitPane.add(tabbedPane);
|
splitPane.add(tabbedPane);
|
||||||
|
add(splitPane);
|
||||||
|
|
||||||
//TODO: move this change listener to the metadata table view
|
//TODO: move this change listener to the metadata table view
|
||||||
// /**
|
// /**
|
||||||
@@ -100,6 +103,5 @@ public class ChannelMetadataViewer extends JPanel
|
|||||||
// mChannelModel.addListener(mChannelSpectrumPanel);
|
// mChannelModel.addListener(mChannelSpectrumPanel);
|
||||||
// mChannelModel.addListener(mMessageActivityPanel);
|
// mChannelModel.addListener(mMessageActivityPanel);
|
||||||
|
|
||||||
add(splitPane);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -256,7 +256,7 @@ public class Metadata
|
|||||||
case SECONDARY_ADDRESS_FROM:
|
case SECONDARY_ADDRESS_FROM:
|
||||||
return mSecondaryAddressFrom.getIdentifier();
|
return mSecondaryAddressFrom.getIdentifier();
|
||||||
case SECONDARY_ADDRESS_TO:
|
case SECONDARY_ADDRESS_TO:
|
||||||
return mPrimaryAddressTo.getIdentifier();
|
return mSecondaryAddressTo.getIdentifier();
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -89,10 +89,6 @@ public class MutableMetadata extends Metadata implements Listener<AttributeChang
|
|||||||
{
|
{
|
||||||
mChannelFrequency = request.getLongValue();
|
mChannelFrequency = request.getLongValue();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
mChannelFrequency = 0;
|
|
||||||
}
|
|
||||||
broadcast(Attribute.CHANNEL_FREQUENCY);
|
broadcast(Attribute.CHANNEL_FREQUENCY);
|
||||||
break;
|
break;
|
||||||
case CHANNEL_FREQUENCY_LABEL:
|
case CHANNEL_FREQUENCY_LABEL:
|
||||||
|
|||||||
@@ -132,7 +132,6 @@ public class ChannelState extends Module implements ICallEventProvider, IDecoder
|
|||||||
{
|
{
|
||||||
if(mStateMonitorFuture == null && mStateMonitor != null)
|
if(mStateMonitorFuture == null && mStateMonitor != null)
|
||||||
{
|
{
|
||||||
mMutableMetadata.resetAllAttributes();
|
|
||||||
mMutableMetadata.receive(new AttributeChangeRequest<State>(Attribute.CHANNEL_STATE, mState));
|
mMutableMetadata.receive(new AttributeChangeRequest<State>(Attribute.CHANNEL_STATE, mState));
|
||||||
|
|
||||||
if(mTrafficChannelEndListener != null)
|
if(mTrafficChannelEndListener != null)
|
||||||
@@ -154,6 +153,8 @@ public class ChannelState extends Module implements ICallEventProvider, IDecoder
|
|||||||
@Override
|
@Override
|
||||||
public void stop()
|
public void stop()
|
||||||
{
|
{
|
||||||
|
mMutableMetadata.resetAllAttributes();
|
||||||
|
|
||||||
if(mStateMonitorFuture != null)
|
if(mStateMonitorFuture != null)
|
||||||
{
|
{
|
||||||
boolean success = mStateMonitorFuture.cancel(true);
|
boolean success = mStateMonitorFuture.cancel(true);
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ public class ControllerPanel extends JPanel
|
|||||||
{
|
{
|
||||||
setLayout(new MigLayout("insets 0 0 0 0 ", "[grow,fill]", "[]0[grow,fill]"));
|
setLayout(new MigLayout("insets 0 0 0 0 ", "[grow,fill]", "[]0[grow,fill]"));
|
||||||
|
|
||||||
add(mAudioPanel);
|
add(mAudioPanel, "wrap");
|
||||||
|
|
||||||
//Tabbed View - configuration, calls, messages, map
|
//Tabbed View - configuration, calls, messages, map
|
||||||
mTabbedPane = new JideTabbedPane();
|
mTabbedPane = new JideTabbedPane();
|
||||||
|
|||||||
@@ -290,12 +290,13 @@ public class ChannelProcessingManager implements ChannelEventListener
|
|||||||
|
|
||||||
processingChain.start();
|
processingChain.start();
|
||||||
|
|
||||||
|
getChannelMetadataModel().add(processingChain.getChannelState().getMutableMetadata(), channel);
|
||||||
|
|
||||||
channel.setEnabled(true);
|
channel.setEnabled(true);
|
||||||
|
|
||||||
mProcessingChains.put(channel.getChannelID(), processingChain);
|
mProcessingChains.put(channel.getChannelID(), processingChain);
|
||||||
|
|
||||||
mChannelModel.broadcast(
|
mChannelModel.broadcast(new ChannelEvent(channel, Event.NOTIFICATION_PROCESSING_START));
|
||||||
new ChannelEvent(channel, Event.NOTIFICATION_PROCESSING_START));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void stopProcessing(Channel channel, boolean remove)
|
private void stopProcessing(Channel channel, boolean remove)
|
||||||
@@ -306,6 +307,8 @@ public class ChannelProcessingManager implements ChannelEventListener
|
|||||||
{
|
{
|
||||||
ProcessingChain processingChain = mProcessingChains.get(channel.getChannelID());
|
ProcessingChain processingChain = mProcessingChains.get(channel.getChannelID());
|
||||||
|
|
||||||
|
getChannelMetadataModel().remove(processingChain.getChannelState().getMutableMetadata());
|
||||||
|
|
||||||
processingChain.stop();
|
processingChain.stop();
|
||||||
|
|
||||||
processingChain.removeEventLoggingModules();
|
processingChain.removeEventLoggingModules();
|
||||||
|
|||||||
@@ -24,6 +24,9 @@ import audio.IAudioPacketProvider;
|
|||||||
import audio.squelch.ISquelchStateListener;
|
import audio.squelch.ISquelchStateListener;
|
||||||
import audio.squelch.ISquelchStateProvider;
|
import audio.squelch.ISquelchStateProvider;
|
||||||
import audio.squelch.SquelchState;
|
import audio.squelch.SquelchState;
|
||||||
|
import channel.metadata.AttributeChangeRequest;
|
||||||
|
import channel.metadata.IAttributeChangeRequestListener;
|
||||||
|
import channel.metadata.IAttributeChangeRequestProvider;
|
||||||
import channel.state.ChannelState;
|
import channel.state.ChannelState;
|
||||||
import channel.state.DecoderState;
|
import channel.state.DecoderState;
|
||||||
import channel.state.DecoderStateEvent;
|
import channel.state.DecoderStateEvent;
|
||||||
@@ -95,6 +98,7 @@ public class ProcessingChain implements IChannelEventListener
|
|||||||
{
|
{
|
||||||
private final static Logger mLog = LoggerFactory.getLogger(ProcessingChain.class);
|
private final static Logger mLog = LoggerFactory.getLogger(ProcessingChain.class);
|
||||||
|
|
||||||
|
private Broadcaster<AttributeChangeRequest> mAttributeChangeRequestBroadcaster = new Broadcaster<>();
|
||||||
private Broadcaster<AudioPacket> mAudioPacketBroadcaster = new Broadcaster<>();
|
private Broadcaster<AudioPacket> mAudioPacketBroadcaster = new Broadcaster<>();
|
||||||
private Broadcaster<CallEvent> mCallEventBroadcaster = new Broadcaster<>();
|
private Broadcaster<CallEvent> mCallEventBroadcaster = new Broadcaster<>();
|
||||||
private Broadcaster<ChannelEvent> mChannelEventBroadcaster = new Broadcaster<>();
|
private Broadcaster<ChannelEvent> mChannelEventBroadcaster = new Broadcaster<>();
|
||||||
@@ -297,6 +301,11 @@ public class ProcessingChain implements IChannelEventListener
|
|||||||
*/
|
*/
|
||||||
private void registerListeners(Module module)
|
private void registerListeners(Module module)
|
||||||
{
|
{
|
||||||
|
if(module instanceof IAttributeChangeRequestListener)
|
||||||
|
{
|
||||||
|
mAttributeChangeRequestBroadcaster.addListener(((IAttributeChangeRequestListener)module).getAttributeChangeRequestListener());
|
||||||
|
}
|
||||||
|
|
||||||
if(module instanceof IAudioPacketListener)
|
if(module instanceof IAudioPacketListener)
|
||||||
{
|
{
|
||||||
mAudioPacketBroadcaster.addListener(((IAudioPacketListener) module).getAudioPacketListener());
|
mAudioPacketBroadcaster.addListener(((IAudioPacketListener) module).getAudioPacketListener());
|
||||||
@@ -354,6 +363,11 @@ public class ProcessingChain implements IChannelEventListener
|
|||||||
*/
|
*/
|
||||||
private void unregisterListeners(Module module)
|
private void unregisterListeners(Module module)
|
||||||
{
|
{
|
||||||
|
if(module instanceof IAttributeChangeRequestListener)
|
||||||
|
{
|
||||||
|
mAttributeChangeRequestBroadcaster.removeListener(((IAttributeChangeRequestListener) module).getAttributeChangeRequestListener());
|
||||||
|
}
|
||||||
|
|
||||||
if(module instanceof IAudioPacketListener)
|
if(module instanceof IAudioPacketListener)
|
||||||
{
|
{
|
||||||
mAudioPacketBroadcaster.removeListener(((IAudioPacketListener) module).getAudioPacketListener());
|
mAudioPacketBroadcaster.removeListener(((IAudioPacketListener) module).getAudioPacketListener());
|
||||||
@@ -411,6 +425,11 @@ public class ProcessingChain implements IChannelEventListener
|
|||||||
*/
|
*/
|
||||||
private void registerProviders(Module module)
|
private void registerProviders(Module module)
|
||||||
{
|
{
|
||||||
|
if(module instanceof IAttributeChangeRequestProvider)
|
||||||
|
{
|
||||||
|
((IAttributeChangeRequestProvider)module).setAttributeChangeRequestListener(mAttributeChangeRequestBroadcaster);
|
||||||
|
}
|
||||||
|
|
||||||
if(module instanceof IAudioPacketProvider)
|
if(module instanceof IAudioPacketProvider)
|
||||||
{
|
{
|
||||||
((IAudioPacketProvider) module).setAudioPacketListener(mAudioPacketBroadcaster);
|
((IAudioPacketProvider) module).setAudioPacketListener(mAudioPacketBroadcaster);
|
||||||
@@ -463,6 +482,11 @@ public class ProcessingChain implements IChannelEventListener
|
|||||||
*/
|
*/
|
||||||
private void unregisterProviders(Module module)
|
private void unregisterProviders(Module module)
|
||||||
{
|
{
|
||||||
|
if(module instanceof IAttributeChangeRequestProvider)
|
||||||
|
{
|
||||||
|
((IAttributeChangeRequestProvider)module).removeAttributeChangeRequestListener(mAttributeChangeRequestBroadcaster);
|
||||||
|
}
|
||||||
|
|
||||||
if(module instanceof IAudioPacketProvider)
|
if(module instanceof IAudioPacketProvider)
|
||||||
{
|
{
|
||||||
((IAudioPacketProvider) module).setAudioPacketListener(null);
|
((IAudioPacketProvider) module).setAudioPacketListener(null);
|
||||||
|
|||||||
@@ -203,8 +203,11 @@ public class P25DecoderState extends DecoderState
|
|||||||
getAttributeChangeRequestListener(), getAliasList(), AliasIDType.SITE);
|
getAttributeChangeRequestListener(), getAliasList(), AliasIDType.SITE);
|
||||||
mFromTalkgroupMonitor = new AliasedStringAttributeMonitor(Attribute.PRIMARY_ADDRESS_FROM,
|
mFromTalkgroupMonitor = new AliasedStringAttributeMonitor(Attribute.PRIMARY_ADDRESS_FROM,
|
||||||
getAttributeChangeRequestListener(), getAliasList(), AliasIDType.TALKGROUP);
|
getAttributeChangeRequestListener(), getAliasList(), AliasIDType.TALKGROUP);
|
||||||
|
mFromTalkgroupMonitor.addIllegalValue("000000");
|
||||||
mToTalkgroupMonitor = new AliasedStringAttributeMonitor(Attribute.PRIMARY_ADDRESS_TO,
|
mToTalkgroupMonitor = new AliasedStringAttributeMonitor(Attribute.PRIMARY_ADDRESS_TO,
|
||||||
getAttributeChangeRequestListener(), getAliasList(), AliasIDType.TALKGROUP);
|
getAttributeChangeRequestListener(), getAliasList(), AliasIDType.TALKGROUP);
|
||||||
|
mToTalkgroupMonitor.addIllegalValue("0000");
|
||||||
|
mToTalkgroupMonitor.addIllegalValue("000000");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Modulation getModulation()
|
public Modulation getModulation()
|
||||||
|
|||||||
@@ -21,10 +21,10 @@ import java.util.EnumSet;
|
|||||||
|
|
||||||
public enum MixerChannel
|
public enum MixerChannel
|
||||||
{
|
{
|
||||||
LEFT( "L" ),
|
LEFT( "LEFT" ),
|
||||||
RIGHT( "R" ),
|
RIGHT( "RIGHT" ),
|
||||||
MONO( "M" ),
|
MONO( "MONO" ),
|
||||||
STEREO( "S" );
|
STEREO( "STEREO" );
|
||||||
|
|
||||||
private String mLabel;
|
private String mLabel;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user