Work in progress.

-Removed channel collection panel since panels will only have 1 channel
now
-Resolved issue with channel list and channel selection events
-Fixed some of the classes from the rebase to master branch
This commit is contained in:
denny
2016-02-15 07:10:41 -05:00
parent 1f654b5b9c
commit 2c6e35c739
19 changed files with 244 additions and 330 deletions

View File

@@ -24,20 +24,22 @@ import java.util.concurrent.CopyOnWriteArrayList;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;
import javax.swing.table.AbstractTableModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import alias.AliasEvent.Event;
import sample.Broadcaster;
import sample.Listener;
import alias.AliasEvent.Event;
/**
* Alias Model
*/
public class AliasModel implements TableModel
public class AliasModel extends AbstractTableModel
{
private static final long serialVersionUID = 1L;
private final static Logger mLog = LoggerFactory.getLogger( AliasModel.class );
public static final int COLUMN_LIST = 0;
@@ -47,7 +49,6 @@ public class AliasModel implements TableModel
public static final int COLUMN_COLOR = 4;
private List<Alias> mAliases = new ArrayList<>();
private List<TableModelListener> mTableModelListeners = new CopyOnWriteArrayList<>();
private Broadcaster<AliasEvent> mAliasEventBroadcaster = new Broadcaster<>();
public AliasModel()
@@ -141,8 +142,7 @@ public class AliasModel implements TableModel
int index = mAliases.size() - 1;
broadcast( new TableModelEvent( this, index, index,
TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT ) );
fireTableRowsInserted( index, index );
broadcast( new AliasEvent( alias, Event.ADD ) );
@@ -163,8 +163,7 @@ public class AliasModel implements TableModel
mAliases.remove( alias );
broadcast( new TableModelEvent( this, index, index,
TableModelEvent.ALL_COLUMNS, TableModelEvent.DELETE ) );
fireTableRowsDeleted( index, index );
broadcast( new AliasEvent( alias, Event.DELETE ) );
}
@@ -247,26 +246,6 @@ public class AliasModel implements TableModel
throw new IllegalArgumentException( "Not yet implemented" );
}
private void broadcast( TableModelEvent event )
{
for( TableModelListener listener: mTableModelListeners )
{
listener.tableChanged( event );
}
}
@Override
public void addTableModelListener( TableModelListener listener )
{
mTableModelListeners.add( listener );
}
@Override
public void removeTableModelListener( TableModelListener listener )
{
mTableModelListeners.remove( listener );
}
public void broadcast( AliasEvent event )
{
mAliasEventBroadcaster.broadcast( event );
@@ -275,7 +254,7 @@ public class AliasModel implements TableModel
{
int index = mAliases.indexOf( event.getAlias() );
broadcast( new TableModelEvent( this, index ) );
fireTableRowsUpdated( index, index );
}
}

View File

@@ -99,8 +99,7 @@ public class ControllerPanel extends JPanel
mMessageActivityPanel = new MessageActivityPanel( channelProcessingManager );
mCallEventPanel = new CallEventPanel( mSettingsManager,
channelProcessingManager );
mCallEventPanel = new CallEventPanel( mSettingsManager, channelProcessingManager );
mChannelSpectrumPanel = new ChannelSpectrumPanel( mSettingsManager,
channelProcessingManager );

View File

@@ -179,7 +179,16 @@ public class Channel extends Configuration implements IFrequencyChangeProcessor
return mSelected;
}
public void setSelected( boolean selected )
/**
* Sets selection status of the channel.
*
* NOTE: this method is package private so that only the ChannelSelectionManager
* can toggle the selection state. Use the channel model to broadcast a
* request select/deselect channel event.
*
* @param selected
*/
void setSelected( boolean selected )
{
mSelected = selected;
}

View File

