更改TableView JavaFX中的值列标题

更改TableView JavaFX中的值列标题,javafx,tableview,tablecolumn,Javafx,Tableview,Tablecolumn,我试图在JavaFX中创建一个TableView,用户可以通过双击表格标题来更改列标题的值。 应出现一个文本框,在填写新值后,该值应分配给列标题 与James评论中概述的方法略有不同: 将鼠标处理程序注册到表中 双击会干扰排序的内容时。。。但这是另一个问题,找到表示tableColumn的TableColumnHeader(如果有) 创建并连接一个文本字段,并按照James的建议将其设置为列的图形 请注意,TableColumnHeader的包取决于版本,对于fx8,它被认为是驻留在com.xx

我试图在JavaFX中创建一个TableView,用户可以通过双击表格标题来更改列标题的值。 应出现一个文本框,在填写新值后,该值应分配给列标题


与James评论中概述的方法略有不同:

将鼠标处理程序注册到表中 双击会干扰排序的内容时。。。但这是另一个问题,找到表示tableColumn的TableColumnHeader(如果有) 创建并连接一个文本字段,并按照James的建议将其设置为列的图形 请注意,TableColumnHeader的包取决于版本,对于fx8,它被认为是驻留在com.xx.skin中的内部api,对于fx9,它在javafx.xx.skin中是公共的

例如:

public class TableHeaderWithInput extends Application {
    TableView<Locale> table;

    protected void installHeaderHandler(Observable s) {
        table.addEventFilter(MouseEvent.MOUSE_PRESSED, e -> {
            if (e.isPrimaryButtonDown() &&  e.getClickCount() > 1) {
                EventTarget target = e.getTarget();
                TableColumnBase<?, ?> column = null;
                while (target instanceof Node) {
                    target = ((Node) target).getParent();
                    // beware: package of TableColumnHeader is version specific
                    if (target instanceof TableColumnHeader) {
                        column = ((TableColumnHeader) target).getTableColumn();
                        if (column != null) break;
                    }
                }
                if (column != null) {
                    TableColumnBase<?,?> tableColumn = column;
                    TextField textField = new TextField(column.getText());
                    textField.setMaxWidth(column.getWidth());
                    textField.setOnAction(a -> {
                        tableColumn.setText(textField.getText());
                        tableColumn.setGraphic(null);
                    });
                    textField.focusedProperty().addListener((src, ov, nv) -> {
                        if (!nv) tableColumn.setGraphic(null);
                    });
                    column.setGraphic(textField);
                    textField.requestFocus();
                }
                e.consume();
            }
        });
    }

    private Parent getContent() {
        table = new TableView<>(FXCollections.observableArrayList(
                Locale.getAvailableLocales()));
        table.setTableMenuButtonVisible(true);
        // quick hack: don't let sorting interfere ...
        table.setSortPolicy(e -> {return false;});
        TableColumn<Locale, String> countryCode = new TableColumn<>("CountryCode");
        countryCode.setCellValueFactory(new PropertyValueFactory<>("country"));
        TableColumn<Locale, String> language = new TableColumn<>("Language");
        language.setCellValueFactory(new PropertyValueFactory<>("language"));
        table.getColumns().addAll(countryCode, language);
        table.skinProperty().addListener(this::installHeaderHandler);
        BorderPane pane = new BorderPane(table);
        return pane;
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        primaryStage.setScene(new Scene(getContent(), 800, 400));
        primaryStage.setTitle(FXUtils.version());
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

    @SuppressWarnings("unused")
    private static final Logger LOG = Logger
            .getLogger(TableHeaderWithInput.class.getName());
}

尝试以下方法:将图形设置为标签,而不是在列上设置文本。您可以使用标签注册鼠标侦听器,该标签在双击时将图形更改为文本字段,并使用文本字段注册侦听器,当用户按enter键或文本字段失去焦点时,该文本字段将恢复为标签。这里的缺点是它禁止使用表的内置菜单按钮。如果您在执行此操作时遇到问题,请发布一个具体问题。