Resolves #170 adding support for Airspy Mini tuner's 3 and 6 MHz

sample rates.

Resolves issue in PolyphaseChannelManager responding to sample rate
changes in the tuner.  The manager now recreates the channelizer when
needed if the tuner's sample rate has changed since the last time the
channelizer was used.

Updates the Tuner selection view to reflect tuner lock state.  Updates
the tuner editors to enable/disable frequency controller and sample
rate controls according to the tuner's lock state.
This commit is contained in:
Denny
2018-07-14 07:45:42 -04:00
parent 9e7fa7618d
commit 104c4f72be
18 changed files with 376 additions and 348 deletions

View File

@@ -1,17 +1,17 @@
/*******************************************************************************
* SDR Trunk
* 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
* 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/>
******************************************************************************/
@@ -19,18 +19,27 @@
package io.github.dsheirer.source.tuner;
import com.jidesoft.swing.JideSplitPane;
import io.github.dsheirer.sample.Listener;
import io.github.dsheirer.source.tuner.TunerEvent.Event;
import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.*;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.RowSorter;
import javax.swing.SortOrder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableRowSorter;
import java.awt.*;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
@@ -38,129 +47,150 @@ import java.util.List;
public class TunerViewPanel extends JPanel
{
private static final long serialVersionUID = 1L;
private final static Logger mLog = LoggerFactory.getLogger( TunerViewPanel.class );
private static final long serialVersionUID = 1L;
private final static Logger mLog = LoggerFactory.getLogger(TunerViewPanel.class);
private TunerModel mTunerModel;
private JTable mTunerTable;
private TableRowSorter<TunerModel> mRowSorter;
private JideSplitPane mSplitPane;
private TunerEditor mTunerEditor;
public TunerViewPanel( TunerModel tunerModel )
{
mTunerModel = tunerModel;
mTunerEditor = new TunerEditor( mTunerModel.getTunerConfigurationModel() );
init();
}
private void init()
{
setLayout( new MigLayout( "insets 0 0 0 0", "[fill,grow]", "[fill,grow]" ) );
private TunerModel mTunerModel;
private JTable mTunerTable;
private TableRowSorter<TunerModel> mRowSorter;
private JideSplitPane mSplitPane;
private TunerEditor mTunerEditor;
mRowSorter = new TableRowSorter<>( mTunerModel );
List<RowSorter.SortKey> sortKeys = new ArrayList<>();
sortKeys.add( new RowSorter.SortKey( TunerModel.TUNER_TYPE, SortOrder.ASCENDING ) );
sortKeys.add( new RowSorter.SortKey( TunerModel.TUNER_ID, SortOrder.ASCENDING ) );
mRowSorter.setSortKeys( sortKeys );
mTunerTable = new JTable( mTunerModel );
mTunerTable.setRowSorter( mRowSorter );
mTunerTable.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
mTunerTable.getSelectionModel().addListSelectionListener( new ListSelectionListener()
{
@Override
public void valueChanged( ListSelectionEvent event )
{
if( !event.getValueIsAdjusting() )
{
int row = mTunerTable.getSelectedRow();
int modelRow = mTunerTable.convertRowIndexToModel( row );
public TunerViewPanel(TunerModel tunerModel)
{
mTunerModel = tunerModel;
mTunerEditor = new TunerEditor(mTunerModel.getTunerConfigurationModel());
mTunerEditor.setItem( mTunerModel.getTuner( modelRow ) );
}
}
} );
mTunerTable.addMouseListener( new MouseAdapter()
{
@Override
public void mouseClicked( MouseEvent e )
{
int column = mTunerTable.columnAtPoint( e.getPoint() );
init();
}
if( column == TunerModel.SPECTRAL_DISPLAY_MAIN )
{
int tableRow = mTunerTable.rowAtPoint( e.getPoint() );
int modelRow = mTunerTable.convertRowIndexToModel( tableRow );
Tuner tuner = mTunerModel.getTuner( modelRow );
if( tuner != null )
{
mTunerModel.broadcast( new TunerEvent( tuner,
Event.REQUEST_MAIN_SPECTRAL_DISPLAY ) );
}
}
else if( column == TunerModel.SPECTRAL_DISPLAY_NEW )
{
int tableRow = mTunerTable.rowAtPoint( e.getPoint() );
int modelRow = mTunerTable.convertRowIndexToModel( tableRow );
Tuner tuner = mTunerModel.getTuner( modelRow );
if( tuner != null )
{
mTunerModel.broadcast( new TunerEvent( tuner,
Event.REQUEST_NEW_SPECTRAL_DISPLAY ) );
}
}
}
} );
TableCellRenderer renderer = new LinkCellRenderer();
mTunerTable.getColumnModel().getColumn( 5 ).setCellRenderer( renderer );
mTunerTable.getColumnModel().getColumn( 6 ).setCellRenderer( renderer );
JScrollPane listScroller = new JScrollPane( mTunerTable );
listScroller.setPreferredSize( new Dimension( 400, 20 ) );
private void init()
{
setLayout(new MigLayout("insets 0 0 0 0", "[fill,grow]", "[fill,grow]"));
JScrollPane editorScroller = new JScrollPane( mTunerEditor );
editorScroller.setPreferredSize( new Dimension( 400, 80 ) );
mSplitPane = new JideSplitPane();
mSplitPane.setOrientation( JideSplitPane.VERTICAL_SPLIT );
mSplitPane.add( listScroller );
mSplitPane.add( editorScroller );
add( mSplitPane );
}
public class LinkCellRenderer extends DefaultTableCellRenderer
{
private static final long serialVersionUID = 1L;
mRowSorter = new TableRowSorter<>(mTunerModel);
List<RowSorter.SortKey> sortKeys = new ArrayList<>();
sortKeys.add(new RowSorter.SortKey(TunerModel.TUNER_TYPE, SortOrder.ASCENDING));
sortKeys.add(new RowSorter.SortKey(TunerModel.TUNER_ID, SortOrder.ASCENDING));
mRowSorter.setSortKeys(sortKeys);
@Override
public Component getTableCellRendererComponent( JTable table,
Object value, boolean isSelected, boolean hasFocus, int row,
int column )
{
JLabel label = (JLabel)super.getTableCellRendererComponent( table,
value, isSelected, hasFocus, row, column );
label.setForeground( Color.BLUE.brighter() );
if( column == TunerModel.SPECTRAL_DISPLAY_MAIN )
{
label.setToolTipText( "Show this tuner in the main spectral display" );
}
else if( column == TunerModel.SPECTRAL_DISPLAY_NEW )
{
label.setToolTipText( "Show this tuner in a new spectral display" );
}
return label;
}
}
mTunerTable = new JTable(mTunerModel);
mTunerTable.setRowSorter(mRowSorter);
mTunerTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
mTunerTable.getSelectionModel().addListSelectionListener(new ListSelectionListener()
{
@Override
public void valueChanged(ListSelectionEvent event)
{
if(!event.getValueIsAdjusting())
{
int row = mTunerTable.getSelectedRow();
int modelRow = mTunerTable.convertRowIndexToModel(row);
mTunerEditor.setItem(mTunerModel.getTuner(modelRow));
}
}
});
mTunerModel.addListener(new Listener<TunerEvent>()
{
@Override
public void receive(TunerEvent tunerEvent)
{
switch(tunerEvent.getEvent())
{
case LOCK_STATE_CHANGE:
int row = mTunerTable.getSelectedRow();
if(row >= 0)
{
int modelRow = mTunerTable.convertRowIndexToModel(row);
mTunerEditor.setItem(mTunerModel.getTuner(modelRow));
}
break;
}
}
});
mTunerTable.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
int column = mTunerTable.columnAtPoint(e.getPoint());
if(column == TunerModel.SPECTRAL_DISPLAY_MAIN)
{
int tableRow = mTunerTable.rowAtPoint(e.getPoint());
int modelRow = mTunerTable.convertRowIndexToModel(tableRow);
Tuner tuner = mTunerModel.getTuner(modelRow);
if(tuner != null)
{
mTunerModel.broadcast(new TunerEvent(tuner,
Event.REQUEST_MAIN_SPECTRAL_DISPLAY));
}
}
else if(column == TunerModel.SPECTRAL_DISPLAY_NEW)
{
int tableRow = mTunerTable.rowAtPoint(e.getPoint());
int modelRow = mTunerTable.convertRowIndexToModel(tableRow);
Tuner tuner = mTunerModel.getTuner(modelRow);
if(tuner != null)
{
mTunerModel.broadcast(new TunerEvent(tuner,
Event.REQUEST_NEW_SPECTRAL_DISPLAY));
}
}
}
});
TableCellRenderer renderer = new LinkCellRenderer();
mTunerTable.getColumnModel().getColumn(5).setCellRenderer(renderer);
mTunerTable.getColumnModel().getColumn(6).setCellRenderer(renderer);
JScrollPane listScroller = new JScrollPane(mTunerTable);
listScroller.setPreferredSize(new Dimension(400, 20));
JScrollPane editorScroller = new JScrollPane(mTunerEditor);
editorScroller.setPreferredSize(new Dimension(400, 80));
mSplitPane = new JideSplitPane();
mSplitPane.setOrientation(JideSplitPane.VERTICAL_SPLIT);
mSplitPane.add(listScroller);
mSplitPane.add(editorScroller);
add(mSplitPane);
}
public class LinkCellRenderer extends DefaultTableCellRenderer
{
private static final long serialVersionUID = 1L;
@Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row,
int column)
{
JLabel label = (JLabel)super.getTableCellRendererComponent(table,
value, isSelected, hasFocus, row, column);
label.setForeground(Color.BLUE.brighter());
if(column == TunerModel.SPECTRAL_DISPLAY_MAIN)
{
label.setToolTipText("Show this tuner in the main spectral display");
}
else if(column == TunerModel.SPECTRAL_DISPLAY_NEW)
{
label.setToolTipText("Show this tuner in a new spectral display");
}
return label;
}
}
}