protected void init() {
    setTitle(Messages.getInstance().getString("ChartEditorTitle"));

    editModel = new LegacyChartEditModel();
    editModel.addPropertyChangeListener(
        LegacyChartEditModel.CHART_EXPRESSION_PROPERTY, new ChartExpressionChangeHandler());
    editModel.addPropertyChangeListener(
        LegacyChartEditModel.PRIMARY_DATA_SOURCE_PROPERTY, new PrimaryDataSourceChangeHandler());
    editModel.addPropertyChangeListener(
        LegacyChartEditModel.SECONDARY_DATA_SOURCE_PROPERTY,
        new SecondaryDataSourceChangeHandler());

    chartTable = new ElementMetaDataTable();
    chartPropertiesTableModel = new ChartExpressionPropertiesTableModel();

    primaryDataSourceTable = new ElementMetaDataTable();
    primaryDataSourcePropertiesTableModel = new ExpressionPropertiesTableModel();
    primaryDataSourcePropertiesTableModel.setFilterInlineExpressionProperty(true);

    secondaryDataSourceTable = new ElementMetaDataTable();
    secondaryDataSourcePropertiesTableModel = new ExpressionPropertiesTableModel();
    secondaryDataSourcePropertiesTableModel.setFilterInlineExpressionProperty(true);

    dataSourceTabbedPane = new JTabbedPane();
    dataSourceTabbedPane.add(
        Messages.getInstance().getString("PrimaryDataSource"), createPrimaryDataSourcePanel());
    dataSourceTabbedPane.add(
        Messages.getInstance().getString("SecondaryDataSource"), createSecondaryDataSourcePanel());

    super.init();
  }
  private Component createChartSelectorButtonPane() {
    final ChartType[] types = ChartType.values();
    final ButtonGroup buttonGroup = new ButtonGroup();
    final JPanel buttonCarrier = new JPanel();
    buttonCarrier.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5));

    for (int i = 0; i < types.length; i++) {
      final ChartType type = types[i];

      final SelectChartExpressionAction action =
          new SelectChartExpressionAction(type.getExpressionType());
      editModel.getChartExpressionsModel().addListDataListener(action);

      final ActionToggleButton button = new ActionToggleButton();
      button.putClientProperty("hideActionText", Boolean.TRUE); // NON-NLS
      button.setAction(action);
      button.setBorder(new EmptyBorder(0, 0, 0, 0));
      buttonGroup.add(button);
      buttonCarrier.add(button);
    }

    final JPanel panel = new JPanel();
    panel.setLayout(new BorderLayout());
    panel.add(buttonCarrier, BorderLayout.NORTH);
    return panel;
  }
  private JPanel createChartPanel() {
    final JPanel innerChartExpressionPanel = new JPanel(new BorderLayout());
    innerChartExpressionPanel.add(
        new SortHeaderPanel(chartPropertiesTableModel), BorderLayout.NORTH);
    final JComboBox comboBox = new SmartComboBox(editModel.getChartExpressionsModel());
    comboBox.setRenderer(new ExpressionListCellRenderer());
    innerChartExpressionPanel.add(comboBox, BorderLayout.CENTER);

    final JPanel chartExpressionPanel = new JPanel(new BorderLayout());
    chartExpressionPanel.add(innerChartExpressionPanel, BorderLayout.NORTH);
    chartExpressionPanel.add(
        configureExpressionTable(chartTable, chartPropertiesTableModel), BorderLayout.CENTER);
    return chartExpressionPanel;
  }
  private JPanel createPrimaryDataSourcePanel() {
    final JPanel innerPrimaryDataSourcePanel = new JPanel(new BorderLayout());
    innerPrimaryDataSourcePanel.add(
        new SortHeaderPanel(primaryDataSourcePropertiesTableModel), BorderLayout.NORTH);
    final JComboBox comboBox = new SmartComboBox(editModel.getPrimaryDataSourcesModel());
    comboBox.setRenderer(new ExpressionListCellRenderer());
    innerPrimaryDataSourcePanel.add(comboBox, BorderLayout.CENTER);

    final JPanel primaryDataSourcePanel = new JPanel(new BorderLayout());
    primaryDataSourcePanel.add(innerPrimaryDataSourcePanel, BorderLayout.NORTH);
    primaryDataSourcePanel.add(
        configureExpressionTable(primaryDataSourceTable, primaryDataSourcePropertiesTableModel),
        BorderLayout.CENTER);
    return primaryDataSourcePanel;
  }
  public ChartEditingResult performEdit(
      final Element element, final ReportDesignerContext reportDesignerContext)
      throws CloneNotSupportedException {
    if (element == null) {
      throw new NullPointerException();
    }
    if (reportDesignerContext == null) {
      throw new NullPointerException();
    }
    if (LegacyChartsUtil.isLegacyChartElement(element) == false) {
      return null;
    }
    try {
      chartTable.setReportDesignerContext(reportDesignerContext);
      primaryDataSourceTable.setReportDesignerContext(reportDesignerContext);
      secondaryDataSourceTable.setReportDesignerContext(reportDesignerContext);

      chartPropertiesTableModel.setActiveContext(reportDesignerContext.getActiveContext());
      primaryDataSourcePropertiesTableModel.setActiveContext(
          reportDesignerContext.getActiveContext());
      secondaryDataSourcePropertiesTableModel.setActiveContext(
          reportDesignerContext.getActiveContext());

      final Element editableElement = element.derive();
      final Expression chartExpression =
          editableElement.getAttributeExpression(
              AttributeNames.Core.NAMESPACE, AttributeNames.Core.VALUE);

      final Expression originalPrimaryDataSourceExpression;
      final Expression originalSecondaryDataSourceExpression;
      if (chartExpression != null) {
        originalPrimaryDataSourceExpression = extractPrimaryDatasource(element);
        originalSecondaryDataSourceExpression = extractSecondaryDatasource(element);

        editModel.setChartExpression(chartExpression.getInstance());
        if (originalPrimaryDataSourceExpression != null) {
          editModel.setPrimaryDataSource(originalPrimaryDataSourceExpression.getInstance());
        } else {
          editModel.setPrimaryDataSource(null);
        }

        if (originalSecondaryDataSourceExpression != null) {
          editModel.setSecondaryDataSource(originalSecondaryDataSourceExpression.getInstance());
        } else {
          editModel.setSecondaryDataSource(null);
        }

      } else {
        editModel.setChartExpression(null);
        editModel.setPrimaryDataSource(null);
        editModel.setSecondaryDataSource(null);
        originalPrimaryDataSourceExpression = null;
        originalSecondaryDataSourceExpression = null;
      }

      if (editModel.getCurrentChartType() != null) {
        final ChartType chartType = editModel.getCurrentChartType();
        if (editModel.getPrimaryDataSource() == null) {
          final Class dataSourceImplementation =
              chartType.getPreferredPrimaryDataSourceImplementation();
          final ExpressionMetaData data =
              ExpressionRegistry.getInstance()
                  .getExpressionMetaData(dataSourceImplementation.getName());
          editModel.getPrimaryDataSourcesModel().setSelectedItem(data);
        }
        if (editModel.getSecondaryDataSource() == null) {
          final Class dataSourceImplementation =
              chartType.getPreferredSecondaryDataSourceImplementation();
          if (dataSourceImplementation != null) {
            final ExpressionMetaData data =
                ExpressionRegistry.getInstance()
                    .getExpressionMetaData(dataSourceImplementation.getName());
            editModel.getSecondaryDataSourcesModel().setSelectedItem(data);
          }
        }
      }

      if (performEdit() == false) {
        return null;
      }

      secondaryDataSourceTable.stopEditing();
      primaryDataSourceTable.stopEditing();
      chartTable.stopEditing();

      return new ChartEditingResult(
          chartExpression,
          originalPrimaryDataSourceExpression,
          originalSecondaryDataSourceExpression,
          editModel.getChartExpression(),
          editModel.getPrimaryDataSource(),
          editModel.getSecondaryDataSource());
    } finally {
      chartTable.setReportDesignerContext(null);
      primaryDataSourceTable.setReportDesignerContext(null);
      secondaryDataSourceTable.setReportDesignerContext(null);

      chartPropertiesTableModel.setActiveContext(null);
      primaryDataSourcePropertiesTableModel.setActiveContext(null);
      secondaryDataSourcePropertiesTableModel.setActiveContext(null);
    }
  }