@Override
  public Component getOptionsPanel() {
    JPanel panel = new JPanel(new GridLayout(0, 1, 4, 4));
    final JCheckBox hideOriginalTableHeader = new JCheckBox("Hide the original table header");
    hideOriginalTableHeader.addItemListener(
        new ItemListener() {
          public void itemStateChanged(ItemEvent e) {
            JTableHeader header = _table.getTableHeader();
            if (header instanceof NestedTableHeader) {
              ((NestedTableHeader) header)
                  .setOriginalTableHeaderVisible(!hideOriginalTableHeader.isSelected());
            }
          }
        });
    panel.add(hideOriginalTableHeader);

    final JCheckBox autoStartCellEditing = new JCheckBox("Auto-start editing when TAB or ENTER");
    autoStartCellEditing.addItemListener(
        new ItemListener() {
          public void itemStateChanged(ItemEvent e) {
            _table.setAutoStartCellEditing(autoStartCellEditing.isSelected());
          }
        });
    autoStartCellEditing.setSelected(_table.isAutoStartCellEditing());
    panel.add(autoStartCellEditing);

    final JCheckBox autoSelectTextWhenStartsEditing =
        new JCheckBox("Auto-select the cell text when editing");
    autoSelectTextWhenStartsEditing.addItemListener(
        new ItemListener() {
          public void itemStateChanged(ItemEvent e) {
            _table.setAutoSelectTextWhenStartsEditing(autoSelectTextWhenStartsEditing.isSelected());
          }
        });
    autoSelectTextWhenStartsEditing.setSelected(_table.isAutoSelectTextWhenStartsEditing());
    panel.add(autoSelectTextWhenStartsEditing);

    final JCheckBox enable = new JCheckBox("Enable Table");
    enable.addItemListener(
        new ItemListener() {
          public void itemStateChanged(ItemEvent e) {
            _table.setEnabled(enable.isSelected());
          }
        });
    enable.setSelected(_table.isEnabled());
    panel.add(enable);

    JCheckBox columnAutoResizable = new JCheckBox("Column Auto Resizable");
    columnAutoResizable.addItemListener(
        new ItemListener() {
          public void itemStateChanged(ItemEvent e) {
            boolean selected = e.getStateChange() == ItemEvent.SELECTED;
            _table.setColumnAutoResizable(selected);
            _table.setAutoResizeMode(
                selected ? JTable.AUTO_RESIZE_OFF : JTable.AUTO_RESIZE_ALL_COLUMNS);
          }
        });
    columnAutoResizable.setSelected(_table.isColumnAutoResizable());
    panel.add(columnAutoResizable);

    JComboBox autoCompletionModeComboBox =
        new JComboBox(
            new Object[] {
              "Disabled", "Cells in the same column", "Cells in the same row", "All cells"
            });
    autoCompletionModeComboBox.setSelectedIndex(_table.getEditorAutoCompletionMode());
    autoCompletionModeComboBox.addItemListener(
        new ItemListener() {
          public void itemStateChanged(ItemEvent e) {
            if (e.getStateChange() == ItemEvent.SELECTED) {
              _table.setEditorAutoCompletionMode(((JComboBox) e.getSource()).getSelectedIndex());
            }
          }
        });
    panel.add(
        JideSwingUtilities.createLabeledComponent(
            new JLabel("AutoCompletion Mode: "),
            autoCompletionModeComboBox,
            BorderLayout.BEFORE_LINE_BEGINS));

    return panel;
  }
  public Component getDemoPanel() {
    JPanel panel = new JPanel(new BorderLayout(6, 6));
    DefaultTableModel model = new CustomizedTableModel(8, 8);
    model.setValueAt("no editing", 2, 2);
    model.setValueAt("no stop", 2, 3);
    model.setValueAt("valid", 2, 4);
    _table = new JideTable(model);
    _table.setNestedTableHeader(true);
    _table.setAlwaysRequestFocusForEditor(true);
    _table.setClickCountToStart(2);
    _table.setEditorAutoCompletionMode(JideTable.EDITOR_AUTO_COMPLETION_MODE_TABLE);

    TableColumnGroup all = new TableColumnGroup("AH");
    TableColumnGroup first = new TableColumnGroup("AB");
    first.add(_table.getColumnModel().getColumn(0));
    first.add(_table.getColumnModel().getColumn(1));
    TableColumnGroup second = new TableColumnGroup("CD");
    second.add(_table.getColumnModel().getColumn(2));
    second.add(_table.getColumnModel().getColumn(3));
    TableColumnGroup third = new TableColumnGroup("EF");
    third.add(_table.getColumnModel().getColumn(4));
    third.add(_table.getColumnModel().getColumn(5));
    TableColumnGroup fourth = new TableColumnGroup("GH");
    fourth.add(_table.getColumnModel().getColumn(6));
    fourth.add(_table.getColumnModel().getColumn(7));
    all.add(first);
    all.add(second);
    all.add(third);
    all.add(fourth);

    if (_table.getTableHeader() instanceof NestedTableHeader) {
      NestedTableHeader header = (NestedTableHeader) _table.getTableHeader();
      header.addColumnGroup(all);
    }

    panel.add(new JScrollPane(_table), BorderLayout.CENTER);
    _message = new JLabel();
    panel.add(_message, BorderLayout.AFTER_LAST_LINE);
    _table.addCellEditorListener(
        new JideCellEditorListener() {
          public boolean editingStarting(ChangeEvent e) {
            int row = ((CellChangeEvent) e).getRow();
            int column = ((CellChangeEvent) e).getColumn();
            if ("no editing".equals(_table.getValueAt(row, column))) {
              _message.setText("Editing is not started because editingStarting() returns false.");
              return false;
            } else {
              return true;
            }
          }

          public void editingStarted(ChangeEvent e) {}

          public boolean editingStopping(ChangeEvent e) {
            if (e.getSource() instanceof CellEditor) {
              if ("no stop".equals(((CellEditor) e.getSource()).getCellEditorValue())) {
                _message.setText("Editing is not stopped because editingStopping() returns false.");
                return false;
              }
            }
            return true;
          }

          public void editingCanceled(ChangeEvent e) {}

          public void editingStopped(ChangeEvent e) {}
        });

    _table.addValidator(
        new Validator() {
          public ValidationResult validating(ValidationObject e) {
            if ("invalid".equals(e.getNewValue())) {
              ValidationResult validationResult =
                  new ValidationResult(0, false, "The value is \"invalid\"");
              _message.setText(validationResult.getMessage());
              return validationResult;
            } else {
              return ValidationResult.OK;
            }
          }
        });
    _message.setForeground(Color.RED);
    _message.setText("");
    return panel;
  }