JavaFX 2:获取TableCell行索引

8
我有一个带复选框的表格。当我点击第三或第四列中的复选框时,我想要改变第一列中的复选框的选择。我希望能够更改同一行中的其他单元格。我已经有了这些列,所以我想知道单元格所在的行。同时,我也非常不确定我到目前为止是否正确。我目前的做法主要参考以下内容:
- http://download.oracle.com/javafx/2.0/ui_controls/list-view.htm - http://download.oracle.com/javafx/2.0/ui_controls/table-view.htm - http://download.oracle.com/javafx/2.0/api/index.html?javafx/scene/control/Cell.html

enter image description here

这里是我的SSCCE(简短自包含可编译示例)

如果以下代码有任何问题,请纠正我。

package javafxapplication5;

import javafx.application.Application;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Callback;

public class JavaFXApplication extends Application {

    private static final ObservableList<ContactOptions> addContactOption = FXCollections.observableArrayList(
            new ContactOptions("Yes", "John Doe", "No", "Yes"),
            new ContactOptions("Yes", "Jane Doe", "No", null),
            new ContactOptions("Yes", "John Smith", "Yes", "Yes"),
            new ContactOptions("Yes", "Patty Smith", "Yes", "No"),
            new ContactOptions("Yes", "Jo Johnson", "Yes", "Yes"),
            new ContactOptions("No", "Mary Johnson", "No", "No"),
            new ContactOptions("Yes", "Clint Doe", "No", null),
            new ContactOptions("Yes", "Sally Sue", "No", "Yes"),
            new ContactOptions("Yes", "Bob Ryan", null, "Yes"),
            new ContactOptions("No", "Mary Sue", "No", "No"),
            new ContactOptions("Yes", "Bob Smith", "No", "Yes"));
    private static TableView<ContactOptions> contactOptions = new TableView<ContactOptions>();

    public static void main(String[] args) {
        Application.launch(JavaFXApplication.class, args);
    }

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Hello World");
        Group root = new Group();
        Scene scene = new Scene(root, 400, 200, Color.LIGHTGREEN);

        Callback<TableColumn, TableCell> cellFactory = new Callback<TableColumn, TableCell>() {

            @Override
            public TableCell call(final TableColumn param) {
                final CheckBox checkBox = new CheckBox();
                final TableCell cell = new TableCell() {

                    @Override
                    public void updateItem(Object item, boolean empty) {
                        super.updateItem(item, empty);
                        if (item == null) {
                            checkBox.setDisable(true);
                            checkBox.setSelected(false);
                        } else {
                            checkBox.setDisable(false);
                            checkBox.setSelected(item.toString().equals("Yes") ? true : false);
                            commitEdit(checkBox.isSelected() ? "Yes" : "No");
                        }
                    }
                };
                cell.setNode(checkBox);
                return cell;
            }
        };

        TableColumn firstCol = new TableColumn("Contact?");
        firstCol.setPrefWidth(60);
        firstCol.setProperty("one");
        firstCol.setCellFactory(cellFactory);

        TableColumn secondCol = new TableColumn("Name");
        secondCol.setPrefWidth(200);
        secondCol.setSortAscending(true);
        secondCol.setProperty("two");

        TableColumn thirdCol = new TableColumn("Call");
        thirdCol.setPrefWidth(60);
        thirdCol.setProperty("three");
        thirdCol.setCellFactory(cellFactory);

        TableColumn fourthCol = new TableColumn("Email");
        fourthCol.setPrefWidth(60);
        fourthCol.setProperty("four");
        fourthCol.setCellFactory(cellFactory);

        contactOptions.setItems(addContactOption);
        contactOptions.getColumns().addAll(firstCol, secondCol, thirdCol, fourthCol);
        contactOptions.setPrefSize(400, 200);

        root.getChildren().add(contactOptions);
        primaryStage.setScene(scene);
        primaryStage.setVisible(true);
    }

    public static class ContactOptions {

        private final StringProperty one;
        private final StringProperty two;
        private final StringProperty three;
        private final StringProperty four;

        ContactOptions(String col1, String col2, String col3, String col4) {
            this.one = new StringProperty(col1);
            this.two = new StringProperty(col2);
            this.three = new StringProperty(col3);
            this.four = new StringProperty(col4);
        }

        public String getOne() {
            return one.get();
        }

        public String getTwo() {
            return two.get();
        }

        public String getThree() {
            return three.get();
        }

        public String getFour() {
            return four.get();
        }
    }
}
2个回答

7

就快完成了

在调用commitEdit之前,需要调用getTableView().edit(getTableRow().getIndex(), param)。这会将单元格置于“编辑模式”。由于没有startEdit方法,进入编辑模式非常简单,但仍然是必需的。

之后,如此描述:http://download.oracle.com/javafx/2.0/ui_controls/table-view.htm

需要调用:

firstCol.setOnEditCommit(new EventHandler<EditEvent<String>>() {
    @Override
    public void handle(EditEvent<String> event) {
        String newValue = event.getNewValue();
        ContactOptions data = (ContactOptions) event.getTableView().getItems().get(event.getTablePosition().getRow());
        data.one.set(newValue)
        if(newValue.equals("No")) {
            data.three.set("No");
            data.four.set("No");
        }
    }
}

现在我需要知道的是如何在数据更新后更新表格的显示

1
使用Observable的优势在于JavaFX UI元素可以在“幕后”为您执行绑定。换句话说,如果您将数据模型类实现为JavaFX Bean,则每当其更改时,UI将自动更新。这是因为可观察模型中的绑定会自动分配和生成更改通知事件。
但是,为了使此功能正常工作,您必须根据JavaFX Bean范例定义数据模型,否则UI不会在更改发生时更新。
您的数据模型定义如下:
public static class ContactOptions {

    private final StringProperty one;
    private final StringProperty two;
    private final StringProperty three;
    private final StringProperty four;

    ContactOptions(String col1, String col2, String col3, String col4) {
        this.one = new StringProperty(col1);
        this.two = new StringProperty(col2);
        this.three = new StringProperty(col3);
        this.four = new StringProperty(col4);
    }

    public String getOne() {
        return one.get();
    }

    public String getTwo() {
        return two.get();
    }

    public String getThree() {
        return three.get();
    }

    public String getFour() {
        return four.get();
    }
}

针对您的第一个实例字段,我将只关注它。为了使其符合JavaFX属性范式的要求,您可以按照以下方式编写代码:

public static class ContactOptions {

    private final StringProperty one = new SimpleStringProperty();

    public final String getOne() { return this.one.get(); }
    public final void setOne(String v) { this.one.set(v); }
    public final StringProperty oneProperty() { return this.one; }

可以为JavaFX bean编写属性定义,以提供更懒的初始化方式,但这将起作用。 Java bean和JavaFX bean之间的区别在于,您还必须为该属性提供访问器(上面最后一行)。

如果将所有字段都变成类似上面的属性,则会发现UI会更新以反映更改。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接