java JavaFX TableView - 无法编辑

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12895517/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 10:40:53  来源:igfitidea点击:

JavaFX TableView - can not be edited

javatableviewjavafx-2

提问by immerhart

I am trying to use the edit on a TableView. i used this tut as reference: http://docs.oracle.com/javafx/2/ui_controls/table-view.htm#but I am using a FXML file for the creation (with the JavaFX Scene Builder). I have checked the editable checkboxes for the table and the columns (in the Scene Builder), but if I execute the program, I am not able to edit the values. I have downloaded the example project from the tut and the editing works there... so, in my project the TextFielddoesn′t get opened :( The controller:

我正在尝试在TableView. 我使用这个 tut 作为参考:http: //docs.oracle.com/javafx/2/ui_controls/table-view.htm#但我使用 FXML 文件进行创建(使用 JavaFX Scene Builder)。我已经检查了表和列的可编辑复选框(在场景构建器中),但是如果我执行程序,我无法编辑值。我已经从 tut 下载了示例项目,编辑在那里工作......所以,在我的项目TextField中没有打开:( 控制器:

public class StatesPopupController implements Controllerable, Initializable {
    // <editor-fold desc="fxml import stuff" defaultstate="collapsed">
    @FXML //  fx:id="guiStatesTable"
    private TableView<StateData> guiStatesTable; // Value injected by FXMLLoader
    @FXML //  fx:id="guiColorColumn"
    private TableColumn<StateData, String> guiColorColumn; // Value injected by FXMLLoader
    @FXML //  fx:id="guiFontEffectColumn"
    private TableColumn<StateData, String> guiFontEffectColumn; // Value injected by FXMLLoader
    @FXML //  fx:id="guiUseColumn"
    private TableColumn<StateData, String> guiUseColumn; // Value injected by FXMLLoader
    @FXML //  fx:id="guiValueColumn"
    private TableColumn<StateData, String> guiValueColumn; // Value injected by FXMLLoader
    @FXML //  fx:id="guiStateAddColor"
    private TextField guiStateAddColor; // Value injected by FXMLLoader
    @FXML //  fx:id="guiStateAddFontEffect"
    private TextField guiStateAddFontEffect; // Value injected by FXMLLoader
    @FXML //  fx:id="guiStateAddUse"
    private TextField guiStateAddUse; // Value injected by FXMLLoader
    @FXML //  fx:id="guiStateAddValue"
    private TextField guiStateAddValue; // Value injected by FXMLLoader
// </editor-fold>

    private Modelable model = null;

    public StatesPopupController() {
        this.model = new StatesPopupModel();
    }

    @Override
    public Modelable getModel() {
        return model;
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        this.guiStatesTable.setEditable(true);
        this.guiValueColumn.setCellValueFactory(new PropertyValueFactory<StateData, String>("value"));
        this.guiColorColumn.setCellValueFactory(new PropertyValueFactory<StateData, String>("color"));
        this.guiUseColumn.setCellValueFactory(new PropertyValueFactory<StateData, String>("use"));
        this.guiFontEffectColumn.setCellValueFactory(new PropertyValueFactory<StateData, String>("fontEffect"));
        this.guiStatesTable.setItems(((StatesPopupModel)this.model).getTableData());
    }

    public void newAddBtnEvent(ActionEvent event {
        ((StatesPopupModel)this.model).addDataEntry(guiStateAddValue.getText(), guiStateAddColor.getText(), guiStateAddUse.getText(), guiStateAddFontEffect.getText());
        guiStateAddValue.clear();
        guiStateAddColor.clear();
        guiStateAddUse.clear();
        guiStateAddFontEffect.clear();
        this.guiStatesTable.setItems(((StatesPopupModel) this.model).getTableData());
    }

    public void newEditValueEvent(CellEditEvent<StateData, String> event) {

        ((StateData)event.getTableView().getItems().get(event.getTablePosition().getRow())).setValue(event.getNewValue());
    }

    public void newEditColorEvent(ActionEvent event) {
        System.out.print("asd");
    }

    public void newEditUseEvent(ActionEvent event) {}

    public void newEditFontEffectEvent(ActionEvent event) {}
}

Model:

模型:

public class StatesPopupModel implements Modelable {
    private ObservableList<StateData> data = FXCollections.observableArrayList(
        new StateData("inactive", "9", "permit", "plain"),
        new StateData("active", "2", "permit", "plain"),
        new StateData("unavailable", "7", "inhibit", "plain"),
        new StateData("available", "2", "permit", "plain"),
        new StateData("invisible", "2", "inhibit", "plain"),
        new StateData("visible", "4", "permit", "plain"),
        new StateData("controlSign", "10", "inhibit", "plain"),
        new StateData("label", "5", "permit", "plain"));

    public void addDataEntry(String value, String color, String use, String fontEffect) {
        data.add(new StateData(value, color, use, fontEffect));
    }

    public ObservableList<StateData> getTableData() {
        return data;
    }
}

The StateDataclass:

StateData类:

public class StateData
{
    private final SimpleStringProperty value;
    private final SimpleStringProperty color;
    private final SimpleStringProperty use;
    private final SimpleStringProperty fontEffect;

    public StateData(String value, String color, String use, String fontEffect) {
        this.value = new SimpleStringProperty(value);
        this.color = new SimpleStringProperty(color);
        this.use = new SimpleStringProperty(use);
        this.fontEffect = new SimpleStringProperty(fontEffect);
    }

