我有一个ListView作为JavaFX分页控件的内容节点。
我的目的是在选择新页面后将焦点设置到ListView。
我的方法的问题是有时ListView具有焦点,但有时没有。
选择新页面后,如何确保ListView具有焦点?
平台:
Windows 7的
JDK 1.8.0.25(64位)
码:
package test.focus;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.scene.control.Pagination;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.util.Callback;
public class MainApp extends Application {
@Override
public void start(Stage stage) throws Exception {
Pagination pagination = new Pagination(5);
final ObservableList<String> texts = FXCollections.observableArrayList("a", "b", "c", "d", "e", "f", "g", "h", "i", "j");
final ListView<String> textsListView = new ListView<>();
pagination.setPageFactory(new Callback<Integer, Node>() {
@Override
public Node call(Integer page) {
textsListView.setItems(FXCollections.observableArrayList(texts.subList(page, page + 2)));
textsListView.getSelectionModel().select(0);
// Platform.runLater does not work, too
textsListView.requestFocus();
return textsListView;
}
});
BorderPane root = new BorderPane(pagination);
Scene scene = new Scene(root, 800, 600);
stage.setTitle("Focus issue");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
最佳答案
您需要两件事来始终将重点放在列表上:pagination
不应成为焦点遍历循环的一部分。
每当列表失去焦点时,都应再次请求它。
这对我有用:
final ListView<String> textsListView = new ListView<>();
textsListView.focusedProperty().addListener((ov,b,b1)->{
if(!b1){
textsListView.requestFocus();
}
});
pagination.setFocusTraversable(false);
pagination.setPageFactory(page -> {
textsListView.setItems(
FXCollections.observableArrayList(texts.subList(page, page + 2)));
textsListView.getSelectionModel().select(0);
textsListView.requestFocus();
return textsListView;
});
编辑
为了避免列表每次失去焦点时都请求焦点,此方法仅在加载新页面时才请求焦点:
final ListView<String> textsListView = new ListView<>();
final BooleanProperty loaded=new SimpleBooleanProperty(false);
pagination.setFocusTraversable(false);
pagination.setPageFactory(page -> {
textsListView.setItems(
FXCollections.observableArrayList(texts.subList(page, page + 2)));
textsListView.getSelectionModel().select(0);
loaded.set(true);
return textsListView;
});
loaded.addListener((ov,b,b1)->{
if(b1){
textsListView.requestFocus();
loaded.set(false);
}
});