JavaFX 2:获取TableCell行索引

时间:2011-08-29 19:06:50

标签: java tableview tablerow tablecell javafx-2

我有一个带复选框的表格。当我单击第三列或第四列中的复选框时,我想更改第一列中复选框的选择。我希望能够更改同一行上的其他单元格。我已经有了这些列,所以我想知道单元格在哪一行。我也很不确定到目前为止我是否正确。

到目前为止,我所做的主要来自

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 个答案:

答案 0 :(得分:6)

几乎在那里

在致电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");
        }
    }
}

现在我需要知道的是how to update the table's display once the data is updated

答案 1 :(得分:1)

使用Observables的一个优点是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属性的JavaFX bean范例,请以这种方式编写代码,例如:

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更新以反映更改。