Files
sdrtrunk/src/main/java/io/github/dsheirer/spectrum/OverlayPanel.java
Denny 030fc1617c 328 Channel Auto-Start capability. Adds auto-start and auto-start
ordering to each channel configuration to provide the user with greater
control over initial application startup configuration.

Adds new dialog window that displays on startup that allows the user to
invoke/cancel auto-start, or simply allow the timer to expire whereby
the channels will be auto-started.

Updates channel table model to include an auto-start column and relabels
the 'Enabled' column to read 'Playing'.

Updates channel editor to change the 'Enable/Disable' button to read
'Start/Stop'.

Changes the 'enabled' property of the channel configuration to indicate
the current 'processing' status - isProcessing().

Channel's XML configuration re-purposes the 'enabled' property to indicate
auto-start and adds a new (optional) auto-start 'order' attribute.
2018-02-10 08:09:43 -05:00

922 lines
28 KiB
Java

/*******************************************************************************
* 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 <http://www.gnu.org/licenses/>
*
******************************************************************************/
package io.github.dsheirer.spectrum;
import io.github.dsheirer.controller.channel.Channel;
import io.github.dsheirer.controller.channel.Channel.ChannelType;
import io.github.dsheirer.controller.channel.ChannelEvent;
import io.github.dsheirer.controller.channel.ChannelEventListener;
import io.github.dsheirer.controller.channel.ChannelModel;
import io.github.dsheirer.settings.ColorSetting;
import io.github.dsheirer.settings.ColorSetting.ColorSettingName;
import io.github.dsheirer.settings.Setting;
import io.github.dsheirer.settings.SettingChangeListener;
import io.github.dsheirer.settings.SettingsManager;
import io.github.dsheirer.source.tuner.TunerChannel;
import io.github.dsheirer.source.tuner.frequency.FrequencyChangeEvent;
import io.github.dsheirer.source.tuner.frequency.IFrequencyChangeProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.JPanel;
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;
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 final DecimalFormat PPM_FORMATTER = new DecimalFormat( "#.0" );
private final static RenderingHints RENDERING_HINTS = new RenderingHints(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
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 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<Channel> mVisibleChannels = new CopyOnWriteArrayList<Channel>();
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();
}
/**
* Sets the current zoom level (2^zoom)
*
* 0 No Zoom
* 1 2x Zoom
* 2 4x Zoom
* 3 8x Zoom
* 4 16x Zoom
* 5 32x Zoom
* 6 64x Zoom
*
* @param zoom level, 0 - 6.
*/
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)
{
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)
{
if(mCursorVisible)
{
drawFrequencyLine(graphics, mCursorLocation.x, mColorSpectrumCursor);
String frequency = CURSOR_FORMAT.format(getFrequencyFromAxis(mCursorLocation.getX()) / 1E6D);
FontMetrics fontMetrics = graphics.getFontMetrics(this.getFont());
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)
{
Stroke currentStroke = graphics.getStroke();
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);
//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)
{
double xAxis = getAxisFromFrequency(frequency);
drawFrequencyLine(graphics, xAxis, mColorSpectrumLine);
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)
{
graphics.setColor(mColorSpectrumLine);
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)
{
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)
{
double height = getSize().getHeight() - mSpectrumInset;
graphics.setColor(Color.LIGHT_GRAY);
graphics.draw(new Line2D.Double(xaxis, height * 0.65d, xaxis, height - 1.0d));
}
/**
* Draws the Automatic Frequency Control (AFC) channel center offset
*/
private void drawAFC(Graphics2D graphics, double frequencyAxis, double errorAxis, double bandwidth,
int correction, long frequency)
{
double height = getSize().getHeight() - mSpectrumInset;
double verticalAxisTop = height * 0.88d;
double verticalAxisBottom = height * 0.98d;
double halfBandwidth = bandwidth / 2.0;
double errorEdgeStart = errorAxis - halfBandwidth;
double errorEdgeStop = errorAxis + halfBandwidth;
graphics.setColor(Color.YELLOW);
//Horizontal line connecting frequency and error line
graphics.draw(new Line2D.Double(errorEdgeStart, verticalAxisBottom, errorEdgeStop, verticalAxisBottom));
//Vertical band edge lines
graphics.draw(new Line2D.Double(errorEdgeStart, verticalAxisTop, errorEdgeStart, verticalAxisBottom));
graphics.draw(new Line2D.Double(errorEdgeStop, verticalAxisTop, errorEdgeStop, verticalAxisBottom));
double ppm = (double)correction / ((double)frequency / 1E6d);
String label = "PPM " + PPM_FORMATTER.format(ppm) ;
FontMetrics fontMetrics = graphics.getFontMetrics(this.getFont());
Rectangle2D rect = fontMetrics.getStringBounds(label, graphics);
//Only render the correction value label if the spacing is large enough
if(rect.getWidth() <= bandwidth && rect.getHeight() * 5 <= height)
{
graphics.drawString(label, (float)(errorEdgeStart + 1.0), (float)(verticalAxisBottom - 2.0));
}
}
/**
* Returns the x-axis value corresponding to the frequency
*/
private double getAxisFromFrequency(long frequency)
{
double screenWidth = (double)getSize().getWidth();
double pixelsPerBin = screenWidth / (double)mDFTSize.getSize();
double pixelOffsetToMinDisplayFrequency = pixelsPerBin * 2.0d;
//Calculate frequency offset from the min frequency
double frequencyOffset = (double)(frequency - getMinDisplayFrequency());
//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)
{
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)
{
String label = mLabelSizeMonitor.format(frequency);
FontMetrics fontMetrics = graphics.getFontMetrics(this.getFont());
Rectangle2D rect = fontMetrics.getStringBounds(label, graphics);
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)
{
for(Channel channel : mVisibleChannels)
{
if(mChannelDisplay == ChannelDisplay.ALL ||
(mChannelDisplay == ChannelDisplay.ENABLED && channel.isProcessing()))
{
//Choose the correct background color to use
if(channel.isSelected())
{
graphics.setColor(mColorChannelConfigSelected);
}
else if(channel.isProcessing())
{
graphics.setColor(mColorChannelConfigProcessing);
}
else
{
graphics.setColor(mColorChannelConfig);
}
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.draw(box);
//Change to the line color to render the channel name, etc.
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);
//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);
//Draw the channel label and adjust the y-axis position
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);
/* Draw Automatic Frequency Control line */
int correction = channel.getChannelFrequencyCorrection();
if(correction != 0)
{
long error = frequency + correction;
drawAFC(graphics, frequencyAxis, getAxisFromFrequency(error), width, correction,
tunerChannel.getFrequency());
}
}
}
}
}
/**
* 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)
{
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))
{
label.setRect(x - (maxWidth / 2.0d), y - label.getHeight(), maxWidth, label.getHeight());
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);
}
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()
{
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<Channel> getChannelsAtFrequency(long frequency)
{
ArrayList<Channel> configs = new ArrayList<Channel>();
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;
}
}