@@ -1,5 +1,7 @@
package controller.channel;
import java.awt.Color;
import java.awt.Component;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@@ -12,6 +14,7 @@ import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableCellRenderer;
import net.coderazzi.filters.gui.AutoChoices;
import net.coderazzi.filters.gui.TableFilterHeader;
@@ -64,6 +67,7 @@ public class ChannelController extends JPanel
//System Configuration View and Editor
mChannelTable = new JTable( mChannelModel );
mChannelTable.setDefaultRenderer( String.class, new ChannelTableCellRenderer() );
mChannelTable.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
mChannelTable.getSelectionModel().addListSelectionListener( this );
mChannelTable.setAutoCreateRowSorter( true );
@@ -216,4 +220,52 @@ public class ChannelController extends JPanel
break;
}
}
public class ChannelTableCellRenderer extends DefaultTableCellRenderer
{
private static final long serialVersionUID = 1L;
@Override
public Component getTableCellRendererComponent( JTable table,
Object value, boolean isSelected, boolean hasFocus, int row,
int column )
{
Component component = super.getTableCellRendererComponent(
table, value, isSelected, hasFocus, row, column );
ChannelModel model = (ChannelModel)table.getModel();
int index = table.convertRowIndexToModel( row );
Channel channel = model.getChannelAtIndex( index );
boolean enabled = channel.getEnabled();
if( isSelected )
{
if( enabled )
{
component.setBackground( Color.YELLOW );
}
else
{
component.setBackground( table.getSelectionBackground() );
}
}
else
{
if( enabled )
{
component.setBackground( Color.GREEN );
}
else
{
component.setBackground( table.getBackground() );
}
}
return component;
}
}
}

View File

