我正在使用JavaFX中的TableView。我想做的是跟踪对表格的编辑。当用户离开表格时,我想检查是否有任何编辑,如果是,则提示用户询问他们是否要保存更改。
我有TableView工作,我可以跟踪编辑,我可以确定TableView何时失去焦点(使用focusedProperty更改侦听器)。
然而,问题是当单击一个单元格进行编辑时,表格的focusedProperty更改侦听器将触发(编辑单元格获得焦点,表格本身会丢失它)。我真正想要的是一种方法来判断焦点更改时是否更改为表的子节点(例如列或单元格)或表外的某些内容(在父GUI上选择不同的选项卡)。但我不想将侦听器添加到可以单击的每个其他可能节点。
如果我知道如何获取当前关注的项目(还没有看到如何做到这一点),我可以递归调用getParent()并检查TableView是否在该列表中,如果是,我会知道这是个孩子。但我还没有看到一种通用的方法来获取应用程序中当前关注的节点。
没有好的通用方法来遍历表的子节点,因为getChildrenUnmodifiable()返回我的Node()类型(我想我可以逐个演员来确定他们每个人是否有更多孩子),或者我必须去从TableColumns到那里的单元格(并检查每个单元格的图形)。
我可能会以递归方式迭代子项,根据需要进行转换,并在此时检查isFocused(),除非有更好的解决方案。但是我希望这里的某个人能够更好地解决这个问题,最好是更通用的解决方案。
答案 0 :(得分:6)
我从节点进行搜索,投射到孩子并检查焦点节点是否是孩子。它不优雅 - 当然感觉应该有更好的方式。但这是我过去常用的方法:
private boolean isChildFocused(javafx.scene.Parent parent)
{
for (Node node : parent.getChildrenUnmodifiable())
{
if (node.isFocused())
{
return true;
}
else if (node instanceof javafx.scene.Parent)
{
if (isChildFocused((javafx.scene.Parent)node))
{
return true;
}
}
}
return false;
}
它似乎工作正常(至少使用TableView作为根级父级),当父级的focusedProperty()更改为false(通过属性更改侦听器)时调用此方法。
答案 1 :(得分:5)
您可以通过场景的getFocusOwner()或focusOwnerProperty()获取当前关注的节点。正如您所说,从焦点节点到TableView的遍历更好。
public void createTable() {
TableView tableView = new TableView();
tableView.focusedProperty().addListener((ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) -> {
if (oldValue && !newValue) {
if (!isParent(tableView, tableView.getScene().getFocusOwner())) {
System.out.println("Saving changes.");
}
}
});
}
public boolean isParent(Parent parent, Node child) {
if (child == null) {
return false;
}
Parent curr = child.getParent();
while (curr != null) {
if (curr == parent) {
return true;
}
curr = curr.getParent();
}
return false;
}