注意到一个以root显示“裸”控件的场景(在控件下面的示例中是TableView)最初没有focusOwner。事实上,根本没有focusOwner(场景的属性不会触发)。如果没有focusOwner,则无法通过键盘访问控件。承认,这不是一个非常现实的现实场景,但无论如何......
将控件添加到任何Parent,然后将该父控件设置为root将焦点转移到控件 - 这是我期望的。
出了什么问题 - 我的期望还是行为?
/**
* Table doesn't have focus initially if not wrapped into a Parent.
* jdk 8u60b5 (didn't try others)
*/
public class TableInitialCellEdit extends Application {
ObservableList<MenuItem> data = FXCollections.observableArrayList(
new MenuItem("some"),
new MenuItem("dummy"),
new MenuItem("data")
);
private Parent getContent() {
TableView<MenuItem> table = new TableView<>(data);
table.setEditable(true);
TableColumn<MenuItem, String> text = new TableColumn<>("Text");
text.setCellValueFactory(new PropertyValueFactory<>("text"));
text.setCellFactory(TextFieldTableCell.forTableColumn());
table.getColumns().addAll(text);
// focus transfered to table if contained in a pane
// return new Pane(table);
// focus not transfered to table if contained directly in the scene
return table;
}
@Override
public void start(Stage primaryStage) throws Exception {
Scene scene = new Scene(getContent());
scene.focusOwnerProperty().addListener((s, old, value) -> System.out.println(value));
primaryStage.setScene(scene);
primaryStage.setTitle(VersionInfo.getRuntimeVersion());
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
答案 0 :(得分:1)
从Node.requestFocus()的文档来看,我认为这种行为是个错误。
我的猜测是方法.com.sun.javafx.scene.traversal.TabOrderHelper#getFirstTargetNode(Parent)
public static Node getFirstTargetNode(Parent p) {
if (p == null || isDisabledOrInvisible(p)) return null;
final ParentTraversalEngine impl_traversalEngine = p.getImpl_traversalEngine();
if (impl_traversalEngine!= null && impl_traversalEngine.canTraverse()) {
Node selected = impl_traversalEngine.selectFirst();
if (selected != null) {
return selected;
}
}
List<Node> parentsNodes = p.getChildrenUnmodifiable();
for (Node n : parentsNodes) {
if (isDisabledOrInvisible(n)) continue;
final ParentTraversalEngine parentEngine = n instanceof Parent ? ((Parent)n).getImpl_traversalEngine() : null;
if (parentEngine != null ? parentEngine.isParentTraversable() : n.isFocusTraversable()) {
return n;
}
if (n instanceof Parent) {
Node result = getFirstTargetNode((Parent)n);
if (result != null) return result;
}
}
return null;
}
如果我正确读取它,它会递归p的层次结构以找到要聚焦的合适节点。在这种情况下,p是表。它通过其子级孩子进行递归但从未找到要关注的节点,直到它返回null。问题可能是,此方法从不考虑返回p本身。