如何确保在继承

时间:2017-01-26 12:10:31

标签: java inheritance javafx superclass

我有这个超级类扩展TableView,我想要制作的每个表都应该继承。

这一行代码需要为从超类继承并需要ContextMenu的每个类执行:

// Sets the context menu for each specific row. This way no
// context menu will appear if we click on a row that is
// empty.
setRowFactory(r -> {
    TableRow<ObservableList<String>> row = new TableRow<ObservableList<String>>() {
        public void updateItem(ObservableList<String> item, boolean empty) {
            super.updateItem(item, empty);
            if (isEmpty()) {
                setContextMenu(null);
            } else {
                setContextMenu(contextMenu);
            }
        }
    };
});

问题是在执行此代码之前需要实例化ContextMenu,因此我无法放入超类的构造函数。

如果表需要ContextMenu(并非总是如此),我如何确保从超类继承的每个类按此顺序执行以下步骤:

  1. 使用ContextMenu实例实例化MenuItem(我想MenuItem个实例可以实例化,并在理论上稍后添加。
  2. 使用在步骤1中实例化的上下文菜单调用上面的“setRowFactory”代码。
  3. 我已经有几次迭代解决了这个问题,但仍未能提出令人满意的解决方案。也许我错过了一些明显的东西。

    编辑:如果您能够以某种方式禁止用户使用setContextMenu的原始TableView方法,以确保正确添加`ContextMenu,那将是完美的办法。但我想这是不可能的。

1 个答案:

答案 0 :(得分:1)

看起来你只是想抑制在表格中的空行上显示上下文菜单。更简单的方法是

public class MyTableView<T> extends TableView<T> {

    public MyTableView() {
        setRowFactory(tv -> {
            TableRow<T> row = new TableRow<>();
            row.setOnContextMenuRequested(e -> {
                if (row.isEmpty()) {
                    e.consume();
                }
            }
            return row ;
        });
    }

    // ...
}

要回答您提出的问题(确保您在致电setRowFactory后仅(并始终)致电setContextMenu):

你可以做

public class MyTableView<T> extends TableView<T> {

    private final ContextMenu contextMenu ;

    public MyTableView(ContextMenu contextMenu) {
        this.contextMenu = contextMenu ;

        setRowFactory(r -> {
            TableRow<ObservableList<String>> row = new TableRow<ObservableList<String>>() {
                public void updateItem(ObservableList<String> item, boolean empty) {
                    super.updateItem(item, empty);
                    if (isEmpty()) {
                        setContextMenu(null);
                    } else {
                        setContextMenu(contextMenu);
                    }
                }
            };
        });

    }

    // ...
}

public class MyTableView<T> extends TableView<T> {

    private ContextMenu rowContextMenu ;

    public ContextMenu getRowContextMenu() {
        return rowContextMenu ;
    }

    public void setRowContextMenu(ContextMenu contextMenu) {
        this.rowContextMenu = contextMenu ;

        setRowFactory(r -> new TableRow<ObservableList<String>>() {
            public void updateItem(ObservableList<String> item, boolean empty) {
                super.updateItem(item, empty);
                if (isEmpty()) {
                    setContextMenu(null);
                } else {
                    setContextMenu(rowContextMenu);
                }
            }
        });
    }

    // ...
}

甚至

public class MyTableView<T> extends TableView<T> {

    public MyTableView() {
        contextMenuProperty().addListener((obs, oldContextMenu, newContextMenu) -> {
            if (newContextMenu == null) {
                setRowFactory(r -> new TableRow<>());
            } else 
                setRowFactory(r -> new TableRow<ObservableList<String>>() {
                    public void updateItem(ObservableList<String> item, boolean empty) {
                        super.updateItem(item, empty);
                        if (isEmpty()) {
                            setContextMenu(null);
                        } else {
                            setContextMenu(newContextMenu);
                        }
                    }
                });
            }
        });
    }

    // ...
}