diff --git a/src/spectrum/OverlayPanel.java b/src/spectrum/OverlayPanel.java
index d826a61c..ae0c23fc 100644
--- a/src/spectrum/OverlayPanel.java
+++ b/src/spectrum/OverlayPanel.java
@@ -1,44 +1,30 @@
/*******************************************************************************
- * SDR Trunk
- * Copyright (C) 2014,2015 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
+ * sdrtrunk
+ * Copyright (C) 2014-2017 Dennis Sheirer
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see
+ *
******************************************************************************/
package spectrum;
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.Point;
-import java.awt.RenderingHints;
-import java.awt.Stroke;
-import java.awt.event.ComponentEvent;
-import java.awt.event.ComponentListener;
-import java.awt.geom.Line2D;
-import java.awt.geom.Rectangle2D;
-import java.text.DecimalFormat;
-import java.util.ArrayList;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-import javax.swing.JPanel;
-
+import controller.channel.Channel;
+import controller.channel.Channel.ChannelType;
+import controller.channel.ChannelEvent;
+import controller.channel.ChannelEventListener;
+import controller.channel.ChannelModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
import settings.ColorSetting;
import settings.ColorSetting.ColorSettingName;
import settings.Setting;
@@ -47,151 +33,151 @@ import settings.SettingsManager;
import source.tuner.TunerChannel;
import source.tuner.frequency.FrequencyChangeEvent;
import source.tuner.frequency.IFrequencyChangeProcessor;
-import controller.channel.Channel;
-import controller.channel.Channel.ChannelType;
-import controller.channel.ChannelEvent;
-import controller.channel.ChannelEventListener;
-import controller.channel.ChannelModel;
-public class OverlayPanel extends JPanel
- implements ChannelEventListener,
- IFrequencyChangeProcessor,
- SettingChangeListener
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ComponentEvent;
+import java.awt.event.ComponentListener;
+import java.awt.geom.Line2D;
+import java.awt.geom.Rectangle2D;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+public class OverlayPanel extends JPanel implements ChannelEventListener, IFrequencyChangeProcessor,
+ SettingChangeListener
{
- private static final long serialVersionUID = 1L;
-
- private final static Logger mLog =
- LoggerFactory.getLogger( OverlayPanel.class );
+ private static final long serialVersionUID = 1L;
- private final static RenderingHints RENDERING_HINTS =
- new RenderingHints( RenderingHints.KEY_ANTIALIASING,
- RenderingHints.VALUE_ANTIALIAS_ON );
+ private final static Logger mLog = LoggerFactory.getLogger(OverlayPanel.class);
- static
- {
- RENDERING_HINTS.put( RenderingHints.KEY_RENDERING,
- RenderingHints.VALUE_RENDER_QUALITY );
- }
-
- private final static BasicStroke DASHED_STROKE = new BasicStroke(0.8f,
- BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 5.0f, new float[] {2.0f, 4.0f}, 0.0f);
-
- private static DecimalFormat CURSOR_FORMAT = new DecimalFormat( "000.00000" );
- private long mFrequency = 0;
- private int mBandwidth = 0;
- private Point mCursorLocation = new Point( 0, 0 );
- private boolean mCursorVisible = false;
+ private final static RenderingHints RENDERING_HINTS = new RenderingHints(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
- private DFTSize mDFTSize = DFTSize.FFT04096;
- private int mZoom = 0;
- private int mDFTZoomWindowOffset = 0;
-
- /**
- * Colors used by this component
- */
- private Color mColorChannelConfig;
- private Color mColorChannelConfigProcessing;
- private Color mColorChannelConfigSelected;
- private Color mColorSpectrumBackground;
- private Color mColorSpectrumCursor;
- private Color mColorSpectrumLine;
-
- //Currently visible/displayable channels
- private CopyOnWriteArrayList mVisibleChannels = new CopyOnWriteArrayList();
- private ChannelDisplay mChannelDisplay = ChannelDisplay.ALL;
-
- //Defines the offset at the bottom of the spectral display to account for
- //the frequency labels
- private double mSpectrumInset = 20.0d;
- private LabelSizeManager mLabelSizeMonitor = new LabelSizeManager();
-
- private SettingsManager mSettingsManager;
- private ChannelModel mChannelModel;
- /**
- * Translucent overlay panel for displaying channel configurations,
- * processing channels, selected channels, frequency labels and lines, and
- * a cursor with a frequency readout.
- */
- public OverlayPanel( SettingsManager settingsManager,
- ChannelModel channelModel )
+ static
{
- mSettingsManager = settingsManager;
-
- if( mSettingsManager != null )
- {
- mSettingsManager.addListener( this );
- }
-
- mChannelModel = channelModel;
-
- if( mChannelModel != null )
- {
- mChannelModel.addListener( this );
- }
-
- addComponentListener( mLabelSizeMonitor );
-
- //Set the background transparent, so the spectrum display can be seen
- setOpaque( false );
-
- //Fetch color settings from settings manager
- setColors();
+ RENDERING_HINTS.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
+ }
+
+ private final static BasicStroke DASHED_STROKE = new BasicStroke(0.8f, BasicStroke.CAP_BUTT,
+ BasicStroke.JOIN_MITER, 5.0f, new float[]{2.0f, 4.0f}, 0.0f);
+
+ private static DecimalFormat CURSOR_FORMAT = new DecimalFormat("000.00000");
+ private long mFrequency = 0;
+ private int mBandwidth = 0;
+ private Point mCursorLocation = new Point(0, 0);
+ private boolean mCursorVisible = false;
+
+ private DFTSize mDFTSize = DFTSize.FFT04096;
+ private int mZoom = 0;
+ private int mDFTZoomWindowOffset = 0;
+
+ /**
+ * Colors used by this component
+ */
+ private Color mColorChannelConfig;
+ private Color mColorChannelConfigProcessing;
+ private Color mColorChannelConfigSelected;
+ private Color mColorSpectrumBackground;
+ private Color mColorSpectrumCursor;
+ private Color mColorSpectrumLine;
+
+ //Currently visible/displayable channels
+ private CopyOnWriteArrayList mVisibleChannels = new CopyOnWriteArrayList();
+ private ChannelDisplay mChannelDisplay = ChannelDisplay.ALL;
+
+ //Defines the offset at the bottom of the spectral display to account for
+ //the frequency labels
+ private double mSpectrumInset = 20.0d;
+ private LabelSizeManager mLabelSizeMonitor = new LabelSizeManager();
+
+ private SettingsManager mSettingsManager;
+ private ChannelModel mChannelModel;
+
+ /**
+ * Translucent overlay panel for displaying channel configurations,
+ * processing channels, selected channels, frequency labels and lines, and
+ * a cursor with a frequency readout.
+ */
+ public OverlayPanel(SettingsManager settingsManager, ChannelModel channelModel)
+ {
+ mSettingsManager = settingsManager;
+
+ if(mSettingsManager != null)
+ {
+ mSettingsManager.addListener(this);
+ }
+
+ mChannelModel = channelModel;
+
+ if(mChannelModel != null)
+ {
+ mChannelModel.addListener(this);
+ }
+
+ addComponentListener(mLabelSizeMonitor);
+
+ //Set the background transparent, so the spectrum display can be seen
+ setOpaque(false);
+
+ //Fetch color settings from settings manager
+ setColors();
+ }
+
+ public void dispose()
+ {
+ if(mChannelModel != null)
+ {
+ mChannelModel.removeListener(this);
+ }
+
+ mChannelModel = null;
+
+ mVisibleChannels.clear();
+
+ if(mSettingsManager != null)
+ {
+ mSettingsManager.removeListener(this);
+ }
+
+ mSettingsManager = null;
+ }
+
+ /**
+ * Sets/changes the DFT bin size
+ */
+ public void setDFTSize(DFTSize size)
+ {
+ mDFTSize = size;
+ }
+
+ public ChannelDisplay getChannelDisplay()
+ {
+ return mChannelDisplay;
+ }
+
+ public void setChannelDisplay(ChannelDisplay display)
+ {
+ mChannelDisplay = display;
+ }
+
+ public void setCursorLocation(Point point)
+ {
+ mCursorLocation = point;
+
+ repaint();
+ }
+
+ public void setCursorVisible(boolean visible)
+ {
+ mCursorVisible = visible;
+
+ repaint();
}
-
- public void dispose()
- {
- if( mChannelModel != null )
- {
- mChannelModel.removeListener( this );
- }
-
- mChannelModel = null;
-
- mVisibleChannels.clear();
-
- if( mSettingsManager != null )
- {
- mSettingsManager.removeListener( this );
- }
-
- mSettingsManager = null;
- }
-
- /**
- * Sets/changes the DFT bin size
- */
- public void setDFTSize( DFTSize size )
- {
- mDFTSize = size;
- }
-
- public ChannelDisplay getChannelDisplay()
- {
- return mChannelDisplay;
- }
- public void setChannelDisplay( ChannelDisplay display )
- {
- mChannelDisplay = display;
- }
-
- public void setCursorLocation( Point point )
- {
- mCursorLocation = point;
-
- repaint();
- }
-
- public void setCursorVisible( boolean visible )
- {
- mCursorVisible = visible;
-
- repaint();
- }
-
/**
* Sets the current zoom level (2^zoom)
- *
+ *
* 0 No Zoom
* 1 2x Zoom
* 2 4x Zoom
@@ -199,745 +185,707 @@ public class OverlayPanel extends JPanel
* 4 16x Zoom
* 5 32x Zoom
* 6 64x Zoom
- *
+ *
* @param zoom level, 0 - 6.
* @param offset into the FFT bins for start zoom window
*/
- public void setZoom( int zoom )
- {
- mZoom = zoom;
-
- mLabelSizeMonitor.update();
- }
-
- public void setZoomWindowOffset( int offset )
- {
- mDFTZoomWindowOffset = offset;
- }
-
- /**
- * Fetches the color settings from the settings manager
- */
- private void setColors()
- {
- mColorChannelConfig = getColor( ColorSettingName.CHANNEL_CONFIG );
-
- mColorChannelConfigProcessing =
- getColor( ColorSettingName.CHANNEL_CONFIG_PROCESSING );
-
- mColorChannelConfigSelected =
- getColor( ColorSettingName.CHANNEL_CONFIG_SELECTED );
-
- mColorSpectrumCursor = getColor( ColorSettingName.SPECTRUM_CURSOR );
-
- mColorSpectrumLine = getColor( ColorSettingName.SPECTRUM_LINE );
-
- mColorSpectrumBackground =
- getColor( ColorSettingName.SPECTRUM_BACKGROUND );
- }
-
- /**
- * Fetches a named color setting from the settings manager. If the setting
- * doesn't exist, creates the setting using the defaultColor
- */
- private Color getColor( ColorSettingName name )
- {
- ColorSetting setting = mSettingsManager.getColorSetting( name );
-
- return setting.getColor();
- }
-
- /**
- * Monitors for setting changes. Colors can be changed by external actions
- * and will automatically update in this class
- */
- @Override
- public void settingChanged( Setting setting )
+ public void setZoom(int zoom)
{
- if( setting instanceof ColorSetting )
- {
- ColorSetting colorSetting = (ColorSetting)setting;
-
- switch( colorSetting.getColorSettingName() )
- {
- case CHANNEL_CONFIG:
- mColorChannelConfig = colorSetting.getColor();
- break;
- case CHANNEL_CONFIG_PROCESSING:
- mColorChannelConfigProcessing = colorSetting.getColor();
- break;
- case CHANNEL_CONFIG_SELECTED:
- mColorChannelConfigSelected = colorSetting.getColor();
- break;
- case SPECTRUM_BACKGROUND:
- mColorSpectrumBackground = colorSetting.getColor();
- break;
- case SPECTRUM_CURSOR:
- mColorSpectrumCursor = colorSetting.getColor();
- break;
- case SPECTRUM_LINE:
- mColorSpectrumLine = colorSetting.getColor();
- break;
- default:
- break;
- }
- }
+ mZoom = zoom;
+
+ mLabelSizeMonitor.update();
}
-
- /**
- * Renders the channel configs, lines, labels, and cursor
- */
- @Override
- public void paintComponent( Graphics g )
- {
- super.paintComponent( g );
-
- Graphics2D graphics = (Graphics2D) g;
- graphics.setBackground( mColorSpectrumBackground );
- graphics.setRenderingHints( RENDERING_HINTS );
-
- drawFrequencies( graphics );
- drawChannels( graphics );
- drawCursor( graphics );
+ public void setZoomWindowOffset(int offset)
+ {
+ mDFTZoomWindowOffset = offset;
}
/**
- * Draws a cursor on the panel, whenever the mouse is hovering over the
+ * Fetches the color settings from the settings manager
+ */
+ private void setColors()
+ {
+ mColorChannelConfig = getColor(ColorSettingName.CHANNEL_CONFIG);
+
+ mColorChannelConfigProcessing = getColor(ColorSettingName.CHANNEL_CONFIG_PROCESSING);
+
+ mColorChannelConfigSelected = getColor(ColorSettingName.CHANNEL_CONFIG_SELECTED);
+
+ mColorSpectrumCursor = getColor(ColorSettingName.SPECTRUM_CURSOR);
+
+ mColorSpectrumLine = getColor(ColorSettingName.SPECTRUM_LINE);
+
+ mColorSpectrumBackground = getColor(ColorSettingName.SPECTRUM_BACKGROUND);
+ }
+
+ /**
+ * Fetches a named color setting from the settings manager. If the setting
+ * doesn't exist, creates the setting using the defaultColor
+ */
+ private Color getColor(ColorSettingName name)
+ {
+ ColorSetting setting = mSettingsManager.getColorSetting(name);
+
+ return setting.getColor();
+ }
+
+ /**
+ * Monitors for setting changes. Colors can be changed by external actions
+ * and will automatically update in this class
+ */
+ @Override
+ public void settingChanged(Setting setting)
+ {
+ if(setting instanceof ColorSetting)
+ {
+ ColorSetting colorSetting = (ColorSetting)setting;
+
+ switch(colorSetting.getColorSettingName())
+ {
+ case CHANNEL_CONFIG:
+ mColorChannelConfig = colorSetting.getColor();
+ break;
+ case CHANNEL_CONFIG_PROCESSING:
+ mColorChannelConfigProcessing = colorSetting.getColor();
+ break;
+ case CHANNEL_CONFIG_SELECTED:
+ mColorChannelConfigSelected = colorSetting.getColor();
+ break;
+ case SPECTRUM_BACKGROUND:
+ mColorSpectrumBackground = colorSetting.getColor();
+ break;
+ case SPECTRUM_CURSOR:
+ mColorSpectrumCursor = colorSetting.getColor();
+ break;
+ case SPECTRUM_LINE:
+ mColorSpectrumLine = colorSetting.getColor();
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ /**
+ * Renders the channel configs, lines, labels, and cursor
+ */
+ @Override
+ public void paintComponent(Graphics g)
+ {
+ super.paintComponent(g);
+
+ Graphics2D graphics = (Graphics2D)g;
+ graphics.setBackground(mColorSpectrumBackground);
+
+ graphics.setRenderingHints(RENDERING_HINTS);
+
+ drawFrequencies(graphics);
+ drawChannels(graphics);
+ drawCursor(graphics);
+ }
+
+ /**
+ * Draws a cursor on the panel, whenever the mouse is hovering over the
* panel
*/
- private void drawCursor( Graphics2D graphics )
+ private void drawCursor(Graphics2D graphics)
{
- if( mCursorVisible )
- {
- drawFrequencyLine( graphics,
- mCursorLocation.x,
- mColorSpectrumCursor );
+ if(mCursorVisible)
+ {
+ drawFrequencyLine(graphics, mCursorLocation.x, mColorSpectrumCursor);
- String frequency = CURSOR_FORMAT.format(
- getFrequencyFromAxis( mCursorLocation.getX() ) / 1E6D );
+ String frequency = CURSOR_FORMAT.format(getFrequencyFromAxis(mCursorLocation.getX()) / 1E6D);
- graphics.drawString( frequency ,
- mCursorLocation.x + 5,
- mCursorLocation.y );
+ FontMetrics fontMetrics = graphics.getFontMetrics(this.getFont());
- if( mZoom != 0 )
- {
- graphics.drawString( "Zoom: " + (int)Math.pow( 2.0, mZoom ) + "x",
- mCursorLocation.x + 17, mCursorLocation.y + 11 );
- }
- }
+ Rectangle2D rect = fontMetrics.getStringBounds(frequency, graphics);
+
+ if(mCursorLocation.y > rect.getHeight())
+ {
+ graphics.drawString(frequency, mCursorLocation.x + 5, mCursorLocation.y);
+ }
+
+ if(mZoom != 0)
+ {
+ graphics.drawString("Zoom: " + (int)Math.pow(2.0, mZoom) + "x", mCursorLocation.x + 17,
+ mCursorLocation.y + 11);
+ }
+ }
}
-
+
/**
* Draws the frequency lines and labels every 10kHz
*/
- private void drawFrequencies( Graphics2D graphics )
+ private void drawFrequencies(Graphics2D graphics)
{
- Stroke currentStroke = graphics.getStroke();
-
-// graphics.setStroke( DASHED_STROKE );
+ Stroke currentStroke = graphics.getStroke();
- long minFrequency = getMinDisplayFrequency();
- long maxFrequency = getMaxDisplayFrequency();
+ long minFrequency = getMinDisplayFrequency();
+ long maxFrequency = getMaxDisplayFrequency();
- //Frequency increments for label and tick spacing
- int label = mLabelSizeMonitor.getLabelIncrement( graphics );
- int major = mLabelSizeMonitor.getMajorTickIncrement( graphics );
- int minor = mLabelSizeMonitor.getMinorTickIncrement( graphics );
+ //Frequency increments for label and tick spacing
+ int label = mLabelSizeMonitor.getLabelIncrement(graphics);
+ int major = mLabelSizeMonitor.getMajorTickIncrement(graphics);
+ int minor = mLabelSizeMonitor.getMinorTickIncrement(graphics);
- //Avoid divide by zero error
- if( minor == 0 )
- {
- minor = 1;
- }
-
- //Adjust the start frequency to a multiple of the minor tick spacing
- long frequency = minFrequency - ( minFrequency % minor );
-
- while( frequency < maxFrequency )
- {
- if( frequency % label == 0 )
- {
- drawFrequencyLineAndLabel( graphics, frequency );
- }
- else if( frequency % major == 0 )
- {
- drawTickLine( graphics, frequency, true );
- }
- else
- {
- drawTickLine( graphics, frequency, false );
- }
-
- frequency += minor;
- }
-
-// graphics.setStroke( currentStroke );
+ //Avoid divide by zero error
+ if(minor == 0)
+ {
+ minor = 1;
+ }
+
+ //Adjust the start frequency to a multiple of the minor tick spacing
+ long frequency = minFrequency - (minFrequency % minor);
+
+ while(frequency < maxFrequency)
+ {
+ if(frequency % label == 0)
+ {
+ drawFrequencyLineAndLabel(graphics, frequency);
+ }
+ else if(frequency % major == 0)
+ {
+ drawTickLine(graphics, frequency, true);
+ }
+ else
+ {
+ drawTickLine(graphics, frequency, false);
+ }
+
+ frequency += minor;
+ }
}
-
+
/**
* Draws a vertical line and a corresponding frequency label at the bottom
*/
- private void drawFrequencyLineAndLabel( Graphics2D graphics, long frequency )
+ private void drawFrequencyLineAndLabel(Graphics2D graphics, long frequency)
{
- double xAxis = getAxisFromFrequency( frequency );
-
- drawFrequencyLine( graphics, xAxis, mColorSpectrumLine );
-
- drawTickLine( graphics, frequency, false );
+ double xAxis = getAxisFromFrequency(frequency);
- graphics.setColor( mColorSpectrumLine );
+ drawFrequencyLine(graphics, xAxis, mColorSpectrumLine);
- drawFrequencyLabel( graphics, xAxis, frequency );
+ drawTickLine(graphics, frequency, false);
+
+ graphics.setColor(mColorSpectrumLine);
+
+ drawFrequencyLabel(graphics, xAxis, frequency);
}
/**
* Draws a vertical line at the xaxis
*/
- private void drawTickLine( Graphics2D graphics, long frequency, boolean major )
+ private void drawTickLine(Graphics2D graphics, long frequency, boolean major)
{
- graphics.setColor( mColorSpectrumLine );
-
- double xAxis = getAxisFromFrequency( frequency );
+ graphics.setColor(mColorSpectrumLine);
- double start = getSize().getHeight() - mSpectrumInset;
- double end = start + ( major ? 9.0d : 3.0d );
-
- graphics.draw( new Line2D.Double( xAxis, start, xAxis, end ) );
+ double xAxis = getAxisFromFrequency(frequency);
+
+ double start = getSize().getHeight() - mSpectrumInset;
+ double end = start + (major ? 9.0d : 3.0d);
+
+ graphics.draw(new Line2D.Double(xAxis, start, xAxis, end));
}
/**
* Draws a vertical line at the xaxis
*/
- private void drawFrequencyLine( Graphics2D graphics, double xaxis, Color color )
+ private void drawFrequencyLine(Graphics2D graphics, double xaxis, Color color)
{
- graphics.setColor( color );
-
- graphics.draw( new Line2D.Double( xaxis, 0.0d,
- xaxis, getSize().getHeight() - mSpectrumInset ) );
+ graphics.setColor(color);
+
+ graphics.draw(new Line2D.Double(xaxis, 0.0d, xaxis, getSize().getHeight() - mSpectrumInset));
}
/**
* Draws a vertical line at the xaxis
*/
- private void drawChannelCenterLine( Graphics2D graphics, double xaxis )
+ private void drawChannelCenterLine(Graphics2D graphics, double xaxis)
{
- double height = getSize().getHeight() - mSpectrumInset;
+ double height = getSize().getHeight() - mSpectrumInset;
- graphics.setColor( Color.LIGHT_GRAY );
+ graphics.setColor(Color.LIGHT_GRAY);
- graphics.draw( new Line2D.Double( xaxis, height * 0.65d,
- xaxis, height - 1.0d ) );
+ graphics.draw(new Line2D.Double(xaxis, height * 0.65d, xaxis, height - 1.0d));
}
-
+
/**
* Draws a vertical line at the xaxis
*/
- private void drawAFC( Graphics2D graphics, double frequencyAxis, double errorAxis )
+ private void drawAFC(Graphics2D graphics, double frequencyAxis, double errorAxis)
{
- double height = getSize().getHeight() - mSpectrumInset;
- double lineHeight = height * 0.75d;
+ double height = getSize().getHeight() - mSpectrumInset;
+ double lineHeight = height * 0.75d;
- graphics.setColor( Color.YELLOW );
+ graphics.setColor(Color.YELLOW);
- //Vertical frequency error line
- graphics.draw( new Line2D.Double( errorAxis, lineHeight,
- errorAxis, height - 1.0d ) );
+ //Vertical frequency error line
+ graphics.draw(new Line2D.Double(errorAxis, lineHeight, errorAxis, height - 1.0d));
- //Horizontal line connecting frequency and error lines
- graphics.draw( new Line2D.Double( frequencyAxis, lineHeight,
- errorAxis, lineHeight ) );
+ //Horizontal line connecting frequency and error lines
+ graphics.draw(new Line2D.Double(frequencyAxis, lineHeight, errorAxis, lineHeight));
}
-
+
/**
* Returns the x-axis value corresponding to the frequency
*/
- private double getAxisFromFrequency( long frequency )
+ private double getAxisFromFrequency(long frequency)
{
- double screenWidth = (double)getSize().getWidth();
+ double screenWidth = (double)getSize().getWidth();
- double pixelsPerBin = screenWidth / (double)mDFTSize.getSize();
-
- double pixelOffsetToMinDisplayFrequency = pixelsPerBin * 2.0d;
+ double pixelsPerBin = screenWidth / (double)mDFTSize.getSize();
- //Calculate frequency offset from the min frequency
- double frequencyOffset = (double)( frequency - getMinDisplayFrequency() );
+ double pixelOffsetToMinDisplayFrequency = pixelsPerBin * 2.0d;
- //Determine ratio of frequency offset to overall bandwidth
- double ratio = frequencyOffset / (double)getDisplayBandwidth();
+ //Calculate frequency offset from the min frequency
+ double frequencyOffset = (double)(frequency - getMinDisplayFrequency());
- //Apply the ratio to the screen width minus 1 bin width
- double screenOffset = screenWidth * ratio;
-
- return pixelOffsetToMinDisplayFrequency + screenOffset;
+ //Determine ratio of frequency offset to overall bandwidth
+ double ratio = frequencyOffset / (double)getDisplayBandwidth();
+
+ //Apply the ratio to the screen width minus 1 bin width
+ double screenOffset = screenWidth * ratio;
+
+ return pixelOffsetToMinDisplayFrequency + screenOffset;
}
/**
* Returns the frequency corresponding to the x-axis value using the current
* zoom level.
*/
- public long getFrequencyFromAxis( double xAxis )
+ public long getFrequencyFromAxis(double xAxis)
{
- double width = getSize().getWidth();
-
- double offset = xAxis / width;
-
- long frequency = getMinDisplayFrequency() +
- Math.round( (double)getDisplayBandwidth() * offset );
-
- if( frequency > ( getMaxFrequency() ) )
- {
- frequency = getMaxFrequency();
- }
-
- return frequency;
+ double width = getSize().getWidth();
+
+ double offset = xAxis / width;
+
+ long frequency = getMinDisplayFrequency() + Math.round((double)getDisplayBandwidth() * offset);
+
+ if(frequency > (getMaxFrequency()))
+ {
+ frequency = getMaxFrequency();
+ }
+
+ return frequency;
}
/**
* Draws a frequency label at the x-axis position, at the bottom of the panel
*/
- private void drawFrequencyLabel( Graphics2D graphics,
- double xaxis,
- long frequency )
+ private void drawFrequencyLabel(Graphics2D graphics, double xaxis, long frequency)
{
- String label = mLabelSizeMonitor.format( frequency );
-
- FontMetrics fontMetrics = graphics.getFontMetrics( this.getFont() );
+ String label = mLabelSizeMonitor.format(frequency);
- Rectangle2D rect = fontMetrics.getStringBounds( label, graphics );
+ FontMetrics fontMetrics = graphics.getFontMetrics(this.getFont());
- float xOffset = (float)rect.getWidth() / 2;
+ Rectangle2D rect = fontMetrics.getStringBounds(label, graphics);
- graphics.drawString( label, (float)( xaxis - xOffset ),
- (float)( getSize().getHeight() - 2.0f ) );
+ float xOffset = (float)rect.getWidth() / 2;
+
+ graphics.drawString(label, (float)(xaxis - xOffset), (float)(getSize().getHeight() - 2.0f));
}
-
+
/**
* Draws visible channel configs as translucent shaded frequency regions
*/
- private void drawChannels( Graphics2D graphics )
+ private void drawChannels(Graphics2D graphics)
{
- for( Channel channel: mVisibleChannels )
- {
- if( mChannelDisplay == ChannelDisplay.ALL ||
- ( mChannelDisplay == ChannelDisplay.ENABLED &&
- channel.getEnabled() ) )
- {
- //Choose the correct background color to use
- if( channel.isSelected() )
- {
- graphics.setColor( mColorChannelConfigSelected );
- }
- else if( channel.getEnabled() )
- {
- graphics.setColor( mColorChannelConfigProcessing );
- }
- else
- {
- graphics.setColor( mColorChannelConfig );
- }
-
- TunerChannel tunerChannel = channel.getTunerChannel();
-
- if( tunerChannel != null )
+ for(Channel channel : mVisibleChannels)
+ {
+ if(mChannelDisplay == ChannelDisplay.ALL ||
+ (mChannelDisplay == ChannelDisplay.ENABLED && channel.getEnabled()))
+ {
+ //Choose the correct background color to use
+ if(channel.isSelected())
{
- double xAxis = getAxisFromFrequency( tunerChannel.getFrequency() );
+ graphics.setColor(mColorChannelConfigSelected);
+ }
+ else if(channel.getEnabled())
+ {
+ graphics.setColor(mColorChannelConfigProcessing);
+ }
+ else
+ {
+ graphics.setColor(mColorChannelConfig);
+ }
- double width = (double)( tunerChannel.getBandwidth() ) /
- (double)getDisplayBandwidth() * getSize().getWidth();
-
- Rectangle2D.Double box =
- new Rectangle2D.Double( xAxis - ( width / 2.0d ),
- 0.0d, width, getSize().getHeight() - mSpectrumInset );
+ TunerChannel tunerChannel = channel.getTunerChannel();
+
+ if(tunerChannel != null)
+ {
+ double xAxis = getAxisFromFrequency(tunerChannel.getFrequency());
+
+ double width = (double)(tunerChannel.getBandwidth()) / (double)getDisplayBandwidth() * getSize().getWidth();
+
+ Rectangle2D.Double box =
+ new Rectangle2D.Double(xAxis - (width / 2.0d), 0.0d, width, getSize().getHeight() - mSpectrumInset);
//Fill the box with the correct color
- graphics.fill( box );
+ graphics.fill(box);
- graphics.draw( box );
+ graphics.draw(box);
//Change to the line color to render the channel name, etc.
- graphics.setColor( mColorSpectrumLine );
+ graphics.setColor(mColorSpectrumLine);
//Draw the labels starting at yAxis position 0
double yAxis = 0;
-
+
//Draw the system label and adjust the y-axis position
String system = channel.hasSystem() ? channel.getSystem() : " ";
-
- yAxis += drawLabel( graphics,
- system,
- this.getFont(),
- xAxis,
- yAxis,
- width );
+
+ yAxis += drawLabel(graphics, system, this.getFont(), xAxis, yAxis, width);
//Draw the site label and adjust the y-axis position
String site = channel.hasSite() ? channel.getSite() : " ";
- yAxis += drawLabel( graphics,
- site,
- this.getFont(),
- xAxis,
- yAxis,
- width );
+ yAxis += drawLabel(graphics, site, this.getFont(), xAxis, yAxis, width);
//Draw the channel label and adjust the y-axis position
- yAxis += drawLabel( graphics,
- channel.getName(),
- this.getFont(),
- xAxis,
- yAxis,
- width );
-
+ yAxis += drawLabel(graphics, channel.getName(), this.getFont(), xAxis, yAxis, width);
+
//Draw the decoder label
- drawLabel( graphics, channel.getDecodeConfiguration().getDecoderType().getShortDisplayString(),
- this.getFont(), xAxis, yAxis, width );
-
- long frequency = tunerChannel.getFrequency();
-
- double frequencyAxis = getAxisFromFrequency( frequency );
-
- drawChannelCenterLine( graphics, frequencyAxis );
+ drawLabel(graphics, channel.getDecodeConfiguration().getDecoderType().getShortDisplayString(),
+ this.getFont(), xAxis, yAxis, width);
+
+ long frequency = tunerChannel.getFrequency();
+
+ double frequencyAxis = getAxisFromFrequency(frequency);
+
+ drawChannelCenterLine(graphics, frequencyAxis);
/* Draw Automatic Frequency Control line */
int correction = channel.getChannelFrequencyCorrection();
-
- if( correction != 0 )
+
+ if(correction != 0)
{
- long error = frequency + correction;
-
- drawAFC( graphics, frequencyAxis, getAxisFromFrequency( error ) );
+ long error = frequency + correction;
+
+ drawAFC(graphics, frequencyAxis, getAxisFromFrequency(error));
}
}
- }
- }
+ }
+ }
}
-
-
+
+
/**
* Draws a textual label at the x/y position, clipping the end of the text
* to fit within the maxwidth value.
- *
+ *
* @return height of the drawn label
*/
- private double drawLabel( Graphics2D graphics, String text, Font font,
- double x, double baseY, double maxWidth )
+ private double drawLabel(Graphics2D graphics, String text, Font font, double x, double baseY, double maxWidth)
{
- FontMetrics fontMetrics = graphics.getFontMetrics( font );
-
- Rectangle2D label = fontMetrics.getStringBounds( text, graphics );
-
+ FontMetrics fontMetrics = graphics.getFontMetrics(font);
+
+ Rectangle2D label = fontMetrics.getStringBounds(text, graphics);
+
double offset = label.getWidth() / 2.0d;
double y = baseY + label.getHeight();
-
+
/**
* If the label is wider than the max width, left justify the text and
* clip the end of it
*/
- if( offset > ( maxWidth / 2.0d ) )
+ if(offset > (maxWidth / 2.0d))
{
- label.setRect( x - ( maxWidth / 2.0d ),
- y - label.getHeight(),
- maxWidth,
- label.getHeight() );
-
- graphics.setClip( label );
+ label.setRect(x - (maxWidth / 2.0d), y - label.getHeight(), maxWidth, label.getHeight());
- graphics.drawString( text,
- (float)( x - ( maxWidth / 2.0d ) ), (float)y );
-
- graphics.setClip( null );
+ graphics.setClip(label);
+
+ graphics.drawString(text, (float)(x - (maxWidth / 2.0d)), (float)y);
+
+ graphics.setClip(null);
}
else
{
- graphics.drawString( text, (float)( x - offset ), (float)y );
+ graphics.drawString(text, (float)(x - offset), (float)y);
}
-
+
return label.getHeight();
}
/**
* Frequency change event handler
*/
- @Override
- public void frequencyChanged( FrequencyChangeEvent event )
- {
- switch( event.getEvent() )
- {
- case NOTIFICATION_SAMPLE_RATE_CHANGE:
- mBandwidth = event.getValue().intValue();
- mLabelSizeMonitor.update();
- break;
- case NOTIFICATION_FREQUENCY_CHANGE:
- mFrequency = event.getValue().longValue();
- mLabelSizeMonitor.update();
- break;
- default:
- break;
- }
-
- /**
- * Reset the visible channels list
- */
- mVisibleChannels.clear();
- mVisibleChannels.addAll(
- mChannelModel.getChannelsInFrequencyRange( getMinFrequency(),
- getMaxFrequency() ) );
- }
-
- /**
- * Channel change event handler
- */
@Override
- @SuppressWarnings( "incomplete-switch" )
- public void channelChanged( ChannelEvent event )
- {
- Channel channel = event.getChannel();
-
- switch( event.getEvent() )
- {
- case NOTIFICATION_ADD:
- case NOTIFICATION_PROCESSING_START:
- if( !mVisibleChannels.contains( channel ) &&
- channel.isWithin( getMinFrequency(), getMaxFrequency() ) )
- {
- mVisibleChannels.add( channel );
- }
- break;
- case NOTIFICATION_DELETE:
- mVisibleChannels.remove( channel );
- break;
- case NOTIFICATION_PROCESSING_STOP:
- if( channel.getChannelType() == ChannelType.TRAFFIC )
- {
- mVisibleChannels.remove( channel );
- }
- break;
- case NOTIFICATION_CONFIGURATION_CHANGE:
- if( mVisibleChannels.contains( channel ) &&
- !channel.isWithin( getMinFrequency(), getMaxFrequency() ) )
- {
- mVisibleChannels.remove( channel );
- }
-
- if( !mVisibleChannels.contains( channel ) &&
- channel.isWithin( getMinFrequency(), getMaxFrequency() ) )
- {
- mVisibleChannels.add( channel );
- }
- break;
- default:
- break;
- }
-
- repaint();
- }
-
- public int getBandwidth()
+ public void frequencyChanged(FrequencyChangeEvent event)
{
- return mBandwidth;
- }
-
- /**
- * Currently displayed minimum frequency
- */
- public long getMinFrequency()
- {
- return mFrequency - ( mBandwidth / 2 );
- }
-
- /**
- * Currently displayed maximum frequency
- */
- public long getMaxFrequency()
- {
- return mFrequency + ( mBandwidth / 2 );
- }
-
- public boolean containsFrequency( long frequency )
- {
- return Math.abs( mFrequency - frequency ) <= ( mBandwidth / 2 );
- }
-
- private long getMinDisplayFrequency()
- {
- double bandwidthPerBin = (double)mBandwidth / (double)( mDFTSize.getSize() );
-
- return getMinFrequency() + (int)( ( mDFTZoomWindowOffset ) * bandwidthPerBin );
- }
-
- private long getMaxDisplayFrequency()
- {
- return getMinDisplayFrequency() + getDisplayBandwidth();
- }
-
- private int getDisplayBandwidth()
- {
- if( mZoom != 0 )
- {
- return mBandwidth / (int)Math.pow( 2.0, mZoom );
- }
-
- return mBandwidth;
- }
-
- /**
- * Returns a list of channel configs that contain the frequency within their
- * min/max frequency settings.
- */
- public ArrayList getChannelsAtFrequency( long frequency )
- {
- ArrayList configs = new ArrayList();
-
- for( Channel config: mVisibleChannels )
- {
- TunerChannel channel = config.getTunerChannel();
-
- if( channel != null &&
- channel.getMinFrequency() <= frequency &&
- channel.getMaxFrequency() >= frequency )
- {
- configs.add( config );
- }
- }
-
- return configs;
- }
-
- @Override
- public void settingDeleted( Setting setting ) { /* not implemented */ }
-
- /**
- * Calculates correct spacing and format for frequency labels and major/minor
- * tick lines based on current frequency, bandwidth, zoom and screen size.
- */
- public class LabelSizeManager implements ComponentListener
- {
- private static final double LABEL_FILL_THRESHOLD = 0.5d;
-
- private DecimalFormat mFrequencyFormat = new DecimalFormat( "0.0" );
-
- private boolean mUpdateRequired = true;
- private int mLabelIncrement = 1;
- private int mMajorTickIncrement = 1;
- private int mMinorTickIncrement = 1;
-
- public String format( long frequency )
- {
- return mFrequencyFormat.format( (double)frequency / 1E6D );
- }
-
- private void setPrecision( int precision )
- {
- if( precision < 1 )
- {
- precision = 1;
- }
-
- if( precision > 5 )
- {
- precision = 5;
- }
-
- mFrequencyFormat.setMinimumFractionDigits( precision );
- mFrequencyFormat.setMaximumFractionDigits( precision );
- }
-
- private void update( Graphics2D graphics )
- {
- if( mUpdateRequired )
- {
- //Set maximum precision as a starting point
- setPrecision( 5 );
-
- FontMetrics fontMetrics =
- graphics.getFontMetrics( OverlayPanel.this.getFont() );
-
- int maxLabelWidth = fontMetrics.stringWidth( format( getMaxDisplayFrequency() ) );
-
- double maxLabels = ( (double)OverlayPanel.this.getWidth() *
- LABEL_FILL_THRESHOLD ) /
- (double)maxLabelWidth;
-
- //Calculate the next smallest base 10 value for the major increment
- int power = (int)Math.log10( (double)getDisplayBandwidth() / maxLabels );
-
- //Set the number of decimal places to display in frequency labels
- int precision = 5 - power;
-
- int start = (int)Math.pow( 10.0, power + 1 );
-
- int minimum = (int)Math.pow( 10.0, power );
-
- int labelIncrement = start;
-
- while( ( (double)getDisplayBandwidth() /
- (double)labelIncrement ) < maxLabels &&
- labelIncrement >= minimum )
- {
- labelIncrement /= 2;
- precision++;
- }
-
- if( labelIncrement == minimum )
- {
- precision = 5 - power;
- }
-
- setPrecision( precision );
-
- mLabelIncrement = labelIncrement;
- mMajorTickIncrement = labelIncrement / 2;
- mMinorTickIncrement = labelIncrement / 10;
-
- mUpdateRequired = false;
- }
- }
-
- /**
- * Forces the display to update the label and frequency display
- * calculations
- */
- public void update()
- {
- mUpdateRequired = true;
- }
-
- public int getMajorTickIncrement( Graphics2D graphics )
- {
- //Check to see if a calculation update is scheduled
- update( graphics );
-
- return mMajorTickIncrement;
- }
-
- public int getMinorTickIncrement( Graphics2D graphics )
- {
- return mMinorTickIncrement;
- }
-
- public int getLabelIncrement( Graphics2D graphics )
- {
- return mLabelIncrement;
- }
-
- @Override
- public void componentResized( ComponentEvent arg0 )
+ switch(event.getEvent())
{
- update();
+ case NOTIFICATION_SAMPLE_RATE_CHANGE:
+ mBandwidth = event.getValue().intValue();
+ mLabelSizeMonitor.update();
+ break;
+ case NOTIFICATION_FREQUENCY_CHANGE:
+ mFrequency = event.getValue().longValue();
+ mLabelSizeMonitor.update();
+ break;
+ default:
+ break;
}
- public void componentHidden( ComponentEvent arg0 ) {}
- public void componentMoved( ComponentEvent arg0 ) {}
- public void componentShown( ComponentEvent arg0 ) {}
+ /**
+ * Reset the visible channels list
+ */
+ mVisibleChannels.clear();
+ mVisibleChannels.addAll(mChannelModel.getChannelsInFrequencyRange(getMinFrequency(), getMaxFrequency()));
+ }
- }
+ /**
+ * Channel change event handler
+ */
+ @Override
+ @SuppressWarnings("incomplete-switch")
+ public void channelChanged(ChannelEvent event)
+ {
+ Channel channel = event.getChannel();
- public enum ChannelDisplay
- {
- ALL, ENABLED, NONE;
- }
+ switch(event.getEvent())
+ {
+ case NOTIFICATION_ADD:
+ case NOTIFICATION_PROCESSING_START:
+ if(!mVisibleChannels.contains(channel) && channel.isWithin(getMinFrequency(), getMaxFrequency()))
+ {
+ mVisibleChannels.add(channel);
+ }
+ break;
+ case NOTIFICATION_DELETE:
+ mVisibleChannels.remove(channel);
+ break;
+ case NOTIFICATION_PROCESSING_STOP:
+ if(channel.getChannelType() == ChannelType.TRAFFIC)
+ {
+ mVisibleChannels.remove(channel);
+ }
+ break;
+ case NOTIFICATION_CONFIGURATION_CHANGE:
+ if(mVisibleChannels.contains(channel) && !channel.isWithin(getMinFrequency(), getMaxFrequency()))
+ {
+ mVisibleChannels.remove(channel);
+ }
+
+ if(!mVisibleChannels.contains(channel) && channel.isWithin(getMinFrequency(), getMaxFrequency()))
+ {
+ mVisibleChannels.add(channel);
+ }
+ break;
+ default:
+ break;
+ }
+
+ repaint();
+ }
+
+ public int getBandwidth()
+ {
+ return mBandwidth;
+ }
+
+ /**
+ * Currently displayed minimum frequency
+ */
+ public long getMinFrequency()
+ {
+ return mFrequency - (mBandwidth / 2);
+ }
+
+ /**
+ * Currently displayed maximum frequency
+ */
+ public long getMaxFrequency()
+ {
+ return mFrequency + (mBandwidth / 2);
+ }
+
+ public boolean containsFrequency(long frequency)
+ {
+ return Math.abs(mFrequency - frequency) <= (mBandwidth / 2);
+ }
+
+ private long getMinDisplayFrequency()
+ {
+ double bandwidthPerBin = (double)mBandwidth / (double)(mDFTSize.getSize());
+
+ return getMinFrequency() + (int)((mDFTZoomWindowOffset) * bandwidthPerBin);
+ }
+
+ private long getMaxDisplayFrequency()
+ {
+ return getMinDisplayFrequency() + getDisplayBandwidth();
+ }
+
+ private int getDisplayBandwidth()
+ {
+ if(mZoom != 0)
+ {
+ return mBandwidth / (int)Math.pow(2.0, mZoom);
+ }
+
+ return mBandwidth;
+ }
+
+ /**
+ * Returns a list of channel configs that contain the frequency within their
+ * min/max frequency settings.
+ */
+ public ArrayList getChannelsAtFrequency(long frequency)
+ {
+ ArrayList configs = new ArrayList();
+
+ for(Channel config : mVisibleChannels)
+ {
+ TunerChannel channel = config.getTunerChannel();
+
+ if(channel != null && channel.getMinFrequency() <= frequency && channel.getMaxFrequency() >= frequency)
+ {
+ configs.add(config);
+ }
+ }
+
+ return configs;
+ }
+
+ @Override
+ public void settingDeleted(Setting setting)
+ { /* not implemented */ }
+
+ /**
+ * Calculates correct spacing and format for frequency labels and major/minor
+ * tick lines based on current frequency, bandwidth, zoom and screen size.
+ */
+ public class LabelSizeManager implements ComponentListener
+ {
+ private static final double LABEL_FILL_THRESHOLD = 0.5d;
+
+ private DecimalFormat mFrequencyFormat = new DecimalFormat("0.0");
+
+ private boolean mUpdateRequired = true;
+ private int mLabelIncrement = 1;
+ private int mMajorTickIncrement = 1;
+ private int mMinorTickIncrement = 1;
+
+ public String format(long frequency)
+ {
+ return mFrequencyFormat.format((double)frequency / 1E6D);
+ }
+
+ private void setPrecision(int precision)
+ {
+ if(precision < 1)
+ {
+ precision = 1;
+ }
+
+ if(precision > 5)
+ {
+ precision = 5;
+ }
+
+ mFrequencyFormat.setMinimumFractionDigits(precision);
+ mFrequencyFormat.setMaximumFractionDigits(precision);
+ }
+
+ private void update(Graphics2D graphics)
+ {
+ if(mUpdateRequired)
+ {
+ //Set maximum precision as a starting point
+ setPrecision(5);
+
+ FontMetrics fontMetrics =
+ graphics.getFontMetrics(OverlayPanel.this.getFont());
+
+ int maxLabelWidth = fontMetrics.stringWidth(format(getMaxDisplayFrequency()));
+
+ double maxLabels = ((double)OverlayPanel.this.getWidth() * LABEL_FILL_THRESHOLD) / (double)maxLabelWidth;
+
+ //Calculate the next smallest base 10 value for the major increment
+ int power = (int)Math.log10((double)getDisplayBandwidth() / maxLabels);
+
+ //Set the number of decimal places to display in frequency labels
+ int precision = 5 - power;
+
+ int start = (int)Math.pow(10.0, power + 1);
+
+ int minimum = (int)Math.pow(10.0, power);
+
+ int labelIncrement = start;
+
+ while(((double)getDisplayBandwidth() / (double)labelIncrement) < maxLabels && labelIncrement >= minimum)
+ {
+ labelIncrement /= 2;
+ precision++;
+ }
+
+ if(labelIncrement == minimum)
+ {
+ precision = 5 - power;
+ }
+
+ setPrecision(precision);
+
+ mLabelIncrement = labelIncrement;
+ mMajorTickIncrement = labelIncrement / 2;
+ mMinorTickIncrement = labelIncrement / 10;
+
+ mUpdateRequired = false;
+ }
+ }
+
+ /**
+ * Forces the display to update the label and frequency display
+ * calculations
+ */
+ public void update()
+ {
+ mUpdateRequired = true;
+ }
+
+ public int getMajorTickIncrement(Graphics2D graphics)
+ {
+ //Check to see if a calculation update is scheduled
+ update(graphics);
+
+ return mMajorTickIncrement;
+ }
+
+ public int getMinorTickIncrement(Graphics2D graphics)
+ {
+ return mMinorTickIncrement;
+ }
+
+ public int getLabelIncrement(Graphics2D graphics)
+ {
+ return mLabelIncrement;
+ }
+
+ @Override
+ public void componentResized(ComponentEvent arg0)
+ {
+ update();
+ }
+
+ public void componentHidden(ComponentEvent arg0)
+ {
+ }
+
+ public void componentMoved(ComponentEvent arg0)
+ {
+ }
+
+ public void componentShown(ComponentEvent arg0)
+ {
+ }
+
+ }
+
+ public enum ChannelDisplay
+ {
+ ALL, ENABLED, NONE;
+ }
}