【问题标题】:Why can't I select a checkbox in my tableview?为什么我不能在我的表格视图中选择一个复选框?
【发布时间】:2017-10-23 20:39:04
【问题描述】:

我有一个包含 Piles TableView 的 javaFX 8 窗格。当我从 TableView 中选择 Pile 时,它​​会查询数据库并使用 LogExt 实例填充第二个 TableView。第二个 TableView 包含一列映射到 LogExt.selected 布尔属性的复选框。

当我运行应用程序时,我无法选择任何复选框。

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;
    }
}

控制器:

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);
        }
    }
}

【问题讨论】:

    标签: checkbox java-8 tableview javafx-8


    【解决方案1】:

    您需要在您的表格上启用编辑功能。

    logTable.setEditable(true);
    

    也可能出现在您的专栏中

    selectedCol.setEditable(true); 
    

    【讨论】:

    • 我希望它这么简单。来自 JavaFX8 的 javadocs,Checkboxtablecell:“请注意,CheckBoxTableCell 呈现 CheckBox 'live',这意味着 CheckBox 始终是交互式的,并且可以由用户直接切换。这意味着单元格不必进入其编辑状态(通常由用户双击单元格)。”此外,来自 tablecolumn 文档:“这与 TableView.editableProperty() 和 TreeTableView.editableProperty() 不同,默认情况下为 true。”实验证实了这两个。
    • 生活和学习。一旦我使表格可编辑,这一切都奏效了。我不明白为什么在此功能的先前实现中从来没有必要这样做......但在这种情况下,logTable.setEditable(true) 起作用了。
    猜你喜欢
    • 2015-12-15
    • 1970-01-01
    • 1970-01-01
    • 2016-01-27
    • 1970-01-01
    • 2015-06-30
    • 1970-01-01
    • 2023-03-24
    • 2015-08-21
    相关资源
    最近更新 更多