JavaFX - 初始化时未选择ListView项

时间:2017-11-14 23:38:49

标签: java listview javafx javafx-8

大家好我对JavaFX中包含ListView的场景初始化有一个相当奇怪的问题。

问题在于,当我为程序初始化场景时,我希望选择ListView的第一项。但是,如果我能够选择它(通过稍后提到的奇怪方法),则ListView本身不是焦点。我想要发生的是ListView中的第一项选择 ListView是焦点。

我将以最少的代码开始尝试说明我的问题:

public class SceneSetter {

static Stage mainStage;
static Scene adminScene;
static AdminController adminCont;

public static void initialize(Stage stage) throws IOException {
    mainStage = stage;

    FXMLLoader adminLoader = new FXMLLoader();
    adminLoader.setLocation(SceneSetter.class.getResource("/view/Admin.fxml"));
    SplitPane adminRoot = adminLoader.load();
    adminScene = new Scene(adminRoot);
    adminCont = adminLoader.getController();

    goToAdmin();
}

public static void goToAdmin() {
    mainStage.setScene(adminScene);
    //adminCont.initialize();
    mainStage.show();
}
}

我的原始程序有多个场景,都需要在程序启动时设置。因此,在这个SceneSetter类中,所有这些场景都被设置并添加了控制器。我已经删除了这些,因为这段代码能够证明这个问题。

我的admincontroller如下:

public class AdminController {
Stage mainStage;
private ObservableList<User> userList;

@FXML
private ListView<User> userListView;

@FXML
private Button adminAdd;

public void initialize() {
    userListView.setItems(Admin.getUserlist());
    userListView.getSelectionModel().select(0);
    userListView.getFocusModel().focus(0);
}

public void setMainStage(Stage s) {
    mainStage = s;
}
}

这里的问题是,当我运行我的代码时,我想要选择的项目是:

  1. 未选中
  2. 不在焦点
  3. 我的困惑是以下复杂的。如果在我的SceneSetter类中,在我的goToAdmin方法中,注释的代码行adminCont.initialize()被注释,程序显示如下:

    enter image description here

    当我取消注释同一行代码时,程序显示如下:

    enter image description here

    在第一个实例中,甚至没有选择正确的项目。在第二个中,ListView不是焦点。

    如何解决此问题?

1 个答案:

答案 0 :(得分:0)

为了集中控制,您需要请求它。您要搜索的方法是requestFocus()。但是有一个问题!阅读JavaDoc:

  

要有资格获得焦点,节点必须是场景的一部分,   它和它的所有祖先必须是可见的,而且绝对不可能   禁用

这意味着你有两个选择。

  • 您可以调用requestFocus()内的Platform.runLater(),以确保已创建场景图。

  • 您可以在场景中添加控件后调用requestFocus()

示例:

import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.stage.Stage;

public class SceneSetter extends Application {

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

    @Override
    public void start(Stage mainStage) throws Exception {
        ListView<String> list = new ListView<String>();
        ObservableList<String> items = FXCollections.observableArrayList("Single", "Double", "Suite", "Family App");
        list.setItems(items);

        list.getSelectionModel().select(0);

        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                list.requestFocus();
            }
        });

        mainStage.setScene(new Scene(list));
        // or here 
        // list.requestFocus();
        mainStage.show();
    }

}

FXML文件的示例

主要

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.stage.Stage;

public class SceneSetter extends Application {

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

    @Override
    public void start(Stage mainStage) throws Exception {
        ListView<String> list = FXMLLoader.load(this.getClass().getResource("GUI.fxml"));

        mainStage.setScene(new Scene(list));

        mainStage.show();
    }

}

控制器

import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.ListView;

public class MyController {

    @FXML
    private ListView<String> userListView;

    @FXML
    public void initialize() {

        ObservableList<String> items = FXCollections.observableArrayList("Single", "Double", "Suite", "Family App");
        userListView.setItems(items);
        userListView.getSelectionModel().select(0);

        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                userListView.requestFocus();
            }
        });
    }
}