private JPanel getRow(int gap, Component comp1, Component comp2) {
    JPanel panel = new JPanel(new BorderLayout(gap, 0));
    panel.setOpaque(false);

    panel.add(comp1, BorderLayout.CENTER);
    panel.add(comp2, BorderLayout.EAST);

    return panel;
  }
  private JPanel createForm() {
    JCheckBox enabledCheckBox = new JCheckBox(Finder.getString("vhost.ssl.edit.enable"));

    new CheckBoxPropertySynchronizer(enabledProperty, enabledCheckBox);
    ChangeIndicator enabledChange = new ChangeIndicator();
    enabledProperty.addChangeListener(enabledChange);

    JLabel iPLabel = new JLabel(Finder.getString("vhost.ssl.edit.ip"));
    JTextField iPField = GUIUtil.createTextField();
    new TextComponentPropertySynchronizer<String, JTextComponent>(ipProperty, iPField);
    ChangeIndicator iPChange = new ChangeIndicator();
    ipProperty.addChangeListener(iPChange);

    JLabel portLabel = new JLabel(Finder.getString("vhost.ssl.edit.port"));

    SpinnerNumberModel portModel = new SpinnerNumberModel(0, 0, Short.MAX_VALUE, 1);
    JSpinner portSpinner = new JSpinner(portModel);

    JComponent editor = portSpinner.getEditor();
    if (editor instanceof JSpinner.DefaultEditor) {
      JTextField field = ((JSpinner.DefaultEditor) editor).getTextField();
      field.setColumns(5);
      field.setHorizontalAlignment(JTextField.RIGHT);
    }

    new SpinnerNumberModelPropertySynchronizer(portProperty, portModel, false);
    portProperty.save();

    ChangeIndicator portChange = new ChangeIndicator();
    portProperty.addChangeListener(portChange);

    JLabel certLabel = new JLabel(Finder.getString("vhost.ssl.edit.certificate"));

    BrowsableFilePanel certPanel = new BrowsableFilePanel();
    certPanel.setOpaque(false);
    fileChoosers.add(certPanel.getFileChooser());

    new TextComponentPropertySynchronizer<String, JTextComponent>(
        certProperty, certPanel.getField());
    ChangeIndicator certChange = new ChangeIndicator();
    certProperty.addChangeListener(certChange);

    JLabel keyLabel = new JLabel(Finder.getString("vhost.ssl.edit.key"));

    BrowsableFilePanel keyPanel = new BrowsableFilePanel();
    keyPanel.setOpaque(false);
    fileChoosers.add(keyPanel.getFileChooser());

    new TextComponentPropertySynchronizer<String, JTextComponent>(keyProperty, keyPanel.getField());
    ChangeIndicator keyChange = new ChangeIndicator();
    keyProperty.addChangeListener(keyChange);

    JPanel formPanel = new JPanel();
    formPanel.setOpaque(false);

    Form form = new Form(formPanel, VerticalAnchor.TOP);

    int hGap = GUIUtil.getHalfGap();
    int sGap = 3 * hGap;
    int indent = GUIUtil.getTextXOffset(enabledCheckBox);

    ColumnLayoutConstraint c = new ColumnLayoutConstraint(HorizontalAnchor.FILL, hGap);

    RowLayoutConstraint r = new RowLayoutConstraint(VerticalAnchor.CENTER, hGap);

    HasAnchors a = new SimpleHasAnchors(HorizontalAnchor.LEFT, VerticalAnchor.CENTER);

    form.addRow(HorizontalAnchor.LEFT, c);
    form.add(enabledCheckBox, r);
    form.add(enabledChange, r);

    form.addTable(2, hGap, hGap, HorizontalAnchor.LEFT, c.setGap(sGap));
    form.add(iPLabel, a);
    form.add(getRow(hGap, iPField, iPChange), a);
    form.add(portLabel, a);
    form.add(getRow(hGap, portSpinner, portChange), a);
    form.add(certLabel, a);
    form.add(getRow(hGap, certPanel, certChange), a);
    form.add(keyLabel, a);
    form.add(getRow(hGap, keyPanel, keyChange), a);

    return formPanel;
  }