    /**
     * @return the value
     */
    public String getValue() {
        return value.get();
    }

    /**
     * @param value the value to set
     */
    public void setValue(String value) {
        this.value.set(value);
    }

    /**
     * @return the color
     */
    public String getColor() {
        return color.get();
    }

    /**
     * @param color the color to set
     */
    public void setColor(String color) {
        this.color.set(color);
    }

    /**
     * @return the use
     */
    public String getUse() {
        return use.get();
    }

    /**
     * @param use the use to set
     */
    public void setUse(String use) {
        this.use.set(use);
    }

    /**
     * @return the fontEffect
     */
    public String getFontEffect() {
        return fontEffect.get();
    }

    /**
     * @param fontEffect the fontEffect to set
     */
    public void setFontEffect(String fontEffect) {
        this.fontEffect.set(fontEffect);
    }
}

And here the fxml:

这里是 fxml:

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

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>

<AnchorPane id="AnchorPane" minHeight="397.0" minWidth="264.0" prefHeight="397.0" prefWidth="427.0" xmlns:fx="http://javafx.com/fxml" fx:controller="controller.popup.StatesPopupController">
  <children>
    <Label text="States" AnchorPane.leftAnchor="14.0" AnchorPane.topAnchor="6.0">
      <font>
        <Font name="System Bold" size="15.0" />
      </font>
    </Label>
    <TableView fx:id="guiStatesTable" editable="true" prefHeight="311.0" prefWidth="236.0" AnchorPane.bottomAnchor="52.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="34.0">
      <columns>
        <TableColumn prefWidth="75.0" text="Value" fx:id="guiValueColumn" />
        <TableColumn prefWidth="75.0" text="Color" fx:id="guiColorColumn" />
        <TableColumn prefWidth="75.0" text="Use" fx:id="guiUseColumn" />
        <TableColumn prefWidth="75.0" text="fontEffect" fx:id="guiFontEffectColumn" />
      </columns>
    </TableView>
    <HBox id="HBox" alignment="CENTER" prefWidth="236.0" spacing="5.0" AnchorPane.bottomAnchor="17.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0">
      <children>
        <TextField fx:id="guiStateAddValue" prefWidth="93.0" promptText="Value" />
        <TextField fx:id="guiStateAddColor" prefWidth="79.0" promptText="Color" />
        <TextField fx:id="guiStateAddUse" prefWidth="79.0" promptText="Use" />
        <TextField fx:id="guiStateAddFontEffect" prefWidth="79.0" promptText="Font Effect" />
        <Button mnemonicParsing="false" onAction="#newAddBtnEvent" text="Add" />
      </children>
    </HBox>
  </children>
</AnchorPane>

Every help is welcome.

欢迎任何帮助。

edit: If I am using:

编辑:如果我使用:

.setCellFactory(TextFieldTableCell.forTableColumn());

I am getting this error:

我收到此错误:

error: method setCellFactory in class TableColumn<S,T> cannot be applied to given types;
    guiUseColumn.setCellFactory(TextFieldTableCell.forTableColumn());
                ^
  required: Callback<TableColumn<StateData,String>,TableCell<StateData,String>>
  found: Callback<TableColumn<Object,String>,TableCell<Object,String>>
  reason: actual argument Callback<TableColumn<Object,String>,TableCell<Object,String>> cannot be converted to Callback<TableColumn<StateData,String>,TableCell<StateData,String>> by method invocation conversion
  where S,T are type-variables:
    S extends Object declared in class TableColumn
    T extends Object declared in class TableColumn

回答by hossein ketabi

try this:

试试这个:

....setCellFactory(TextFieldTableCell.<StateData>forTableColumn());

回答by Sergey Grinev

To make TableVieweditable you should also provide a CellFactorywhich will handle creation of the editing controls.

为了使TableView可编辑,您还应该提供一个CellFactory将处理编辑控件的创建。

You can find corresponding part of the tutorial here: http://docs.oracle.com/javafx/2/ui_controls/table-view.htm#sthref119

您可以在此处找到教程的相应部分:http: //docs.oracle.com/javafx/2/ui_controls/table-view.htm#sthref119

回答by Kulik

I had same issue and I didn't find an appropriate solution with separated FXML view and controller. I also want to stick with this model. Above mentioned example didn't work for me. So I slightly modified this tutorial.

我遇到了同样的问题,但我没有找到具有分离 FXML 视图和控制器的合适解决方案。我也想坚持这个模型。上面提到的例子对我不起作用。所以我稍微修改了这个教程

The solution includes a custom TableCellFactory. It was necessary to change TableCellto TextFieldTableCelland add the following:

该解决方案包括自定义TableCellFactory. 这是必要的改变TableCell,以TextFieldTableCell和添加如下内容:

cell.setConverter(new StringConverter<T>() {
            @Override
            public String toString(T object) {
                return object.toString();
            }
            @Override
            public T fromString(String string) {
                return (T) string;
            }
        });

In Controller are new methods handling changes. For example

在控制器中是处理变化的新方法。例如

@FXML
protected void changeFirstName(CellEditEvent<Person, String> event) {
    ((Person) event.getTableView().getItems().get(event.getTablePosition().getRow())).setFirstName(event.getNewValue());
}

Reference is in FXML file

参考在 FXML 文件中

<TableColumn fx:id="firstNameColumn" text="First Name" prefWidth="100" onEditCommit="#changeFirstName">

You can find full changes in my full Maven example.

您可以在我的完整 Maven 示例中找到完整的更改。