TableView中的行编辑 [英] Row edit in TableView

查看:123
本文介绍了TableView中的行编辑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在JavaFX中有一个 TableView (2.2 / Java 7是特定的),其中每列都是可排序的(实时排序),所有行/列都是可编辑的。作为一个例子,我们假设整个表代表一个订单。表中的每一行代表订单行,列代表订单行的属性,如产品,数量,价格等。用户可以添加,删除和编辑行(订单如他所愿。

I have a TableView in JavaFX (2.2/Java 7 to be specific), where each column is sortable (real-time sorted) and all rows/columns are editable. As an example, let's assume the entire table represents an "order". Each row in the table, represents "order lines", and the columns represents properties of the "order line", like "product", "quantity", "price" etc. The user can add, remove and edit rows ("order lines") as he wish.

为了减少用户对UI的困惑,我想使用行选择,并确保只有一行是一次可编辑(因为排序会使当前编辑的值在表中跳转)。我还对每个订单行进行验证,这对于行而不是单个列更容易可视化(例如,假设组合或产品X和数量7是非法的,因为产品X只能以单位订购5,我想要突出显示X和值7)。

To make the UI less confusing for the user, I would like to use row selection, and also make sure that only a single row is editable at a time (because sorting would otherwise make the currently edited value "jump" around in the table). I also have validation per "order line", which is easier to visualize for a row, rather than individual columns (as an example, assume the combination or product X and the quantity 7 is illegal, as product X can only be ordered in units of 5, I want to highlight both X and the value 7).

可以轻松启用行选择。但是是否有一种实现行编辑的好方法 TableView 中的默认/内置编辑模式更像是Excel,其中每个列可以单独编辑,提交和验证,这不是我想要的。我想要一个像文件浏览器中的文件列表。重要的是,已编辑行的所有编辑都将提交到支持模型(属性 TableView ),由于排序和验证,一次(即没有 onEditCommit 个别列)。

Row selection can easily be enabled. But is there a good way to implement row editing? The default/built in editing mode in a TableView is more like that of Excel where each column may be edited, committed and validated individually, and this is not what I want. I want something like the file list in a file explorer. It is important that all edits for the edited row are committed to the backing model (items property of the TableView) at once (ie. no onEditCommit for individual columns) because of the sorting and validation.

我已经实现了一些东西之前在Swing中类似,然后最终使用我命名的 ColumnList ,这实际上是 List ,但是列标题和列,使其看起来就像一个表。这也是JavaFX中可行的选择吗? TableColum 类似乎非常绑定到 TableView ,但我可能会遗漏一些东西。

I've implemented something similar before in Swing, and then ended up using what I named a ColumnList, which is really a List, but with column headers and columns, to make it appear just like a table. Would this be a viable choice in JavaFX too? The TableColum class seems very bound to a TableView, but I might be missing something.

我也知道JavaFX教程中的地址簿示例,它在表格下方有行选择和编辑器字段。这是我目前在我的应用程序中实现的,但我希望编辑与当前选定的行一致。因此,如果任何人都能找到实现这一目标的方法,那么让编辑器显示在当前所选行的顶部或内部也是一种替代方案。

I also am aware of the "Address book" example in the JavaFX tutorials, which has row selection and editor fields below the table. This is what I have currently implemented in my application, but I want the editing to appear in-line with the currently selected row. So, making the editors appear "on top" or "inside" the currently selected row would also be an alternative, if anyone can come up with a way to achieve that.

推荐答案

您可以随时制作自己的编辑框,并根据需要将其弹出桌面。这不是一个很好的解决方案,但通过一些调整可能会很好。 Dbl点击编辑一行。

You could always make your own editor box and pop it up over the table as needed. This isn't a great solution but with some tweaks it might be nice. Dbl click to edit a row.

import javafx.application.Application;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class TableEdit extends Application {

    @Override
    public void start(Stage primaryStage) {
        TableView<Order> tv = new TableView<>();
        ObservableList<Order> items = FXCollections.observableArrayList(
                new Order("a-12", 100), new Order("b-23", 200), new Order("c-34", 300));
        tv.setItems(items);

        TableColumn<Order, String> tcNum = new TableColumn("Order#");
        tcNum.setPrefWidth(100);
        TableColumn<Order, Number> tcQty = new TableColumn("Qty");
        tcQty.setPrefWidth(100);
        tcNum.setCellValueFactory(new PropertyValueFactory<>("orderNum"));
        tcQty.setCellValueFactory(new PropertyValueFactory<>("qty"));
        tv.getColumns().addAll(tcNum, tcQty);

        HBox hbox = new HBox();
        TextField orderNum = new TextField();
        orderNum.setPrefWidth(100);
        TextField qty = new TextField();
        qty.setPrefWidth(100);

        tv.getSelectionModel().selectedItemProperty().addListener((obs, ov, nv) -> {
            if (nv != null) {
                orderNum.setText(nv.orderNum.get());
                qty.setText(String.valueOf(nv.qty.get()));
            }
        });

        Button commit = new Button("Commit");
        commit.setOnAction(new EventHandler<ActionEvent>() {
            public void handle(ActionEvent evt) {
                Order item = tv.getSelectionModel().getSelectedItem();
                item.orderNum.set(orderNum.getText());
                item.qty.set(Integer.valueOf(qty.getText()));
                tv.toFront();
            }
        });

        hbox.getChildren().addAll(orderNum, qty, commit);
        StackPane root = new StackPane(hbox, tv);

        tv.setOnMouseClicked(new EventHandler<MouseEvent>() {
            public void handle(MouseEvent evt) {
                if (evt.getClickCount()==2){
                    StackPane.setMargin(hbox, new Insets(evt.getSceneY(), 0, 0, 0));
                    hbox.toFront();
                }
            }
        });

        Scene scene = new Scene(root, 300, 250);
        primaryStage.setScene(scene);
        primaryStage.show();

    }

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

    public class Order {

        private final SimpleStringProperty orderNum = new SimpleStringProperty();
        private final SimpleIntegerProperty qty = new SimpleIntegerProperty();

        public SimpleStringProperty orderNumProperty() {return orderNum;}
        public SimpleIntegerProperty qtyProperty() {return qty;}

        public Order(String orderNum, int qty) {
            this.orderNum.set(orderNum);
            this.qty.set(qty);
        }
    }
}

这篇关于TableView中的行编辑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