【问题标题】:JavaFX TableView - can not be editedJavaFX TableView - 无法编辑
【发布时间】:2012-10-05 10:05:45
【问题描述】:

我正在尝试在 TableView 上使用编辑。 我用这个 tut 作为参考: http://docs.oracle.com/javafx/2/ui_controls/table-view.htm# 但我正在使用 FXML 文件进行创建(使用 JavaFX 场景生成器)。 我已经检查了表和列的可编辑复选框(在场景生成器中),但是如果我执行程序,我将无法编辑这些值。我已经从 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) {}
}

型号:

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

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

这里是 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>

欢迎任何帮助。

编辑: 如果我正在使用:

.setCellFactory(TextFieldTableCell.forTableColumn());

我收到此错误:

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

【问题讨论】:

  • 我不明白。这个傻瓜只是不打开文本字段
  • 我遇到了完全相同的问题。问题似乎是 TextFieldTableCell.forTableColumn() 使用泛型,因为方法签名如下: public static Callback, TableCell> forTableColumn() 我没有'还没弄清楚如何调用使用泛型的静态方法。

标签: java tableview javafx-2


【解决方案1】:

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

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

【讨论】:

  • 是的,我也试过了。但我收到了这个错误:(见主帖)你知道如何解决这个问题吗?
  • 我用给定的参数创建了一个新的回调,它现在可以工作了!谢谢。
  • @immerhart 发布您提出的解决方案将帮助 SO 社区,而不仅仅是接受没有为您提供解决方案的答案。
【解决方案2】:

试试这个:

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

【讨论】:

    【解决方案3】:

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

    该解决方案包括一个自定义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;
                }
            });
    

    在控制器中是处理更改的新方法。例如

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

    参考在 FXML 文件中

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

    您可以在我的full Maven example 中找到全部更改。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-10-19
      • 2014-10-14
      • 2014-02-22
      • 1970-01-01
      • 2013-09-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多