mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 16:47:31 -05:00
Adds message filtering, message history clear, and message history size features to the 'Messages' tab. Filter window dynamically constructs a list of filters from the primary filter and each of the auxiliary filters enabled within the currently selected/enabled processing channel.
This commit is contained in:
@@ -52,7 +52,7 @@ public class ConfigurationTreePanel extends JPanel
|
||||
mSystemTree.getSelectionModel().setSelectionMode(
|
||||
TreeSelectionModel.SINGLE_TREE_SELECTION );
|
||||
mSystemTree.setShowsRootHandles( true );
|
||||
mSystemTree.addMouseListener( new Handler() );
|
||||
mSystemTree.addMouseListener( new MouseHandler() );
|
||||
mSystemTree.setCellRenderer( new ControllerTreeCellRenderer() );
|
||||
|
||||
//Give the model a reference to the tree, so that it can force newly
|
||||
@@ -68,9 +68,9 @@ public class ConfigurationTreePanel extends JPanel
|
||||
mSystemTree.addTreeSelectionListener( listener );
|
||||
}
|
||||
|
||||
public class Handler implements MouseListener
|
||||
public class MouseHandler implements MouseListener
|
||||
{
|
||||
public Handler()
|
||||
public MouseHandler()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTable;
|
||||
@@ -131,7 +132,7 @@ public class ControllerPanel extends JPanel
|
||||
|
||||
MapPanel mapPanel = new MapPanel( mResourceManager );
|
||||
mTabbedPane.addTab( "Map", mapPanel );
|
||||
|
||||
|
||||
|
||||
/* Channel state list */
|
||||
mChannelStateList = new ChannelStateList( mResourceManager.getSettingsManager() );
|
||||
|
||||
@@ -18,8 +18,10 @@
|
||||
package controller.activity;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JFrame;
|
||||
@@ -63,7 +65,13 @@ public class ActivitySummaryFrame extends JFrame
|
||||
} );
|
||||
|
||||
add( close );
|
||||
|
||||
setVisible( true );
|
||||
|
||||
EventQueue.invokeLater( new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
setVisible( true );
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import javax.swing.table.AbstractTableModel;
|
||||
|
||||
import message.Message;
|
||||
import sample.Listener;
|
||||
import filter.FilterSet;
|
||||
|
||||
public class MessageActivityModel extends AbstractTableModel
|
||||
implements Listener<Message>
|
||||
@@ -51,10 +52,41 @@ public class MessageActivityModel extends AbstractTableModel
|
||||
|
||||
private boolean mNewMessagesFirst = true;
|
||||
|
||||
private FilterSet mMessageFilter;
|
||||
|
||||
public MessageActivityModel( FilterSet messageFilter )
|
||||
{
|
||||
mMessageFilter = messageFilter;
|
||||
}
|
||||
|
||||
public MessageActivityModel()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all messages from history
|
||||
*/
|
||||
public void clear()
|
||||
{
|
||||
EventQueue.invokeLater( new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
int messageCount = mMessages.size();
|
||||
|
||||
mMessages.clear();
|
||||
|
||||
fireTableRowsDeleted( 0, messageCount - 1 );
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public FilterSet getMessageFilter()
|
||||
{
|
||||
return mMessageFilter;
|
||||
}
|
||||
|
||||
public void dispose()
|
||||
{
|
||||
mMessages.clear();
|
||||
@@ -90,18 +122,21 @@ public class MessageActivityModel extends AbstractTableModel
|
||||
|
||||
public void receive( final Message message )
|
||||
{
|
||||
EventQueue.invokeLater( new Runnable()
|
||||
if( mMessageFilter.passes( message ) )
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
mMessages.addFirst( message );
|
||||
EventQueue.invokeLater( new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
mMessages.addFirst( message );
|
||||
|
||||
MessageActivityModel.this.fireTableRowsInserted( 0, 0 );
|
||||
MessageActivityModel.this.fireTableRowsInserted( 0, 0 );
|
||||
|
||||
prune();
|
||||
}
|
||||
} );
|
||||
prune();
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
private void prune()
|
||||
|
||||
@@ -17,11 +17,37 @@
|
||||
******************************************************************************/
|
||||
package controller.activity;
|
||||
|
||||
import filter.FilterEditorPanel;
|
||||
import filter.FilterSet;
|
||||
import gui.SDRTrunk;
|
||||
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JSlider;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
import message.Message;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.jidesoft.swing.JideButton;
|
||||
import com.jidesoft.swing.JideSplitButton;
|
||||
|
||||
import controller.channel.Channel;
|
||||
import controller.channel.ChannelEvent;
|
||||
import controller.channel.ChannelEvent.Event;
|
||||
@@ -30,23 +56,33 @@ import controller.channel.ChannelEventListener;
|
||||
public class MessageActivityPanel extends JPanel implements ChannelEventListener
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final static Logger mLog = LoggerFactory.getLogger( SDRTrunk.class );
|
||||
|
||||
private static MessageActivityModel EMPTY_MODEL = new MessageActivityModel();
|
||||
|
||||
private JTable mMessageTable;
|
||||
|
||||
private JScrollPane mEmptyScrollPane;
|
||||
private Channel mDisplayedChannel;
|
||||
|
||||
private MessageManagementPanel mManagementPanel = new MessageManagementPanel();
|
||||
|
||||
public MessageActivityPanel()
|
||||
{
|
||||
setLayout( new MigLayout("insets 0 0 0 0 ", "[grow,fill]", "[grow,fill]") );
|
||||
setLayout( new MigLayout("insets 0 0 0 0", "[][grow,fill]", "[]0[grow,fill]") );
|
||||
|
||||
mEmptyScrollPane =
|
||||
new JScrollPane( new JTable( new MessageActivityModel() ) );
|
||||
add( mManagementPanel, "span,growx" );
|
||||
|
||||
mMessageTable = new JTable( EMPTY_MODEL );
|
||||
|
||||
add( mEmptyScrollPane );
|
||||
add( new JScrollPane( mMessageTable ), "span,grow" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelChanged( ChannelEvent event )
|
||||
{
|
||||
boolean changed = false;
|
||||
|
||||
if( event.getEvent() == Event.CHANGE_SELECTED &&
|
||||
event.getChannel().isSelected() )
|
||||
{
|
||||
@@ -54,18 +90,21 @@ public class MessageActivityPanel extends JPanel implements ChannelEventListener
|
||||
( mDisplayedChannel != null &&
|
||||
mDisplayedChannel != event.getChannel() ) )
|
||||
{
|
||||
removeAll();
|
||||
|
||||
JScrollPane scroll =
|
||||
new JScrollPane( event.getChannel().getProcessingChain()
|
||||
.getChannelState().getMessageActivityTable() );
|
||||
|
||||
add( scroll );
|
||||
|
||||
mDisplayedChannel = event.getChannel();
|
||||
|
||||
mMessageTable.setModel( event.getChannel().getProcessingChain()
|
||||
.getChannelState().getMessageActivityModel() );
|
||||
|
||||
if( mDisplayedChannel != null )
|
||||
{
|
||||
mManagementPanel.enable();
|
||||
}
|
||||
else
|
||||
{
|
||||
mManagementPanel.disable();
|
||||
}
|
||||
|
||||
revalidate();
|
||||
repaint();
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
else if( event.getEvent() == Event.PROCESSING_STOPPED ||
|
||||
@@ -75,12 +114,203 @@ public class MessageActivityPanel extends JPanel implements ChannelEventListener
|
||||
mDisplayedChannel == event.getChannel() )
|
||||
{
|
||||
mDisplayedChannel = null;
|
||||
removeAll();
|
||||
add( mEmptyScrollPane );
|
||||
|
||||
revalidate();
|
||||
repaint();
|
||||
mMessageTable.setModel( EMPTY_MODEL );
|
||||
|
||||
mManagementPanel.disable();
|
||||
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( changed )
|
||||
{
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
public class MessageManagementPanel extends JPanel
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private MessageHistoryButton mHistoryButton = new MessageHistoryButton();
|
||||
private MessageFilterButton mFilterButton = new MessageFilterButton();
|
||||
|
||||
public MessageManagementPanel()
|
||||
{
|
||||
setLayout( new MigLayout("insets 2 2 5 5", "[]5[left,grow]", "") );
|
||||
|
||||
disable();
|
||||
|
||||
add( mFilterButton );
|
||||
add( mHistoryButton );
|
||||
}
|
||||
|
||||
public void enable()
|
||||
{
|
||||
mHistoryButton.setEnabled( true );
|
||||
mFilterButton.setEnabled( true );
|
||||
}
|
||||
|
||||
public void disable()
|
||||
{
|
||||
mHistoryButton.setEnabled( false );
|
||||
mFilterButton.setEnabled( false );
|
||||
}
|
||||
}
|
||||
|
||||
public class MessageHistoryButton extends JideSplitButton
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public MessageHistoryButton()
|
||||
{
|
||||
super( "Clear" );
|
||||
|
||||
JPanel historyPanel = new JPanel();
|
||||
|
||||
historyPanel.add( new JLabel( "Message History:" ) );
|
||||
|
||||
final JSlider slider = new JSlider();
|
||||
slider.setMinimum( 0 );
|
||||
slider.setMaximum( 2000 );
|
||||
slider.setMajorTickSpacing( 500 );
|
||||
slider.setPaintTicks( true );
|
||||
slider.setPaintLabels( true );
|
||||
|
||||
slider.addMouseListener( new MouseListener()
|
||||
{
|
||||
@Override
|
||||
public void mouseClicked( MouseEvent arg0 )
|
||||
{
|
||||
if( SwingUtilities.isLeftMouseButton( arg0 ) &&
|
||||
arg0.getClickCount() == 2 )
|
||||
{
|
||||
slider.setValue( 500 ); //default
|
||||
}
|
||||
}
|
||||
|
||||
public void mouseEntered( MouseEvent arg0 ) {}
|
||||
public void mouseExited( MouseEvent arg0 ) {}
|
||||
public void mousePressed( MouseEvent arg0 ) {}
|
||||
public void mouseReleased( MouseEvent arg0 ) {}
|
||||
} );
|
||||
|
||||
if( mDisplayedChannel != null )
|
||||
{
|
||||
slider.setValue( mDisplayedChannel.getProcessingChain()
|
||||
.getChannelState().getMessageActivityModel()
|
||||
.getMaxMessageCount() );
|
||||
}
|
||||
else
|
||||
{
|
||||
slider.setValue( 500 );
|
||||
}
|
||||
|
||||
slider.addChangeListener( new ChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void stateChanged( ChangeEvent arg0 )
|
||||
{
|
||||
if( mDisplayedChannel != null )
|
||||
{
|
||||
mDisplayedChannel.getProcessingChain().getChannelState()
|
||||
.getMessageActivityModel()
|
||||
.setMaxMessageCount( slider.getValue() );
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
historyPanel.add( slider );
|
||||
|
||||
add( historyPanel );
|
||||
|
||||
/* Clear messages */
|
||||
addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
if( mDisplayedChannel != null )
|
||||
{
|
||||
mDisplayedChannel.getProcessingChain().getChannelState()
|
||||
.getMessageActivityModel().clear();
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
public class MessageFilterButton extends JideButton
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public MessageFilterButton()
|
||||
{
|
||||
super( "Filter" );
|
||||
|
||||
addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent arg0 )
|
||||
{
|
||||
if( mDisplayedChannel == null )
|
||||
{
|
||||
JOptionPane.showMessageDialog( MessageFilterButton.this,
|
||||
"Please enable and select a decoding channel to "
|
||||
+ "adjust the channel's message display filter" );
|
||||
}
|
||||
else
|
||||
{
|
||||
final JFrame editor = new JFrame();
|
||||
|
||||
editor.setTitle( "Message Filter Editor" );
|
||||
editor.setSize( 600, 400 );
|
||||
editor.setLocationRelativeTo( MessageFilterButton.this );
|
||||
editor.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
|
||||
editor.setLayout( new MigLayout( "", "[grow,fill]",
|
||||
"[grow,fill][][]" ) );
|
||||
|
||||
@SuppressWarnings( "unchecked" )
|
||||
FilterSet<Message> filter =
|
||||
mDisplayedChannel
|
||||
.getProcessingChain().getChannelState()
|
||||
.getMessageActivityModel().getMessageFilter();
|
||||
|
||||
FilterEditorPanel<Message> panel =
|
||||
new FilterEditorPanel<Message>( filter );
|
||||
|
||||
JScrollPane scroller = new JScrollPane( panel );
|
||||
scroller.setViewportView( panel );
|
||||
|
||||
editor.add( scroller, "wrap" );
|
||||
|
||||
editor.add( new JLabel( "Right-click to select/deselect "
|
||||
+ "all nodes" ), "wrap" );
|
||||
|
||||
JButton close = new JButton( "Close" );
|
||||
close.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
editor.dispose();
|
||||
}
|
||||
} );
|
||||
|
||||
editor.add( close );
|
||||
|
||||
EventQueue.invokeLater( new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
editor.setVisible( true );
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import java.util.concurrent.TimeUnit;
|
||||
import javax.swing.JTable;
|
||||
|
||||
import message.Message;
|
||||
import message.MessageFilterFactory;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -45,6 +46,7 @@ import controller.activity.CallEventModel;
|
||||
import controller.activity.MessageActivityModel;
|
||||
import controller.channel.Channel.ChannelType;
|
||||
import controller.channel.ProcessingChain;
|
||||
import filter.FilterSet;
|
||||
|
||||
/**
|
||||
* ChannelState provides a state machine for tracking a voice or data call
|
||||
@@ -108,8 +110,7 @@ public abstract class ChannelState implements Listener<Message>
|
||||
|
||||
protected JTable mCallEventTable;
|
||||
|
||||
protected MessageActivityModel mMessageActivityModel =
|
||||
new MessageActivityModel();
|
||||
protected MessageActivityModel mMessageActivityModel;
|
||||
protected JTable mMessageActivityTable;
|
||||
|
||||
protected ProcessingChain mProcessingChain;
|
||||
@@ -130,6 +131,12 @@ public abstract class ChannelState implements Listener<Message>
|
||||
SystemProperties props = SystemProperties.getInstance();
|
||||
mCallFadeTimeout = props.get( "call.fade.timeout", 2000 );
|
||||
mCallResetTimeout = props.get( "call.reset.timeout", 4000 );
|
||||
|
||||
/* Get a message filter for the primary decoder and aux decoders */
|
||||
FilterSet messageFilter = MessageFilterFactory
|
||||
.getMessageFilter( mProcessingChain.getChannel() );
|
||||
|
||||
mMessageActivityModel = new MessageActivityModel( messageFilter );
|
||||
}
|
||||
|
||||
public void setCurrentCallEvent( CallEvent callEvent )
|
||||
@@ -240,20 +247,11 @@ public abstract class ChannelState implements Listener<Message>
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the message activity model wrapped in a JTable. Although this
|
||||
* may seem to violate separation between model and view, it simplifies
|
||||
* retaining the JTable state for each channel by keeping a local reference
|
||||
* to reuse
|
||||
* Returns the message activity model.
|
||||
*/
|
||||
public JTable getMessageActivityTable()
|
||||
public MessageActivityModel getMessageActivityModel()
|
||||
{
|
||||
if( mMessageActivityTable == null )
|
||||
{
|
||||
mMessageActivityTable = new JTable( mMessageActivityModel );
|
||||
mMessageActivityTable.setAutoResizeMode( JTable.AUTO_RESIZE_LAST_COLUMN );
|
||||
}
|
||||
|
||||
return mMessageActivityTable;
|
||||
return mMessageActivityModel;
|
||||
}
|
||||
|
||||
public void addAuxChannelState( AuxChannelState state )
|
||||
|
||||
Reference in New Issue
Block a user