mercredi 20 janvier 2016

Rendering a check box with a cellFactory in TableView doesn't work as it should

I want to create the following functionality for the serieses of a line chart when the user clicks on a checkbox on a table view. The table view for items has the ObservableList of the serieses of the chart. So the following code in the controller.

The controller class injects the following from the fxml file.

@FXML
public TableView<Series<Number, Number>> tableViewStatisticsOverview;

@FXML
public TableColumn<Series<Number, Number>, String> tableColumnStatisticName;

@FXML
public TableColumn<Series<Number, Number>, Series<Number, Number>> tableColumnShowSeries;

@FXML
public TableColumn<Series<Number, Number>, Series<Number, Number>> tableColumnAction;

//later on the code
tableViewStatisticsOverview.setItems(chart.getData()); // chart is a linexy chart

//setting up the tableColumnShowSeries to show a checkbox and show and hide the series


tableColumnShowSeries.setCellValueFactory(
            new Callback<TableColumn.CellDataFeatures<Series<Number, Number>, Series<Number, Number>>, ObservableValue<Series<Number, Number>>>() {

                @Override
                public ObservableValue<Series<Number, Number>> call(CellDataFeatures<Series<Number, Number>, Series<Number, Number>> param) {
                    return new ReadOnlyObjectWrapper<Series<Number, Number>>(param
                            .getValue());
                }
            });

tableColumnShowSeries.setCellFactory(
        new TableCollumnCellWithCheckBoxFactoryWrapper());

As data of the table I set the whole series on the row of the table so to be able to set the node of the series visible or not according to the value of the checkbox

TableCollumnCellWithCheckBoxFactoryWrapper class

package com.nokia.avalanche.client.util.fxhelper;

import javafx.scene.chart.XYChart.Series;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.util.Callback;

public class TableCollumnCellWithCheckBoxFactoryWrapper implements
    Callback<TableColumn<Series<Number, Number>, Series<Number, Number>>, TableCell<Series<Number, Number>, Series<Number, Number>>> {


@Override
public TableCell<Series<Number, Number>, Series<Number, Number>> call(TableColumn<Series<Number, Number>, Series<Number, Number>> param) {
        return new CheckBoxCell();
    }

}

CheckBoxCell class

public class CheckBoxCell
    extends TableCell<Series<Number, Number>, Series<Number, Number>> {

Logger LOG = LogManager.getLogger(CheckBoxCell.class);

private HBox checkBoxContainer;
private CheckBox checkBoxShow;

public CheckBoxCell() {
    checkBoxContainer = new HBox();
    checkBoxShow = new CheckBox("");
    checkBoxContainer.setAlignment(Pos.CENTER);
    checkBoxShow.setSelected(true);
    checkBoxContainer.getChildren().add(checkBoxShow);

}



private void addListenerOnCheckBox(Series<Number, Number> series) {

      checkBoxShow.setOnAction(new EventHandler<ActionEvent>() {

          @Override
          public void handle(ActionEvent arg0) {
              LOG.debug("Show checkbox selected: "
                    + checkBoxShow.isSelected());              
              series.getNode().setVisible(checkBoxShow.isSelected());
              if (series.getNode().isVisible()) {
                  series.getNode().toFront();
                  for (Data<Number, Number> data : series.getData()) {
                      data.getNode().toFront();
                  }
              } else {
                  series.getNode().toBack();
                  for (Data<Number, Number> data : series.getData()) {
                      data.getNode().toBack();
                  }
              }          
          }
      });


    }

    @Override
    protected void updateItem(Series<Number, Number> series, boolean empty) {
        super.updateItem(series, empty);
        if (!empty && series != null) {

            addListenerOnCheckBox(series);

            LOG.debug("Series is not empty");
            LOG.debug("Updating item for series with name: " + series.getName());
            setGraphic(checkBoxContainer);
        } else {
            LOG.debug("Series is empty");
            setGraphic(null);
        }

    }

}

The problem is that after adding some series on the chart and they show on the table and try to click on the check box one more check box behaves the same way as the one I am clicking that is It changes it's status from checked to unchecked according to the first one I click. Debugging shows that when code enters the handle method from the action handler the check box is the same object thus unchecking the one makes the other one unchecked. Have I missed something? Is there another way to use the check box and catch the change of checkbox status?




Aucun commentaire:

Enregistrer un commentaire