[英]JavaFX - ListView item not selected upon Initialization
大家好,我有一個關於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類中設置了所有這些場景並添加了控制器。由於這些代碼可以演示問題,因此我將其刪除。
我的管理員如下:
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;
}
}
這里的問題是,當我運行代碼時,要選擇的項目是:
我的困惑是由於以下原因造成的。 如果在我的SceneSetter類中,在我的goToAdmin方法中,對注釋行adminCont.initialize()
的行保持注釋,則該程序如下所示:
當我取消注釋同一行代碼時,該程序如下所示:
在第一種情況下,甚至沒有選擇正確的項目。 在第二個中,ListView不在焦點上。
如何解決此問題?
為了集中控制,您需要請求它。 您要搜索的方法是requestFocus()
。 但是有一個問題! 閱讀JavaDoc:
為了有資格獲得焦點,該節點必須是場景的一部分,並且它及其所有祖先必須可見,並且不得禁用
因此,這意味着您有兩種選擇。
您可以在Platform.runLater()
中調用requestFocus()
,以確保已創建場景圖。
在場景上添加控件后,可以調用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();
}
});
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.