/* SignalFFTSettingsPanel.java created 2007-12-17
*
*/
package org.signalml.plugin.fftsignaltool.dialogs;
import static org.signalml.plugin.fftsignaltool.FFTSignalTool._;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.InputVerifier;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.apache.log4j.Logger;
import org.jfree.chart.renderer.xy.XYSplineRenderer;
import org.signalml.app.model.components.validation.ValidationErrors;
import org.signalml.math.fft.WindowType;
import org.signalml.plugin.export.i18n.SvarogAccessI18n;
import org.signalml.plugin.fftsignaltool.SignalFFTSettings;
/**
* Panel which allows to select the parameters of the FFT. Contains 6
* sub-panels:
* <ul>
* <li>The panel which allows to select the size of the FFT window (the number
* of samples). The size can be selected from predefined values (powers of 2
* from 64 to 2048) or entered custom.</li>
* <li>The panel which allows to select the parameters of the view such as the
* frequency range and the number of labels on the x axis.</li>
* <li>The panel which allows to select the width of the FFT plot (the number of
* pixels). The size can be selected from predefined values from 300 to 800.</li>
* <li>The panel which allows to select the height of the FFT plot (the number
* of pixels). The size can be selected from predefined values from 200 to 700.</li>
* <li>The {@link FFTWindowTypePanel panel} which allows to select the
* {@link WindowType type} of the FFT window,</li>
* <li>The panel which allows to select other options of the FFT plot:
* <ul>
* <li>if the channel should be switched when the mouse goes up or down,</li>
* <li>if the amplitude should be displayed in the logarithmic scale,</li>
* <li>if the plot should be rendered using {@link XYSplineRenderer splines},</li>
* <li>if the title describing the FFT plot (name of the channel, time interval
* and number of samples) should be visible,</li>
* <li>if the labels for frequencies axis should be visible,</li>
* <li>if the label for power axis should be visible,</li>
* </ul>
* </li>
* </ul>
*
* @author Michal Dobaczewski © 2007-2008 CC Otwarte Systemy Komputerowe
* Sp. z o.o.
*/
public class SignalFFTSettingsPanel extends JPanel {
/**
* the serialization constant
*/
private static final long serialVersionUID = 1L;
/**
* the logger
*/
protected static final Logger logger = Logger
.getLogger(SignalFFTSettingsPanel.class);
/**
* the array with possible sizes of FFT window (number of samples)
*/
private int[] possibleWindowWidths = new int[] { 64, 128, 256, 512, 1024,
2048
};
/**
* the array with possible widths of a FFT plot (pixels)
*/
private int[] possiblePlotWidths = new int[] { 300, 400, 500, 600, 700, 800 };
/**
* the array with possible heights of a FFT plot (pixels)
*/
private int[] possiblePlotHeights = new int[] { 200, 300, 400, 500, 600,
700
};
/**
* the {@link FFTWindowTypePanel panel} which allows to select the
* {@link WindowType type} of the FFT window
*/
private FFTWindowTypePanel fftWindowTypePanel;
/**
* the radio button which allows to select custom (specified in in
* {@link #customWindowWidthTextField}) size of the FFT window (number of
* samples)
*/
private JRadioButton customWindowWidthRadioButton;
/**
* the array with radio buttons for {@link #possibleWindowWidths possible
* sizes} of a FFT window
*/
private JRadioButton[] windowWidthRadioButtons;
/**
* the array with radio buttons for {@link #possiblePlotWidths possible
* widths} of a FFT plot (pixels)
*/
private JRadioButton[] plotWidthRadioButtons;
/**
* the array with buttons for {@link #possiblePlotHeights possible heights}
* of a FFT plot (pixels)
*/
private JRadioButton[] plotHeightRadioButtons;
/**
* the check-box which tells if the channel should be switched (checked)
* when the mouse goes up or down or should remain the same (checked)
*/
private JCheckBox channelSwitchingCheckBox;
/**
* the check-box which tells if the amplitude should be displayed in the
* logarithmic scale (checked)
*/
private JCheckBox logarithmicCheckBox;
/**
* the check-box which tells if the plot should be rendered using
* {@link XYSplineRenderer splines}
*/
private JCheckBox splineCheckBox;
/**
* the check-box which tells if the signal should be antialiased
*/
private JCheckBox antialiasCheckBox;
/**
* the check-box which tells if the title describing the FFT plot (name of
* the channel, time interval and number of samples) should be visible
* (checked)
*/
private JCheckBox titleVisibleCheckBox;
/**
* the check-box which tells if the labels for frequencies axies should be
* visible (checked)
*/
private JCheckBox frequencyAxisLabelsVisibleCheckBox;
/**
* the check-box which tells if the label for power axis should be visible
* (checked)
*/
private JCheckBox powerAxisLabelsVisibleCheckBox;
/**
* the text field which allows to enter the size (number of samples) of the
* FFT window
*/
private JTextField customWindowWidthTextField;
/**
* the text field which allows to enter the beginning of the visible
* frequency range (Hz)
*/
private JTextField visibleRangeStartTextField;
/**
* the text field which allows to enter the end of the visible frequency
* range (Hz)
*/
private JTextField visibleRangeEndTextField;
private JTextField customMinYAxis;
private JTextField customMaxYAxis;
/**
* the text field which allows to enter how many labels should be displayed
* on the X axis
*/
private JTextField xAxisLabelCountTextField;
private JRadioButton autoScaleYAxisRadioButton;
/**
* the group of {@link #windowWidthRadioButtons radio buttons} for the FFT
* window size
*/
private ButtonGroup windowWidthButtonGroup;
private ButtonGroup autoScaleYAxisButtonGroup;
/**
* the group of {@link #plotWidthRadioButtons radio buttons} for the FFT
* plot width (pixels)
*/
private ButtonGroup plotWidthButtonGroup;
/**
* the group of {@link #plotHeightRadioButtons radio buttons} for the FFT
* plot height (pixels)
*/
private ButtonGroup plotHeightButtonGroup;
/**
* the cached {@link #customWindowWidthTextField custom size} of the FFT
* window (number of samples)
*/
private String cachedWindowWidth = null;
/**
* {@code true} if the panel has a cross which closes it, {@code false}
* otherwise
*/
private boolean hasCloseCross;
private JRadioButton fixedYAxisRadioButton;
/**
* Constructor. Sets the {@link SvarogAccessI18n message source} and
* initializes this panel.
*
* @param hasCloseCross
* {@code true} if the panel should has a cross which closes it,
* {@code false} otherwise
*/
public SignalFFTSettingsPanel(
boolean hasCloseCross) {
super();
this.hasCloseCross = hasCloseCross;
initialize();
}
/**
* Initializes this panel with BoxLayout and 6 sub-panels:
* <ul>
* <li>The panel which allows to select the size of the FFT window (the
* number of samples). The size can be selected from predefined values
* (powers of 2 from 64 to 2048) or entered custom.</li>
* <li>The panel which allows to select the parameters of the view such as
* the frequency range and the number of labels on the x axis.</li>
* <li>The panel which allows to select the width of the FFT plot (the
* number of pixels). The size can be selected from predefined values from
* 300 to 800.</li>
* <li>The panel which allows to select the height of the FFT plot (the
* number of pixels). The size can be selected from predefined values from
* 200 to 700.</li>
* <li>The {@link FFTWindowTypePanel panel} which allows to select the
* {@link WindowType type} of the FFT window,</li>
* <li>The panel which allows to select other options of the FFT plot:
* <ul>
* <li>if the channel should be switched when the mouse goes up or down,</li>
* <li>if the amplitude should be displayed in the logarithmic scale,</li>
* <li>if the plot should be rendered using {@link XYSplineRenderer splines}
* ,</li>
* <li>if the title describing the FFT plot (name of the channel, time
* interval and number of samples) should be visible,</li>
* <li>if the labels for frequencies axis should be visible,</li>
* <li>if the label for power axis should be visible,</li>
* </ul>
* </li>
* </ul>
*/
private void initialize() {
windowWidthButtonGroup = new ButtonGroup();
plotWidthButtonGroup = new ButtonGroup();
plotHeightButtonGroup = new ButtonGroup();
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
JPanel windowWidthPanel = new JPanel(new GridLayout(3, 3, 3, 3));
CompoundBorder border = new CompoundBorder(new TitledCrossBorder(
_("FFT window width"),
hasCloseCross), new EmptyBorder(3, 3, 3, 3));
windowWidthPanel.setBorder(border);
ItemListener cachingListener = new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
boolean selected = (e.getStateChange() == ItemEvent.SELECTED);
if (selected) {
cachedWindowWidth = ((JRadioButton) e.getItem()).getText();
}
}
};
windowWidthRadioButtons = new JRadioButton[possibleWindowWidths.length];
int i;
for (i = 0; i < possibleWindowWidths.length; i++) {
windowWidthRadioButtons[i] = new JRadioButton(
Integer.toString(possibleWindowWidths[i]));
windowWidthButtonGroup.add(windowWidthRadioButtons[i]);
windowWidthPanel.add(windowWidthRadioButtons[i]);
windowWidthRadioButtons[i].addItemListener(cachingListener);
}
windowWidthRadioButtons[0].setSelected(true);
customWindowWidthRadioButton = new JRadioButton(
_("Custom"));
windowWidthButtonGroup.add(customWindowWidthRadioButton);
windowWidthPanel.add(customWindowWidthRadioButton);
customWindowWidthTextField = new JTextField("");
customWindowWidthTextField.setPreferredSize(new Dimension(80, 25));
customWindowWidthTextField.setEnabled(false);
windowWidthPanel.add(customWindowWidthTextField);
customWindowWidthRadioButton.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
boolean selected = (e.getStateChange() == ItemEvent.SELECTED);
if (selected) {
if (customWindowWidthTextField.getText().isEmpty()) {
if (cachedWindowWidth == null) {
customWindowWidthTextField
.setText(windowWidthRadioButtons[0]
.getText());
} else {
customWindowWidthTextField
.setText(cachedWindowWidth);
}
}
}
customWindowWidthTextField.setEnabled(selected);
}
});
JPanel fftViewPanel = new JPanel(new GridLayout(3, 2, 3, 3));
{
border = new CompoundBorder(
new TitledBorder(_("FFT view")),
new EmptyBorder(3, 3, 3, 3));
fftViewPanel.setBorder(border);
JLabel label = new JLabel(
_("Show fq range [Hz]"));
InputVerifier intInputVerifier = new InputVerifier() {
@Override
public boolean verify(JComponent input) {
try {
String text = ((JTextField) input).getText().trim();
if (text.length() == 0 || Integer.parseInt(text) >= 0)
return true;
else {
JOptionPane
.showMessageDialog(
input.getParent(),
_("Positive integer required"));
return false;
}
} catch (NumberFormatException nfe) {
JOptionPane
.showMessageDialog(
input.getParent(),
_("Positive integer required"));
return false;
}
}
};
JPanel rangePanel = new JPanel();
visibleRangeStartTextField = new JTextField();
visibleRangeStartTextField.setColumns(5);
visibleRangeStartTextField.setInputVerifier(intInputVerifier);
visibleRangeEndTextField = new JTextField();
visibleRangeEndTextField.setColumns(5);
visibleRangeEndTextField.setInputVerifier(intInputVerifier);
rangePanel.add(label);
rangePanel.add(visibleRangeStartTextField);
rangePanel.add(new JLabel("-"));
rangePanel.add(visibleRangeEndTextField);
JPanel countPanel = new JPanel();
label = new JLabel(
_("X-axis label count"));
countPanel.add(label);
xAxisLabelCountTextField = new JTextField();
xAxisLabelCountTextField.setColumns(5);
xAxisLabelCountTextField.setInputVerifier(intInputVerifier);
countPanel.add(xAxisLabelCountTextField);
fftViewPanel.add(countPanel);
fftViewPanel.add(rangePanel);
autoScaleYAxisButtonGroup = new ButtonGroup();
autoScaleYAxisRadioButton = new JRadioButton(
_("Fit Y-axis to data"));
fixedYAxisRadioButton = new JRadioButton(
_("Keep Y-axis fixed"));
autoScaleYAxisButtonGroup.add(autoScaleYAxisRadioButton);
autoScaleYAxisButtonGroup.add(fixedYAxisRadioButton);
fixedYAxisRadioButton.setSelected(true);
fftViewPanel.add(autoScaleYAxisRadioButton);
InputVerifier doubleInputVerifier = new InputVerifier() {
@Override
public boolean verify(JComponent input) {
try {
String text = ((JTextField) input).getText().trim();
if (text.length() == 0 || Double.parseDouble(text) >= 0)
return true;
else {
JOptionPane
.showMessageDialog(
input.getParent(),
_("Positive double required"));
return false;
}
} catch (NumberFormatException nfe) {
JOptionPane
.showMessageDialog(
input.getParent(),
_("Positive double required"));
return false;
}
}
};
JPanel yAxisRangePanel = new JPanel();
yAxisRangePanel.add(fixedYAxisRadioButton);
customMinYAxis = new JTextField();
customMinYAxis.setColumns(5);
customMinYAxis.setInputVerifier(doubleInputVerifier);
customMaxYAxis = new JTextField();
customMaxYAxis.setColumns(5);
customMaxYAxis.setInputVerifier(doubleInputVerifier);
yAxisRangePanel.add(customMinYAxis);
yAxisRangePanel.add(new JLabel("-"));
yAxisRangePanel.add(customMaxYAxis);
fftViewPanel.add(yAxisRangePanel);
fixedYAxisRadioButton.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
customMinYAxis.setEnabled(((JRadioButton)e.getSource()).isSelected());
customMaxYAxis.setEnabled(((JRadioButton)e.getSource()).isSelected());
}
});
}
JPanel plotWidthPanel = new JPanel(new GridLayout(1, 4, 3, 3));
border = new CompoundBorder(new TitledBorder(
_("Plot window width")),
new EmptyBorder(3, 3, 3, 3));
plotWidthPanel.setBorder(border);
Dimension radioSize = new Dimension(50, 20);
plotWidthRadioButtons = new JRadioButton[possiblePlotWidths.length];
for (i = 0; i < possiblePlotWidths.length; i++) {
plotWidthRadioButtons[i] = new JRadioButton(
Integer.toString(possiblePlotWidths[i]));
plotWidthRadioButtons[i].setPreferredSize(radioSize);
plotWidthButtonGroup.add(plotWidthRadioButtons[i]);
plotWidthPanel.add(plotWidthRadioButtons[i]);
}
plotWidthRadioButtons[0].setSelected(true);
JPanel plotHeightPanel = new JPanel(new GridLayout(1, 4, 3, 3));
border = new CompoundBorder(new TitledBorder(
_("Plot window height")),
new EmptyBorder(3, 3, 3, 3));
plotHeightPanel.setBorder(border);
plotHeightRadioButtons = new JRadioButton[possiblePlotHeights.length];
for (i = 0; i < possiblePlotHeights.length; i++) {
plotHeightRadioButtons[i] = new JRadioButton(
Integer.toString(possiblePlotHeights[i]));
plotHeightRadioButtons[i].setPreferredSize(radioSize);
plotHeightButtonGroup.add(plotHeightRadioButtons[i]);
plotHeightPanel.add(plotHeightRadioButtons[i]);
}
plotHeightRadioButtons[0].setSelected(true);
fftWindowTypePanel = new FFTWindowTypePanel(false);
JPanel optionsPanel = new JPanel(new GridLayout(4, 2, 3, 3));
border = new CompoundBorder(new TitledBorder(
_("Options")),
new EmptyBorder(3, 3, 3, 3));
optionsPanel.setBorder(border);
channelSwitchingCheckBox = new JCheckBox(
_("Sticky channel"));
logarithmicCheckBox = new JCheckBox(
_("Logarithmic"));
antialiasCheckBox = new JCheckBox(
_("Antialias"));
splineCheckBox = new JCheckBox(
_("Use splines (experimental)"));
titleVisibleCheckBox = new JCheckBox(
_("Title"));
frequencyAxisLabelsVisibleCheckBox = new JCheckBox(
_("Freq. lables"));
powerAxisLabelsVisibleCheckBox = new JCheckBox(
_("Power labels"));
optionsPanel.add(channelSwitchingCheckBox);
optionsPanel.add(logarithmicCheckBox);
optionsPanel.add(antialiasCheckBox);
optionsPanel.add(splineCheckBox);
optionsPanel.add(frequencyAxisLabelsVisibleCheckBox);
optionsPanel.add(powerAxisLabelsVisibleCheckBox);
optionsPanel.add(titleVisibleCheckBox);
add(windowWidthPanel);
add(fftViewPanel);
add(plotWidthPanel);
add(plotHeightPanel);
add(fftWindowTypePanel);
add(optionsPanel);
Dimension size = getPreferredSize();
if (size.width < 150) {
size.width = 150;
}
setPreferredSize(size);
}
/**
* Fills the fields of this panel from the given {@link SignalFFTSettings
* model}:
* <ul>
* <li>the width and height of the plot,
* <li>
* <li>the size of the FFT window (number of samples),</li>
* <li>the {@link WindowType type} of the FFT window,</li>
* <li>the additional options such as if the title and labels should be
* visible or the signal should be antialiased.</li>
* </ul>
*
* @param settings
* the model
*/
public void fillPanelFromModel(SignalFFTSettings settings) {
int windowWidth = settings.getWindowWidth();
int i;
boolean found = false;
for (i = 0; i < possibleWindowWidths.length; i++) {
if (windowWidth == possibleWindowWidths[i]) {
windowWidthRadioButtons[i].setSelected(true);
found = true;
break;
}
}
if (!found) {
customWindowWidthRadioButton.setSelected(true);
customWindowWidthTextField.setText(Integer.toString(windowWidth));
}
if (settings.getVisibleRangeStart() > Integer.MIN_VALUE) {
visibleRangeStartTextField.setText(""
+ settings.getVisibleRangeStart());
} else {
visibleRangeStartTextField.setText("");
}
if (settings.getVisibleRangeEnd() < Integer.MAX_VALUE) {
visibleRangeEndTextField
.setText("" + settings.getVisibleRangeEnd());
} else {
visibleRangeEndTextField.setText("");
}
if (settings.getXAxisLabelCount() < Integer.MAX_VALUE) {
xAxisLabelCountTextField.setText("" + settings.getXAxisLabelCount());
} else {
xAxisLabelCountTextField.setText("");
}
autoScaleYAxisRadioButton.setSelected(settings.isAutoScaleYAxis());
customMaxYAxis.setText(""+settings.getMaxPowerAxis());
customMinYAxis.setText(""+settings.getMinPowerAxis());
Dimension plotSize = settings.getPlotSize();
for (i = 0; i < possiblePlotWidths.length; i++) {
if (plotSize.width == possiblePlotWidths[i]) {
plotWidthRadioButtons[i].setSelected(true);
break;
}
}
for (i = 0; i < possiblePlotHeights.length; i++) {
if (plotSize.height == possiblePlotHeights[i]) {
plotHeightRadioButtons[i].setSelected(true);
break;
}
}
fftWindowTypePanel.fillPanelFromModel(settings);
channelSwitchingCheckBox.setSelected(!settings.isChannelSwitching()); // note
// the
// description
// of
// this
// field
// causes
// a
// yes/no
// meaning
// inversion
logarithmicCheckBox.setSelected(settings.isLogarithmic());
antialiasCheckBox.setSelected(settings.isAntialias());
splineCheckBox.setSelected(settings.isSpline());
titleVisibleCheckBox.setSelected(settings.isTitleVisible());
frequencyAxisLabelsVisibleCheckBox.setSelected(settings
.isFrequencyAxisLabelsVisible());
powerAxisLabelsVisibleCheckBox.setSelected(settings
.isPowerAxisLabelsVisible());
}
/**
* Stores the user input in the given {@link SignalFFTSettings model}:
* <ul>
* <li>the width and height of the plot,
* <li>
* <li>the size of the FFT window (number of samples),</li>
* <li>the {@link WindowType type} of the FFT window,</li>
* <li>the additional options such as if the title and labels should be
* visible or the signal should be antialiased.</li>
* </ul>
*
* @param settings
* the model
*/
public void fillModelFromPanel(SignalFFTSettings settings) {
int i;
boolean found = false;
for (i = 0; i < possibleWindowWidths.length; i++) {
if (windowWidthRadioButtons[i].isSelected()) {
settings.setWindowWidth(possibleWindowWidths[i]);
found = true;
break;
}
}
if (!found) {
if (customWindowWidthRadioButton.isSelected()) {
settings.setWindowWidth(Integer
.parseInt(customWindowWidthTextField.getText()));
} else {
throw new RuntimeException("Nothing selected");
}
}
String val = visibleRangeStartTextField.getText().trim();
if (val.length() > 0) {
try {
settings.setVisibleRangeStart(Integer.parseInt(val));
} catch (NumberFormatException e) {
logger.error("", e);
settings.setVisibleRangeStart(Integer.MIN_VALUE);
}
} else {
settings.setVisibleRangeStart(Integer.MIN_VALUE);
}
val = visibleRangeEndTextField.getText().trim();
if (val.length() > 0) {
try {
settings.setVisibleRangeEnd(Integer.parseInt(val));
} catch (NumberFormatException e) {
logger.error("", e);
settings.setVisibleRangeEnd(Integer.MAX_VALUE);
}
} else {
settings.setVisibleRangeEnd(Integer.MAX_VALUE);
}
val = xAxisLabelCountTextField.getText().trim();
if (val.length() > 0) {
try {
settings.setXAxisLabelCount(Integer.parseInt(val));
} catch (NumberFormatException e) {
logger.error("", e);
settings.setXAxisLabelCount(Integer.MAX_VALUE);
}
} else {
settings.setXAxisLabelCount(Integer.MAX_VALUE);
}
settings.setAutoScaleYAxis(autoScaleYAxisRadioButton.isSelected());
settings.setMaxPowerAxis(Double.parseDouble(customMaxYAxis.getText()));
settings.setMinPowerAxis(Double.parseDouble(customMinYAxis.getText()));
Dimension plotSize = new Dimension(600, 200);
for (i = 0; i < possiblePlotWidths.length; i++) {
if (plotWidthRadioButtons[i].isSelected()) {
plotSize.width = possiblePlotWidths[i];
break;
}
}
for (i = 0; i < possiblePlotHeights.length; i++) {
if (plotHeightRadioButtons[i].isSelected()) {
plotSize.height = possiblePlotHeights[i];
break;
}
}
settings.setPlotSize(plotSize);
fftWindowTypePanel.fillModelFromPanel(settings);
settings.setChannelSwitching(!channelSwitchingCheckBox.isSelected()); // note
// the
// description
// of
// this
// field
// causes
// a
// yes/no
// meaning
// inversion
settings.setLogarithmic(logarithmicCheckBox.isSelected());
settings.setAntialias(antialiasCheckBox.isSelected());
settings.setSpline(splineCheckBox.isSelected());
settings.setTitleVisible(titleVisibleCheckBox.isSelected());
settings.setFrequencyAxisLabelsVisible(frequencyAxisLabelsVisibleCheckBox
.isSelected());
settings.setPowerAxisLabelsVisible(powerAxisLabelsVisibleCheckBox
.isSelected());
}
/**
* Validates this panel. This panel can be invalid only in the custom window
* size is selected and the entered value is in bad format or to small (
* {@code < 8}).
*
* @param errors
* the object in which the errors are stored
*/
public void validatePanel(ValidationErrors errors) {
if (customWindowWidthRadioButton.isSelected()) {
try {
int windowWidth = Integer.parseInt(customWindowWidthTextField
.getText());
if (windowWidth < 8) {
errors.addError(_("Bad window width. Must be an integer greater than 7"));
}
} catch (NumberFormatException ex) {
errors.addError(_("Bad window width. Must be an integer greater than 7"));
}
}
try {
int xAxisLabelCount = Integer.parseInt(xAxisLabelCountTextField.getText());
if (xAxisLabelCount <= 0) {
errors.addError(_("X-Axis label count should be greater than 0!"));
}
} catch(NumberFormatException ex) {
errors.addError(_("Bad X-Axis label count!"));
}
fftWindowTypePanel.validatePanel(errors);
double maxY = Double.parseDouble(customMaxYAxis.getText());
double minY = Double.parseDouble(customMinYAxis.getText());
if (maxY <= minY)
errors.addError(_("Bad power axis range - min must be lower than max"));
if (fixedYAxisRadioButton.isSelected() &&
logarithmicCheckBox.isSelected() && minY == 0)
errors.addError(_("For logarithmic scale for Y axis min cannot be equal to 0."));
}
}