private JPanel createOptionsPanel() {
    final JLabel numBinsLabel = new JLabel("#Bins:");
    JTextField numBinsField = new JTextField(Integer.toString(NUM_BINS_DEFAULT));
    numBinsField.setPreferredSize(new Dimension(50, numBinsField.getPreferredSize().height));
    final JCheckBox histoLogCheck = new JCheckBox("Log10 scaled bins");

    histoLogCheck.addActionListener(configChangeListener);

    bindingContext
        .getPropertySet()
        .getDescriptor(PROPERTY_NAME_NUM_BINS)
        .setDescription("Set the number of bins in the histogram");
    bindingContext
        .getPropertySet()
        .getDescriptor(PROPERTY_NAME_NUM_BINS)
        .setValueRange(new ValueRange(2.0, 2048.0));
    bindingContext
        .getPropertySet()
        .getDescriptor(PROPERTY_NAME_NUM_BINS)
        .setDefaultValue(NUM_BINS_DEFAULT);
    bindingContext.bind(PROPERTY_NAME_NUM_BINS, numBinsField);

    bindingContext
        .getPropertySet()
        .getDescriptor(PROPERTY_NAME_LOGARITHMIC_HISTOGRAM)
        .setDescription("Use log-10 scaled values for computation of histogram");
    bindingContext
        .getPropertySet()
        .getDescriptor(PROPERTY_NAME_LOGARITHMIC_HISTOGRAM)
        .setDefaultValue(false);
    bindingContext.bind(PROPERTY_NAME_LOGARITHMIC_HISTOGRAM, histoLogCheck);
    log10HistEnablement =
        bindingContext.bindEnabledState(
            PROPERTY_NAME_LOGARITHMIC_HISTOGRAM,
            true,
            new Enablement.Condition() {
              @Override
              public boolean evaluate(BindingContext bindingContext) {
                return getRaster() != null && getRaster().getStx().getMaximum() > 0;
              }
            });

    PropertyChangeListener logChangeListener = new AxisControlChangeListener();

    xAxisRangeControl.getBindingContext().addPropertyChangeListener(logChangeListener);
    xAxisRangeControl
        .getBindingContext()
        .getPropertySet()
        .addProperty(
            bindingContext.getPropertySet().getProperty(PROPERTY_NAME_LOGARITHMIC_HISTOGRAM));
    xAxisRangeControl
        .getBindingContext()
        .getPropertySet()
        .addProperty(bindingContext.getPropertySet().getProperty(PROPERTY_NAME_LOG_SCALED));
    xAxisRangeControl
        .getBindingContext()
        .getPropertySet()
        .getDescriptor(PROPERTY_NAME_LOG_SCALED)
        .setDescription("Toggle whether to use a logarithmic x-axis");
    log10AxisEnablement =
        xAxisRangeControl
            .getBindingContext()
            .bindEnabledState(
                PROPERTY_NAME_LOG_SCALED,
                true,
                new Enablement.Condition() {
                  @Override
                  public boolean evaluate(BindingContext bindingContext) {
                    HistogramPanelModel.HistogramConfig currentConfig = createHistogramConfig();
                    boolean hasStx = model.hasStx(currentConfig);
                    // log10 xAxis is enabled when current histogram exists and is NOT log10 scaled
                    return dataset != null
                        && hasStx
                        && !model.getStx(currentConfig).isLogHistogram();
                  }
                });

    JPanel dataSourceOptionsPanel = GridBagUtils.createPanel();
    GridBagConstraints dataSourceOptionsConstraints =
        GridBagUtils.createConstraints("anchor=NORTHWEST,fill=HORIZONTAL,insets.top=2");
    GridBagUtils.addToPanel(
        dataSourceOptionsPanel,
        new JLabel(" "),
        dataSourceOptionsConstraints,
        "gridwidth=2,gridy=0,gridx=0,weightx=0");
    GridBagUtils.addToPanel(
        dataSourceOptionsPanel,
        numBinsLabel,
        dataSourceOptionsConstraints,
        "insets.top=2,insets.left=4,gridwidth=1,gridy=1,gridx=0,weightx=1");
    GridBagUtils.addToPanel(
        dataSourceOptionsPanel,
        numBinsField,
        dataSourceOptionsConstraints,
        "insets.top=0,insets.left=0,insets.right=2,gridwidth=1,gridy=1,gridx=1");
    GridBagUtils.addToPanel(
        dataSourceOptionsPanel,
        histoLogCheck,
        dataSourceOptionsConstraints,
        "insets.right=0,gridwidth=2,gridy=2,gridx=0");

    xAxisRangeControl
        .getBindingContext()
        .bind(PROPERTY_NAME_LOG_SCALED, new JCheckBox("Log10 scaled"));
    xAxisRangeControl
        .getBindingContext()
        .addPropertyChangeListener(
            PROPERTY_NAME_LOG_SCALED,
            new PropertyChangeListener() {
              @Override
              public void propertyChange(PropertyChangeEvent evt) {
                ValueAxis oldAxis = chart.getXYPlot().getDomainAxis();
                ValueAxis newAxis =
                    StatisticChartStyling.updateScalingOfAxis(
                        (Boolean) evt.getNewValue(), oldAxis, true);
                chart.getXYPlot().setDomainAxis(newAxis);
              }
            });

    JPanel displayOptionsPanel = GridBagUtils.createPanel();
    GridBagConstraints displayOptionsConstraints =
        GridBagUtils.createConstraints("anchor=SOUTH,fill=HORIZONTAL,weightx=1");
    GridBagUtils.addToPanel(
        displayOptionsPanel, xAxisRangeControl.getPanel(), displayOptionsConstraints, "gridy=2");

    JPanel optionsPanel = GridBagUtils.createPanel();
    GridBagConstraints gbc =
        GridBagUtils.createConstraints("anchor=NORTHWEST,fill=HORIZONTAL,insets.top=2,weightx=1");
    GridBagUtils.addToPanel(optionsPanel, dataSourceOptionsPanel, gbc, "gridy=0");
    GridBagUtils.addToPanel(optionsPanel, new JPanel(), gbc, "gridy=1,fill=VERTICAL,weighty=1");
    GridBagUtils.addToPanel(
        optionsPanel, displayOptionsPanel, gbc, "gridy=2,fill=HORIZONTAL,weighty=0");
    GridBagUtils.addToPanel(optionsPanel, new JPanel(), gbc, "gridy=3,fill=VERTICAL,weighty=1");
    GridBagUtils.addToPanel(
        optionsPanel,
        xAxisRangeControl
            .getBindingContext()
            .getBinding(PROPERTY_NAME_LOG_SCALED)
            .getComponents()[0],
        gbc,
        "gridy=4");
    return optionsPanel;
  }
  private JPanel createInputParameterPanel() {
    final PropertyDescriptor boxSizeDescriptor =
        bindingContext.getPropertySet().getDescriptor(PROPERTY_NAME_BOX_SIZE);
    boxSizeDescriptor.setValueRange(new ValueRange(1, 101));
    boxSizeDescriptor.setAttribute("stepSize", 2);
    boxSizeDescriptor.setValidator(
        (property, value) -> {
          if (((Number) value).intValue() % 2 == 0) {
            throw new ValidationException("Only odd values allowed as box size.");
          }
        });
    final JSpinner boxSizeSpinner = new JSpinner();
    bindingContext.bind(PROPERTY_NAME_BOX_SIZE, boxSizeSpinner);

    final JPanel boxSizePanel = new JPanel(new BorderLayout(5, 3));
    boxSizePanel.add(new JLabel("Box size:"), BorderLayout.WEST);
    boxSizePanel.add(boxSizeSpinner);

    correlativeFieldSelector = new CorrelativeFieldSelector(bindingContext);

    final JPanel pointDataSourcePanel = new JPanel(new BorderLayout(5, 3));
    pointDataSourcePanel.add(correlativeFieldSelector.pointDataSourceLabel, BorderLayout.NORTH);
    pointDataSourcePanel.add(correlativeFieldSelector.pointDataSourceList);

    final JPanel pointDataFieldPanel = new JPanel(new BorderLayout(5, 3));
    pointDataFieldPanel.add(correlativeFieldSelector.dataFieldLabel, BorderLayout.NORTH);
    pointDataFieldPanel.add(correlativeFieldSelector.dataFieldList);

    final JCheckBox xLogCheck = new JCheckBox("Log10 scaled");
    bindingContext.bind(PROPERTY_NAME_X_AXIS_LOG_SCALED, xLogCheck);
    final JPanel xAxisOptionPanel = new JPanel(new BorderLayout());
    xAxisOptionPanel.add(xAxisRangeControl.getPanel());
    xAxisOptionPanel.add(xLogCheck, BorderLayout.SOUTH);

    final JCheckBox yLogCheck = new JCheckBox("Log10 scaled");
    bindingContext.bind(PROPERTY_NAME_Y_AXIS_LOG_SCALED, yLogCheck);
    final JPanel yAxisOptionPanel = new JPanel(new BorderLayout());
    yAxisOptionPanel.add(yAxisRangeControl.getPanel());
    yAxisOptionPanel.add(yLogCheck, BorderLayout.SOUTH);

    final JCheckBox acceptableCheck = new JCheckBox("Show tolerance range");
    JLabel fieldPrefix = new JLabel("+/-");
    final JTextField acceptableField = new JTextField();
    acceptableField.setPreferredSize(new Dimension(40, acceptableField.getPreferredSize().height));
    acceptableField.setHorizontalAlignment(JTextField.RIGHT);
    final JLabel percentLabel = new JLabel(" %");
    bindingContext.bind(PROPERTY_NAME_SHOW_ACCEPTABLE_DEVIATION, acceptableCheck);
    bindingContext.bind(PROPERTY_NAME_ACCEPTABLE_DEVIATION, acceptableField);
    bindingContext.getBinding(PROPERTY_NAME_ACCEPTABLE_DEVIATION).addComponent(percentLabel);
    bindingContext.getBinding(PROPERTY_NAME_ACCEPTABLE_DEVIATION).addComponent(fieldPrefix);
    bindingContext.bindEnabledState(
        PROPERTY_NAME_ACCEPTABLE_DEVIATION, true,
        PROPERTY_NAME_SHOW_ACCEPTABLE_DEVIATION, true);

    final JPanel confidencePanel = GridBagUtils.createPanel();
    GridBagConstraints confidencePanelConstraints =
        GridBagUtils.createConstraints(
            "anchor=NORTHWEST,fill=HORIZONTAL,insets.top=5,weighty=0,weightx=1");
    GridBagUtils.addToPanel(
        confidencePanel, acceptableCheck, confidencePanelConstraints, "gridy=0,gridwidth=3");
    GridBagUtils.addToPanel(
        confidencePanel,
        fieldPrefix,
        confidencePanelConstraints,
        "weightx=0,insets.left=22,gridy=1,gridx=0,insets.top=4,gridwidth=1");
    GridBagUtils.addToPanel(
        confidencePanel,
        acceptableField,
        confidencePanelConstraints,
        "weightx=1,gridx=1,insets.left=2,insets.top=2");
    GridBagUtils.addToPanel(
        confidencePanel,
        percentLabel,
        confidencePanelConstraints,
        "weightx=0,gridx=2,insets.left=0,insets.top=4");

    final JCheckBox regressionCheck = new JCheckBox("Show regression line");
    bindingContext.bind(PROPERTY_NAME_SHOW_REGRESSION_LINE, regressionCheck);

    // UI arrangement

    JPanel middlePanel = GridBagUtils.createPanel();
    GridBagConstraints middlePanelConstraints =
        GridBagUtils.createConstraints(
            "anchor=NORTHWEST,fill=HORIZONTAL,insets.top=6,weighty=0,weightx=1");
    GridBagUtils.addToPanel(
        middlePanel, boxSizePanel, middlePanelConstraints, "gridy=0,insets.left=6");
    GridBagUtils.addToPanel(middlePanel, pointDataSourcePanel, middlePanelConstraints, "gridy=1");
    GridBagUtils.addToPanel(middlePanel, pointDataFieldPanel, middlePanelConstraints, "gridy=2");
    GridBagUtils.addToPanel(
        middlePanel, xAxisOptionPanel, middlePanelConstraints, "gridy=3,insets.left=0");
    GridBagUtils.addToPanel(middlePanel, yAxisOptionPanel, middlePanelConstraints, "gridy=4");
    GridBagUtils.addToPanel(
        middlePanel, new JSeparator(), middlePanelConstraints, "gridy=5,insets.left=4");
    GridBagUtils.addToPanel(
        middlePanel,
        confidencePanel,
        middlePanelConstraints,
        "gridy=6,fill=HORIZONTAL,insets.left=-4");
    GridBagUtils.addToPanel(
        middlePanel,
        regressionCheck,
        middlePanelConstraints,
        "gridy=7,insets.left=-4,insets.top=8");

    return middlePanel;
  }