首页 > 解决方案 > 将行添加到 TableView(JavaFX 8)时,似乎无法以编程方式从 TableCell(类似 TextFieldTableCell)中选择 TextField

问题描述

在 JavaFX 8 中,我创建了一个带有 TextField 的自定义 TableCell,以便获得比使用“常规”TextFieldTableCell 更多的控制权。我想要实现的是在单击 Add 按钮时自动选择 TextField(因此用户不必在触发 Add-Record 按钮后单击该 TextField 或 Tab 。不幸的是,我只设法选择行/单元格,但不选择底层的 TextField (并且似乎没有达到 startEdit() 方法)。

这是我的代码(主要 FX 应用程序代码、POJO、在场景生成器中创建的 FXML 代码、控制器代码和 CustomTextFieldTableCell 类):

主.java

package test;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));

        Scene scene = new Scene(root);

        stage.setScene(scene);
        stage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

}

POJO

package test;

import javafx.beans.property.SimpleStringProperty;

class TestObject {

    private final SimpleStringProperty field1 = new SimpleStringProperty();
    private final SimpleStringProperty field2 = new SimpleStringProperty();

    public SimpleStringProperty field1Property() {
        return field1;
    }

    public void setField1(String string) {
        field1.set(string);
    }

    public SimpleStringProperty field2Property() {
        return field2;
    }

    public void setField2(String string) {
        field2.set(string);
    }



}

FXML文档.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane id="AnchorPane" prefHeight="425.0" prefWidth="517.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.171" fx:controller="test.FXMLDocumentController">
    <children>
        <Label fx:id="label" layoutX="126" layoutY="120" minHeight="16" minWidth="69" />
      <TableView fx:id="tableView" layoutX="14.0" layoutY="52.0" prefHeight="359.0" prefWidth="489.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="52.0">
        <columns>
          <TableColumn fx:id="col1" prefWidth="150.0" text="C1" />
          <TableColumn fx:id="col2" minWidth="0.0" prefWidth="141.0" text="C2" />
        </columns>
      </TableView>
      <Button fx:id="btnAdd" layoutX="14.0" layoutY="14.0" onAction="#handleAdd" text="_Add" />
    </children>
</AnchorPane>

FXMLDocumentController.java

package test;

import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;

public class FXMLDocumentController implements Initializable {

    @FXML
    private Button btnAdd;
    @FXML
    private TableView<TestObject> tableView;
    @FXML
    private TableColumn<TestObject, String> col1;
    @FXML
    private TableColumn<TestObject, String> col2;

    @FXML
    private void handleAdd(ActionEvent event) {
        TestObject testObject = new TestObject();
        tableView.getItems().add(testObject);
        tableView.edit(tableView.getItems().indexOf(testObject), col1);
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        col1.setCellValueFactory(cellData -> cellData.getValue().field1Property());
        col1.setCellFactory((final TableColumn<TestObject, String> column) -> new CustomTextFieldTableCell());
        col1.setOnEditStart((TableColumn.CellEditEvent<TestObject, String> event) -> {
            //Inside code doesn't seem to ever get reached
            System.out.println("Edit started");
        });
        col2.setCellValueFactory(cellData -> cellData.getValue().field2Property());
        col2.setCellFactory((final TableColumn<TestObject, String> column) -> new TableCell<>());
    }    

}

CustomTextFieldTableCell.java

package test;

import javafx.event.ActionEvent;
import javafx.scene.control.TableCell;
import javafx.scene.control.TextField;

public class CustomTextFieldTableCell extends TableCell<TestObject, String> {

    private final TextField textField;

    public CustomTextFieldTableCell() {
        textField = new TextField();
        textField.setOnAction((ActionEvent event) -> {
            commitEdit(textField.getText());
            event.consume();
        });
        textField.prefWidthProperty().bind(prefWidthProperty().subtract(3));
    }

    /** {@inheritDoc} */
    @Override
    public void startEdit() {
        if (!isEditable()
                || getTableView() == null
                || getTableColumn() == null
                || getTableView() != null && !getTableView().isEditable()
                || getTableColumn() != null && !getTableColumn().isEditable()) {
            return;
        }
        super.startEdit();

        if (isEditing()) {
            /*
            textField.setText(getItem().trim());
            this.setText(textField.getText());
            */
            //Platform.runLater(() -> textField.requestFocus());
            textField.requestFocus();
        }
    }

    /** {@inheritDoc} */
    @Override
    public void updateItem(String item, boolean empty) {
        super.updateItem(item, empty);
        setText(null);
        if (empty) {
            setGraphic(null);
        } else {
            textField.setText(item == null ? "" : item.trim());
            setGraphic(textField);
        }
    }

}

视觉上会发生什么:

在此处输入图像描述

我需要我的代码做的是将插入符号放置在 TextField 或 TextField 焦点内,但是我的代码现在不会发生这种情况。

在此处输入图像描述

知道我错过了什么吗?

标签: javafxtableviewtextfieldtablecell

解决方案


推荐阅读