lundi 23 octobre 2017

Why can't I select a checkbox in my tableview?

I have a javaFX 8 pane that contains a Piles TableView. When I select a Pile from the TableView, it queries a database and populates a second TableView with instances of LogExt. This second TableView includes a column of checkboxes mapped to the LogExt.selected boolean property.

When I run the application, I can't select any of the checkboxes.

LogExt:

public class LogExt {
    private BooleanProperty selected = new SimpleBooleanProperty();
    private Log log;

    public LogExt(Log log) {
        this.setSelected(false);
        this.log = log;
    }

    public boolean isSelected() {
        return selected.get();
    }

    public BooleanProperty selectedProperty() {
        return selected;
    }

    public void setSelected(boolean selected) {
        this.selected.set(selected);
    }

    public Log getLog() {
        return log;
    }

    public void setLog(Log log) {
        this.log = log;
    }
}

The controller:

public class CustomOrderController {
    @FXML
    private RadioButton openRadio;
    @FXML
    private ToggleGroup stageGroup;
    @FXML
    private TableView<Pile> pileTableView;
    @FXML
    private TableColumn<Pile, String> pileNoCol;
    @FXML
    private TableColumn<Pile, String> speciesCol;
    @FXML
    private TableColumn<Pile, String> gradeCol;
    @FXML
    private TableColumn<Pile, String> logTypeCol;
    @FXML
    private TableColumn<Pile, String> pileStartCol;
    @FXML
    private TableView<LogExt> logTable;
    @FXML
    private TableColumn<LogExt, Boolean> selectedCol;
    @FXML
    private TableColumn<LogExt, String> logSpeciesCol;
    @FXML
    private TableColumn<LogExt, String> logGradeCol;
    @FXML
    private TableColumn<LogExt, String> lengthCol;
    @FXML
    private TableColumn<LogExt, String> diameterCol;
    @FXML
    private TableColumn<LogExt, String> footageCol;
    @FXML
    private TextField totalFootageField;
    @FXML
    private TextField selectedFootageField;
    @FXML
    private Button clearButton;
    @FXML
    private TextField reportNoField;
    @FXML
    private Button saveButton;

    private ObservableList openPileList = null;
    private ObservableList finishedPileList = null;
    private final static Logger LOG = LoggerFactory.getLogger(CustomOrderController.class);

    @FXML
    protected void initialize() {
        super.initialize();

        // Set table columns to display proper values.
        pileNoCol.setCellValueFactory(new PropertyValueFactory<>("pileNo"));
        speciesCol.setCellValueFactory(param -> {
            StringProperty stringProperty;
            if (param.getValue().getSpecies() != null)
                stringProperty = new SimpleStringProperty(param.getValue().getSpecies().getName());
            else stringProperty = new SimpleStringProperty("All");
            return stringProperty;
        });
        gradeCol.setCellValueFactory(param -> {
            StringProperty grade;
            if (param.getValue().getGrade() != null)
                grade = new SimpleStringProperty(param.getValue().getGrade().getName());
            else grade = new SimpleStringProperty("All");
            return grade;
        });
        logTypeCol.setCellValueFactory(param -> {
            StringProperty logType;
            if (param.getValue().getLogType() != null)
                logType = new SimpleStringProperty(param.getValue().getLogType().getName());
            else logType = new SimpleStringProperty("All");
            return logType;
        });
        pileStartCol.setCellValueFactory(param -> {
            StringProperty startDate;
            if (param.getValue().getPileStart() != null)
                startDate = new SimpleStringProperty(
                        param.getValue().getPileStart().format(DATETIMEFORMATTER));
            else startDate = null;
            return startDate;
        });
        // Add listener to catch table selections.
        pileTableView.getSelectionModel().selectedItemProperty().addListener(
                (observable, oldValue, newValue) -> selectPile());

        // Add listener to catch radio button selections.
        stageGroup.selectedToggleProperty().addListener((
                observable, oldValue, newValue) -> changeList());
        // Ensure values entered in the limit/warning fields are acceptable.
        reportNoField.setTextFormatter(new TextFormatter<>(INTEGERSTRINGCONVERTER
                , 0, POSINTEGERFILTER));

        selectedCol.setCellValueFactory(new PropertyValueFactory<>("selected"));
        selectedCol.setCellFactory(CheckBoxTableCell.forTableColumn(selectedCol));
        logSpeciesCol.setCellValueFactory(param ->
                new SimpleStringProperty(param.getValue().getLog().getSpecies().getName()));
        logGradeCol.setCellValueFactory(param ->
                new SimpleStringProperty(param.getValue().getLog().getLogGrade().getName()));
        lengthCol.setCellValueFactory(param ->
                new SimpleStringProperty(String.format("%d", param.getValue().getLog().getDeductionLength())));
        diameterCol.setCellValueFactory(param ->
                new SimpleStringProperty(String.format("%d", param.getValue().getLog().getDeductionDiameter())));
        footageCol.setCellValueFactory(param ->
                new SimpleStringProperty(String.format("%d", param.getValue().getLog().getNetFootage())));
    }

    protected void refreshPane() {
        // Get the list of piles.
        openPileList = FXCollections.observableList(HibernateUtil.getProgramsCommonDB().
                query("from Pile where pileEnd = '" + NODATETIME.format(QUERYDATETIMEFORMATTER) + "'"));
        finishedPileList = FXCollections.observableList(HibernateUtil.getProgramsCommonDB().
                query("from Pile where pileEnd > '" + NODATETIME.format(QUERYDATETIMEFORMATTER) +
                        "' and consumeStart = '" + NODATETIME.format(QUERYDATETIMEFORMATTER) + "'"));
        changeList();

        // Set buttons and fields off to start.
        clear();
    }

    private void changeList() {
        clear();
        if (openRadio.isSelected()) pileTableView.setItems(openPileList);
        else pileTableView.setItems(finishedPileList);
    }

    private void enableWidgets(boolean yes) {
        clearButton.setDisable(!yes);
        logTable.setDisable(!yes);
        reportNoField.setDisable(!yes);
        LOG.info("OpenRadio: {}, enable: {}", openRadio.isSelected(), yes);
        saveButton.setDisable(true);
    }

    private void clearWidgets() {
        pileTableView.getSelectionModel().clearSelection();
        logTable.getItems().clear();
        totalFootageField.clear();
        selectedFootageField.clear();
        reportNoField.clear();
    }

    @FXML
    private void clear() {
        clearWidgets();
        enableWidgets(false);
    }

    private void selectPile() {
        Pile currentPile = pileTableView.getSelectionModel().getSelectedItem();
        if (currentPile != null) {
            // Fill the logs list with logs from this pile that have not been consumed.
            List oList = HibernateUtil.getLogsDB().query("from Log where pileID = "
                    + currentPile.getId()
                    + " and (consumeTime is null or consumeTime = '"
                    + NODATETIME.format(QUERYDATETIMEFORMATTER) + "')");
            List<LogExt> logList = new ArrayList<>();
            oList.forEach(o -> {
                LogExt logExt = new LogExt((Log) o);
                logList.add(logExt);
            });
            totalFootageField.setText(String.format("%d", logList.stream()
                    .mapToInt(value -> value.getLog().getNetFootage())
                    .sum()));
            logTable.setItems(FXCollections.observableList(logList));
            enableWidgets(true);
        }
    }
}




Aucun commentaire:

Enregistrer un commentaire