@@ -22,9 +22,7 @@ import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;
import javax.swing.table.AbstractTableModel;
import module.decode.DecoderType;
@@ -37,20 +35,18 @@ import controller.channel.ChannelEvent.Event;
/**
* Channel Model
*/
public class ChannelModel implements IChannelEventBroadcaster, TableModel
public class ChannelModel extends AbstractTableModel implements IChannelEventBroadcaster
{
private static final long serialVersionUID = 1L;
private final static Logger mLog = LoggerFactory.getLogger( ChannelModel.class );
private ChannelSelectionManager mChannelSelectionManager;
private List<Channel> mChannels = new ArrayList<>();
private List<Channel> mTrafficChannels = new ArrayList<>();
private List<Channel> mChannels = new CopyOnWriteArrayList<>();
private List<Channel> mTrafficChannels = new CopyOnWriteArrayList<>();
private List<ChannelEventListener> mListeners = new CopyOnWriteArrayList<>();
private List<TableModelListener> mTableModelListeners = new CopyOnWriteArrayList<>();
public ChannelModel()
{
mChannelSelectionManager = new ChannelSelectionManager( this );
addListener( mChannelSelectionManager );
}
/**
@@ -138,7 +134,7 @@ public class ChannelModel implements IChannelEventBroadcaster, TableModel
case NOTIFICATION_PROCESSING_STOP:
case NOTIFICATION_SELECTION_CHANGE:
int index = mChannels.indexOf( event.getChannel() );
broadcast( new TableModelEvent( this, index ) );
fireTableRowsUpdated( index, index );
break;
default:
break;
@@ -177,8 +173,7 @@ public class ChannelModel implements IChannelEventBroadcaster, TableModel
index = mChannels.size() - 1;
broadcast( new TableModelEvent( this, index, index,
TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT ) );
fireTableRowsInserted( index, index );
break;
case TRAFFIC:
mTrafficChannels.add( channel );
@@ -214,8 +209,7 @@ public class ChannelModel implements IChannelEventBroadcaster, TableModel
if( index >= 0 )
{
broadcast( new TableModelEvent( this, index, index,
TableModelEvent.ALL_COLUMNS, TableModelEvent.DELETE ) );
fireTableRowsDeleted( index, index );
}
break;
case TRAFFIC:
@@ -348,26 +342,6 @@ public class ChannelModel implements IChannelEventBroadcaster, TableModel
throw new IllegalArgumentException( "Not yet implemented" );
}
private void broadcast( TableModelEvent event )
{
for( TableModelListener listener: mTableModelListeners )
{
listener.tableChanged( event );
}
}
@Override
public void addTableModelListener( TableModelListener listener )
{
mTableModelListeners.add( listener );
}
@Override
public void removeTableModelListener( TableModelListener listener )
{
mTableModelListeners.remove( listener );
}
public void createChannel( DecoderType decoderType, long frequency )
{
throw new UnsupportedOperationException( "Not yet implemented" );

View File

@@ -77,8 +77,6 @@ public class ChannelProcessingManager implements ChannelEventListener
mRecorderManager = recorderManager;
mSourceManager = sourceManager;
mThreadPoolManager = threadPoolManager;
mChannelModel.addListener( this );
}
/**
@@ -184,7 +182,7 @@ public class ChannelProcessingManager implements ChannelEventListener
return;
}
if( processingChain == null )
{
processingChain = new ProcessingChain( mThreadPoolManager,
@@ -258,6 +256,7 @@ public class ChannelProcessingManager implements ChannelEventListener
}
processingChain.setSource( source );
processingChain.start();
channel.setEnabled( true );

View File

@@ -119,10 +119,10 @@ public class SDRTrunk
SourceManager sourceManager = new SourceManager( mSettingsManager, threadPoolManager );
AliasModel aliasModel = new AliasModel();
ChannelModel channelModel = new ChannelModel();
AliasModel aliasModel = new AliasModel();
PlaylistManager playlistManager = new PlaylistManager( threadPoolManager,
aliasModel, channelModel );
@@ -137,7 +137,11 @@ public class SDRTrunk
channelProcessingManager.addAudioPacketListener( recorderManager );
AliasActionManager aliasActionManager = new AliasActionManager( threadPoolManager );
ChannelSelectionManager channelSelectionManager =
new ChannelSelectionManager( channelModel );
channelModel.addListener( channelSelectionManager );
AliasActionManager aliasActionManager = new AliasActionManager( threadPoolManager );
channelProcessingManager.addMessageListener( aliasActionManager );
AudioManager audioManager = new AudioManager( threadPoolManager, sourceManager.getMixerManager() );
@@ -145,16 +149,6 @@ public class SDRTrunk
MapService mapService = new MapService( mSettingsManager );
channelProcessingManager.addMessageListener( mapService );
ChannelSelectionManager channelSelectionManager =
new ChannelSelectionManager( channelModel );
channelModel.addListener( channelSelectionManager );
//TODO: move this to the end once we add the alias model, otherwise the
//configuration tree won't load correctly
//Initialize the playlist manager to load the saved playlist
playlistManager.init();
ConfigurationControllerModel configurationControllerModel =
new ConfigurationControllerModel( channelModel, channelProcessingManager,
@@ -169,11 +163,16 @@ public class SDRTrunk
mTitle = getTitle();
//Initialize the GUI
//TODO: move this to the end once we add the alias model, otherwise the
//configuration tree won't load correctly
//Initialize the playlist manager to load the saved playlist
playlistManager.init();
mLog.info( "starting main application gui" );
//Initialize the GUI
initGUI();
mLog.info( "starting main application gui" );
if( mLogChannelAndMemoryUsage )
{
Runnable cml = new ChannelMemoryLogger();

View File

@@ -475,13 +475,15 @@ public class ProcessingChain implements IChannelEventListener
}
/* If this is a tuner source, broadcast the frequency to all
* of the decoder state's */
* of the decoder state's and start the samples flowing */
if( mSource instanceof TunerChannelSource )
{
TunerChannelSource tcs = (TunerChannelSource)mSource;
try
{
long frequency = ((TunerChannelSource)mSource).getFrequency();
long frequency = tcs.getFrequency();
mDecoderStateEventBroadcaster.broadcast(
new DecoderStateEvent( this, Event.SOURCE_FREQUENCY,
State.IDLE, frequency ) );
@@ -490,6 +492,8 @@ public class ProcessingChain implements IChannelEventListener
{
mLog.error( "Error getting frequency from tuner channel source", e );
}
tcs.start();
}
}
else
@@ -603,6 +607,7 @@ public class ProcessingChain implements IChannelEventListener
*/
public void addMessageListener( Listener<Message> listener )
{
mLog.debug( "Registering Message Listener:" + listener.getClass() );
mMessageBroadcaster.addListener( listener );
}

View File

@@ -1,6 +1,6 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
* Copyright (C) 2014-2016 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
@@ -24,13 +24,19 @@ import java.util.LinkedList;
import javax.swing.table.AbstractTableModel;
import message.Message;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sample.Listener;
import filter.FilterSet;
public class MessageActivityModel extends AbstractTableModel
implements Listener<Message>
{
private static final long serialVersionUID = 1L;
private final static Logger mLog = LoggerFactory.getLogger( MessageActivityModel.class );
private static final long serialVersionUID = 1L;
private static final int sTIME = 0;
private static final int sPROTOCOL = 1;
private static final int sERROR_STATUS = 2;

View File

@@ -1,6 +1,6 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
* Copyright (C) 2014-2016 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

View File

@@ -131,7 +131,7 @@ public class P25MessageFramer implements Listener<Dibit>
if( demodulator != null )
{
/* For CQPSK, we include 3 additional sync detectors to watch for and
* correction +/-90 and 180 degree costas loop phase lock errors */
* correct +/-90 and 180 degree costas loop phase lock errors */
mMatcher.add( new CostasPhaseErrorDetector( FrameSync.P25_PHASE1_ERROR_90_CCW,
demodulator, PHASE_CORRECTION_90_DEGREES ) );
@@ -291,6 +291,7 @@ public class P25MessageFramer implements Listener<Dibit>
else
{
mComplete = true;
dispatch( new P25Message( mMessage.copy(), mDUID, mAliasList ) );
}
}
else

View File

@@ -49,8 +49,8 @@ public class P25_LSMDecoder extends P25Decoder implements IComplexBufferListener
/* Instrumentation Taps */
private static final String INSTRUMENT_BASEBAND_FILTER_OUTPUT = "Tap Point: Baseband Filter Output";
private static final String INSTRUMENT_AGC_OUTPUT = "Tap Point: AGC Output";
private static final String INSTRUMENT_QPSK_DEMODULATOR_OUTPUT = "Tap Point: CQPSK Demodulator Output";
private static final String INSTRUMENT_CQPSK_SLICER_OUTPUT = "Tap Point: CQPSK Slicer Output";
private static final String INSTRUMENT_LSM_DEMODULATOR_OUTPUT = "Tap Point: LSM Demodulator Output";
private static final String INSTRUMENT_QPSK_SLICER_OUTPUT = "Tap Point: QPSK Slicer Output";
private List<TapGroup> mAvailableTaps;
@@ -59,8 +59,8 @@ public class P25_LSMDecoder extends P25Decoder implements IComplexBufferListener
new ComplexBufferToStreamConverter();
private ComplexFeedForwardGainControl mAGC =
new ComplexFeedForwardGainControl( 32 );
private LSMDemodulator mCQPSKDemodulator = new LSMDemodulator();
private QPSKPolarSlicer mCQPSKSlicer = new QPSKPolarSlicer();
private LSMDemodulator mLSMDemodulator = new LSMDemodulator();
private QPSKPolarSlicer mQPSKSlicer = new QPSKPolarSlicer();
private P25MessageFramer mMessageFramer;
public P25_LSMDecoder( AliasList aliasList )
@@ -74,12 +74,12 @@ public class P25_LSMDecoder extends P25Decoder implements IComplexBufferListener
mStreamConverter.setListener( mAGC );
mAGC.setListener( mCQPSKDemodulator );
mAGC.setListener( mLSMDemodulator );
mCQPSKDemodulator.setSymbolListener( mCQPSKSlicer );
mLSMDemodulator.setSymbolListener( mQPSKSlicer );
mMessageFramer = new P25MessageFramer( aliasList, mCQPSKDemodulator );
mCQPSKSlicer.addListener( mMessageFramer );
mMessageFramer = new P25MessageFramer( aliasList, mLSMDemodulator );
mQPSKSlicer.addListener( mMessageFramer );
mMessageFramer.setListener( getMessageProcessor() );
}
@@ -97,11 +97,11 @@ public class P25_LSMDecoder extends P25Decoder implements IComplexBufferListener
mAGC.dispose();
mAGC = null;
mCQPSKDemodulator.dispose();
mCQPSKDemodulator = null;
mLSMDemodulator.dispose();
mLSMDemodulator = null;
mCQPSKSlicer.dispose();
mCQPSKSlicer = null;
mQPSKSlicer.dispose();
mQPSKSlicer = null;
mMessageFramer.dispose();
mMessageFramer = null;
@@ -132,14 +132,14 @@ public class P25_LSMDecoder extends P25Decoder implements IComplexBufferListener
group.add( new ComplexTap( INSTRUMENT_BASEBAND_FILTER_OUTPUT, 0, 1.0f ) );
group.add( new ComplexTap( INSTRUMENT_AGC_OUTPUT, 0, 1.0f ) );
group.add( new QPSKTap( INSTRUMENT_QPSK_DEMODULATOR_OUTPUT, 0, 1.0f ) );
group.add( new DibitTap( INSTRUMENT_CQPSK_SLICER_OUTPUT, 0, 0.1f ) );
group.add( new QPSKTap( INSTRUMENT_LSM_DEMODULATOR_OUTPUT, 0, 1.0f ) );
group.add( new DibitTap( INSTRUMENT_QPSK_SLICER_OUTPUT, 0, 0.1f ) );
mAvailableTaps.add( group );
if( mCQPSKDemodulator != null )
if( mLSMDemodulator != null )
{
mAvailableTaps.addAll( mCQPSKDemodulator.getTapGroups() );
mAvailableTaps.addAll( mLSMDemodulator.getTapGroups() );
}
}
@@ -152,9 +152,9 @@ public class P25_LSMDecoder extends P25Decoder implements IComplexBufferListener
@Override
public void registerTap( Tap tap )
{
if( mCQPSKDemodulator != null )
if( mLSMDemodulator != null )
{
mCQPSKDemodulator.registerTap( tap );
mLSMDemodulator.registerTap( tap );
}
switch( tap.getName() )
@@ -167,15 +167,15 @@ public class P25_LSMDecoder extends P25Decoder implements IComplexBufferListener
case INSTRUMENT_AGC_OUTPUT:
ComplexSampleTap agcSymbol = (ComplexSampleTap)tap;
mAGC.setListener( agcSymbol );
agcSymbol.setListener( mCQPSKDemodulator );
agcSymbol.setListener( mLSMDemodulator );
break;
case INSTRUMENT_QPSK_DEMODULATOR_OUTPUT:
case INSTRUMENT_LSM_DEMODULATOR_OUTPUT:
QPSKTap qpsk = (QPSKTap)tap;
mCQPSKDemodulator.setSymbolListener( qpsk );
qpsk.setListener( mCQPSKSlicer );
mLSMDemodulator.setSymbolListener( qpsk );
qpsk.setListener( mQPSKSlicer );
break;
case INSTRUMENT_CQPSK_SLICER_OUTPUT:
mCQPSKSlicer.addListener( (DibitTap)tap );
case INSTRUMENT_QPSK_SLICER_OUTPUT:
mQPSKSlicer.addListener( (DibitTap)tap );
break;
default:
throw new IllegalArgumentException( "Unrecognized tap: " +
@@ -189,9 +189,9 @@ public class P25_LSMDecoder extends P25Decoder implements IComplexBufferListener
@Override
public void unregisterTap( Tap tap )
{
if( mCQPSKDemodulator != null )
if( mLSMDemodulator != null )
{
mCQPSKDemodulator.unregisterTap( tap );
mLSMDemodulator.unregisterTap( tap );
}
switch( tap.getName() )
@@ -200,13 +200,13 @@ public class P25_LSMDecoder extends P25Decoder implements IComplexBufferListener
mStreamConverter.setListener( mAGC );
break;
case INSTRUMENT_AGC_OUTPUT:
mAGC.setListener( mCQPSKDemodulator );
mAGC.setListener( mLSMDemodulator );
break;
case INSTRUMENT_QPSK_DEMODULATOR_OUTPUT:
mCQPSKDemodulator.setSymbolListener( mCQPSKSlicer );
case INSTRUMENT_LSM_DEMODULATOR_OUTPUT:
mLSMDemodulator.setSymbolListener( mQPSKSlicer );
break;
case INSTRUMENT_CQPSK_SLICER_OUTPUT:
mCQPSKSlicer.removeListener( (DibitTap)tap );
case INSTRUMENT_QPSK_SLICER_OUTPUT:
mQPSKSlicer.removeListener( (DibitTap)tap );
break;
default:
throw new IllegalArgumentException( "Unrecognized tap: " +

View File

@@ -14,7 +14,7 @@ public enum DataUnitID
TSBK1( 7, 260, false, "TSBK1", "Trunking Signaling Block" ),
TSBK2( 7, 260, false, "TSBK2", "Trunking Signaling Block" ),
TSBK3( 7, 260, false, "TSBK3", "Trunking Signaling Block" ),
VSELP2( 9, 1680, false, "VSEL1", "Motorola VSELP Unit 1" ),
VSELP2( 9, 1680, false, "VSEL2", "Motorola VSELP Unit 2" ),
LDU2 ( 10, 1632, true, "LDU2 ", "Logical Link Data Unit 2" ),
PDU0 ( 12, 260, false, "PDU0 ", "Packet Header Data Unit" ),
PDU1 ( 12, 356, false, "PDU1 ", "Packet Data Unit-Unconfirmed" ),
@@ -75,8 +75,12 @@ public enum DataUnitID
return TDU;
case 5:
return LDU1;
case 6:
return VSELP1;
case 7:
return TSBK1;
case 9:
return VSELP2;
case 10:
return LDU2;
case 12:

View File

@@ -0,0 +1,29 @@
package module.decode.state;
import controller.channel.Channel.ChannelType;
/**
* Allows decoders to change the call timeout setting in the channel state
*/
public class ChangeChannelTimeoutEvent extends DecoderStateEvent
{
private ChannelType mChannelType;
private long mCallTimeout;
public ChangeChannelTimeoutEvent( Object source, ChannelType channelType, long timeout )
{
super( source, Event.CHANGE_CALL_TIMEOUT, State.IDLE );
mChannelType = channelType;
mCallTimeout = timeout;
}
public ChannelType getChannelType()
{
return mChannelType;
}
public long getCallTimeout()
{
return mCallTimeout;
}
}

View File

@@ -1,154 +0,0 @@
package module.decode.state;
import java.awt.Component;
import java.awt.Point;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JMenu;
import javax.swing.JPanel;
import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import playlist.PlaylistManager;
import settings.SettingsManager;
import controller.channel.Channel;
import controller.channel.ChannelModel;
import controller.channel.ChannelProcessingManager;
/**
* Channel Collection assembles a primary channel panel and any related decoder
* state panels, provides contextual access to the channel and supports channel
* selection.
*/
public class ChannelCollectionPanel extends JPanel
{
private static final long serialVersionUID = 1L;
private final static Logger mLog = LoggerFactory.getLogger( ChannelCollectionPanel.class );
private ChannelModel mChannelModel;
private ChannelProcessingManager mChannelProcessingManager;
private PlaylistManager mPlaylistManager;
private SettingsManager mSettingsManager;
private List<ChannelStatePanel> mChannelPanels = new ArrayList<ChannelStatePanel>();
public ChannelCollectionPanel( ChannelModel channelModel,
ChannelProcessingManager channelProcessingManager,
PlaylistManager playlistManager,
SettingsManager settingsManager,
Channel channel )
{
mChannelModel = channelModel;
mChannelProcessingManager = channelProcessingManager;
mPlaylistManager = playlistManager;
mSettingsManager = settingsManager;
init( channel );
}
protected void init( Channel channel )
{
setLayout( new MigLayout( "insets 0 0 0 0", "[grow,fill]", "[]0[]0[]") );
setOpaque( false );
ChannelStatePanel csp = new ChannelStatePanel( mChannelModel,
mChannelProcessingManager, mPlaylistManager, mSettingsManager, channel );
mChannelPanels.add( csp );
add( csp, "span,grow" );
}
public Channel getChannel()
{
if( mChannelPanels.size() >= 1 )
{
return mChannelPanels.get( 0 ).getChannel();
}
return null;
}
public void dispose()
{
for( ChannelStatePanel panel: mChannelPanels )
{
panel.dispose();
}
mChannelPanels.clear();
mPlaylistManager = null;
mSettingsManager = null;
}
/**
* Toggles the selection state of the channel if it matches the channel
* argument. Otherwise, sets the selection state to false.
*/
public void setSelectedChannel( Channel channel )
{
for( ChannelStatePanel panel: mChannelPanels )
{
if( panel.getChannel() == channel )
{
/* Toggle the selection state */
panel.getChannel().setSelected( !panel.getChannel().isSelected() );
panel.repaint();
}
else
{
if( panel.getChannel().isSelected() )
{
panel.getChannel().setSelected( false );
panel.repaint();
}
}
}
}
/**
* Returns the channel represented by the channel panel at the gui point
* location, to selecting the channel
*
* @param point - current location of the mouse
*
* @return - channel or null
*/
public Channel getChannelAt( Point point )
{
Component c = this.getComponentAt( point );
if( c instanceof ChannelCollectionPanel )
{
return ((ChannelCollectionPanel)c).getChannel();
}
else
{
return getChannel();
}
}
protected SettingsManager getSettingsManager()
{
return mSettingsManager;
}
public JMenu getContextMenu()
{
if( !mChannelPanels.isEmpty() )
{
return mChannelPanels.get( 0 ).getContextMenu();
}
return null;
}
}

View File

@@ -23,6 +23,7 @@ import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JMenu;
import javax.swing.JPanel;
@@ -42,6 +43,7 @@ import settings.ColorSettingResetMenuItem;
import settings.SettingsManager;
import controller.channel.Channel;
import controller.channel.ChannelEvent;
import controller.channel.ChannelEvent.Event;
import controller.channel.ChannelEventListener;
import controller.channel.ChannelModel;
import controller.channel.ChannelProcessingManager;
@@ -55,8 +57,7 @@ public class ChannelList extends JPanel implements ChannelEventListener
private final static Logger mLog = LoggerFactory.getLogger( ChannelList.class );
private HashMap<Channel,ChannelCollectionPanel> mDisplayedPanels =
new HashMap<Channel,ChannelCollectionPanel>();
private Map<Channel,ChannelPanel> mDisplayedPanels = new HashMap<Channel,ChannelPanel>();
private ChannelModel mChannelModel;
private ChannelProcessingManager mChannelProcessingManager;
@@ -104,12 +105,12 @@ public class ChannelList extends JPanel implements ChannelEventListener
{
if( !mDisplayedPanels.containsKey( channel ) )
{
ChannelCollectionPanel panel = new ChannelCollectionPanel( mChannelModel,
mChannelProcessingManager, mPlaylistManager, mSettingsManager, channel );
ChannelPanel channelPanel = new ChannelPanel( mChannelModel,
mChannelProcessingManager, mPlaylistManager, mSettingsManager, channel );
add( panel, "wrap" );
add( channelPanel, "wrap" );
mDisplayedPanels.put( channel, panel );
mDisplayedPanels.put( channel, channelPanel );
revalidate();
repaint();
@@ -120,7 +121,7 @@ public class ChannelList extends JPanel implements ChannelEventListener
{
if( mDisplayedPanels.containsKey( channel ) )
{
ChannelCollectionPanel panel = mDisplayedPanels.remove( channel );
ChannelPanel panel = mDisplayedPanels.remove( channel );
if( panel != null )
{
@@ -134,15 +135,6 @@ public class ChannelList extends JPanel implements ChannelEventListener
}
}
public void setSelectedChannel( Channel channel )
{
/* Send channel selection to each channel panel */
for( ChannelCollectionPanel panel: mDisplayedPanels.values() )
{
panel.setSelectedChannel( channel );
}
}
public class ListSelectionListener implements MouseListener
{
@Override
@@ -150,18 +142,22 @@ public class ChannelList extends JPanel implements ChannelEventListener
{
Component component = getComponentAt( e.getPoint() );
if( component instanceof ChannelCollectionPanel )
if( component instanceof ChannelPanel )
{
ChannelCollectionPanel panel = (ChannelCollectionPanel)component;
ChannelPanel panel = (ChannelPanel)component;
Point translatedPoint = SwingUtilities
.convertPoint( e.getComponent(), e.getPoint(), panel );
Channel channel = panel.getChannelAt( translatedPoint );
Channel channel = panel.getChannel();
if( e.getButton() == MouseEvent.BUTTON1 )
{
setSelectedChannel( channel );
if( channel.isSelected() )
{
mChannelModel.broadcast( new ChannelEvent( channel, Event.REQUEST_DESELECT ) );
}
else
{
mChannelModel.broadcast( new ChannelEvent( channel, Event.REQUEST_SELECT ) );
}
}
else if( e.getButton() == MouseEvent.BUTTON3 )
{

View File

@@ -15,13 +15,12 @@ import javax.swing.JMenu;
import javax.swing.JPanel;
import module.ProcessingChain;
import module.decode.DecoderFactory;
import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import controller.channel.Channel;
import controller.channel.ChannelUtils;
import module.decode.DecoderFactory;
import net.miginfocom.swing.MigLayout;
import playlist.PlaylistManager;
import record.RecorderType;
import record.config.RecordConfiguration;
@@ -31,18 +30,22 @@ import settings.ColorSetting.ColorSettingName;
import settings.Setting;
import settings.SettingChangeListener;
import settings.SettingsManager;
import controller.channel.Channel;
import controller.channel.ChannelEvent;
import controller.channel.ChannelEvent.Event;
import controller.channel.ChannelEventListener;
import controller.channel.ChannelModel;
import controller.channel.ChannelProcessingManager;
import controller.channel.ChannelUtils;
public class ChannelStatePanel extends JPanel
implements Listener<ChangedAttribute>, SettingChangeListener
public class ChannelPanel extends JPanel
implements Listener<ChangedAttribute>,
SettingChangeListener,
ChannelEventListener
{
private static final long serialVersionUID = 1L;
private final static Logger mLog = LoggerFactory.getLogger( ChannelStatePanel.class );
private final static Logger mLog = LoggerFactory.getLogger( ChannelPanel.class );
private Font mFontDetails = new Font( Font.MONOSPACED, Font.PLAIN, 12 );
private Font mFontDecoder = new Font( Font.MONOSPACED, Font.PLAIN, 12 );
@@ -88,19 +91,16 @@ public class ChannelStatePanel extends JPanel
*
* Updates color background according to current channel state.
*/
public ChannelStatePanel( ChannelModel channelModel,
ChannelProcessingManager channelProcessingManager,
PlaylistManager playlistManager,
SettingsManager settingsManager,
Channel channel )
public ChannelPanel( ChannelModel channelModel,
ChannelProcessingManager channelProcessingManager,
PlaylistManager playlistManager,
SettingsManager settingsManager,
Channel channel )
{
mChannelModel = channelModel;
mChannelProcessingManager = channelProcessingManager;
mPlaylistManager = playlistManager;
mSettingsManager = settingsManager;
mSettingsManager.addListener( this );
mChannel = channel;
ProcessingChain processingChain =
@@ -109,9 +109,7 @@ public class ChannelStatePanel extends JPanel
if( processingChain != null )
{
mChannelState = processingChain.getChannelState();
mChannelState.setChangedAttributeListener( this );
init();
for( DecoderState decoderState: processingChain.getDecoderStates() )
@@ -120,6 +118,10 @@ public class ChannelStatePanel extends JPanel
mDecoderPanels.add( panel );
add( panel, "grow,span" );
}
mChannelState.setChangedAttributeListener( this );
mChannelModel.addListener( this );
mSettingsManager.addListener( this );
}
else
{
@@ -191,6 +193,11 @@ public class ChannelStatePanel extends JPanel
public void dispose()
{
mChannelModel.removeListener( this );
mChannelModel = null;
mChannelProcessingManager = null;
mPlaylistManager = null;
mSettingsManager.removeListener( this );
@@ -426,6 +433,16 @@ public class ChannelStatePanel extends JPanel
public JMenu getContextMenu()
{
return ChannelUtils.getContextMenu( mChannelModel, mChannelProcessingManager,
mPlaylistManager, mChannel, ChannelStatePanel.this );
mPlaylistManager, mChannel, ChannelPanel.this );
}
@Override
public void channelChanged( ChannelEvent event )
{
if( event.getEvent() == Event.NOTIFICATION_SELECTION_CHANGE &&
event.getChannel() == mChannel )
{
repaint();
}
}
}

View File

@@ -103,11 +103,8 @@ public class PlaylistManager implements ChannelEventListener
mPlaylistLoading = true;
mLog.debug( "Transferring aliases to model" );
mAliasModel.addAliases( mPlaylist.getAliases() );
mLog.debug( "Transferring channels to model" );
mChannelModel.addChannels( mPlaylist.getChannels() );
mLog.debug( "Transfer to models is complete" );
mPlaylistLoading = false;
}
@@ -175,13 +172,9 @@ public class PlaylistManager implements ChannelEventListener
{
//TODO: recreate the playlist and load values from each of the models
mLog.debug( "Aliases in model:" + mAliasModel.getAliases().size() );
mPlaylist.setAliases( mAliasModel.getAliases() );
mLog.debug( "Aliases in playlist:" + mPlaylist.getAliases().size() );
mLog.debug( "Channels in model:" + mChannelModel.getChannels().size() );
mPlaylist.setChannels( mChannelModel.getChannels() );
mLog.debug( "Channels in playlist:" + mPlaylist.getChannels().size() );
JAXBContext context = null;

View File

@@ -1,5 +1,10 @@
package sample.complex;
import module.decode.p25.P25_LSMDecoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sample.Listener;
/**
@@ -7,9 +12,10 @@ import sample.Listener;
*/
public class ComplexBufferToStreamConverter implements Listener<ComplexBuffer>
{
private final static Logger mLog = LoggerFactory.getLogger( ComplexBufferToStreamConverter.class );
private ComplexSampleListener mListener;
public void dispose()
{
mListener = null;