我有一个基本的JavaFX程序,包含一个带有一些标签和几个按钮等的窗口。在OSX和Linux上,一切都很好,但在Windows 10上,移动主窗口似乎给我的图形带来了巨大压力卡片,每当我在应用程序的窗口和另一个窗口之间切换时,整个屏幕都会闪烁一秒钟。这只适用于此应用程序,该系统是一款高性能游戏装备,配备G-Sync,980 GTX,i7-6700k,16 GB RAM,双显示器等,并且在各种CPU和GPU基准测试中表现非常出色,真的,真的,不应该在屏幕上移动窗口时遇到任何问题。
当我在任务管理器中观察Java进程时,RAM使用情况没有任何明显的变化,并且当在整个屏幕上移动窗口时,CPU使用率仅为~1.4%。当拖动窗口时,它似乎只在20 FPS左右更新,而在我的系统上移动任何其他窗口似乎以60+ FPS运行。简而言之,在视觉上渲染我的JavaFX窗口时会出现某种奇怪的性能瓶颈。
据我所知,我没有使用任何3D功能或任何类似的东西,而且我没有做任何奇怪的JavaFX。我的窗口创建代码基于Oracle的标准教程,介绍了如何初始化JavaFX窗口等等。
下面是我的JavaFX窗口的初始化代码,以及来自控制器的init方法:
Main.start():
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.hide();
lockInstance();
Platform.setImplicitExit(false);
hostServices = HostServicesFactory.getInstance(this);
AccountManager.init();
if(OS.isLinux()) {
CURRENT_OS = OS_TYPE.LINUX;
} else if(OS.isMacOS()) {
CURRENT_OS = OS_TYPE.OSX;
} else if(OS.isWindows()) {
CURRENT_OS = OS_TYPE.WINDOWS;
}
System.out.println("detected os: " + CURRENT_OS);
//AccountManager.urlPrefix = "http://localhost:8080/api/";
String res = "ERROR";
try {
res = JWSystem.getAppBundleName();
} catch (Exception e) {}
if(!res.contains("ERROR"))
DEPLOY_MODE = true;
System.out.println("DEPLOY_MODE: " + DEPLOY_MODE);
prefs = Preferences.userNodeForPackage(this.getClass());
FIRST_RUN = prefs.getBoolean("first_run", true);
prefs.putBoolean("first_run", false);
System.out.println("FIRST_RUN: " + FIRST_RUN);
if(FIRST_RUN && DEPLOY_MODE) {
createDesktopIcon();
}
// setup
Thread t = new Thread(new Runnable() {
@Override
public void run() {
if(CURRENT_OS == OS_TYPE.LINUX)
SystemIcons.initUbuntuMimeTypes();
if(FIRST_RUN && DEPLOY_MODE) {
addStartupEntry();
}
}
});
t.start();
// load UI
Parent root = FXMLLoader.load(getClass().getResource("assets/main.fxml"));
primaryStage.resizableProperty().setValue(Boolean.FALSE);
primaryStage.setTitle("DuroCloud");
Scene scene = new Scene(root, 600, 400);
mainScene = scene;
primaryStage.setScene(scene);
mainStage = primaryStage;
scene.getStylesheets().addAll(getClass().getResource("assets/overrides.css").toExternalForm());
primaryStage.show();
primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
public void handle(WindowEvent we) {
Platform.exit();
System.out.println("Stage is closing");
System.exit(0);
}
});
}
Controller.initialize():
public void initialize(URL fxmlFileLocation, ResourceBundle resources) {
faFolderIconImage = new Image(this.getClass().getResourceAsStream("assets/fa-folder_256_0_464646_none.png"));
faFileIconImage = new Image(this.getClass().getResourceAsStream("assets/fa-file_256_0_464646_none.png"));
faTextFileIconImage = new Image(this.getClass().getResourceAsStream("assets/fa-file-text_256_0_464646_none.png"));
faPdfFileIconImage = new Image(this.getClass().getResourceAsStream("assets/fa-file-pdf-o_256_0_464646_none.png"));
faMovieFileIconImage = new Image(this.getClass().getResourceAsStream("assets/fa-file-movie-o_256_0_464646_none.png"));
faImageFileIconImage = new Image(this.getClass().getResourceAsStream("assets/fa-file-image-o_256_0_464646_none.png"));
faExcelFileIconImage = new Image(this.getClass().getResourceAsStream("assets/fa-file-excel-o_256_0_464646_none.png"));
faCodeFileIconImage = new Image(this.getClass().getResourceAsStream("assets/fa-file-code-o_256_0_464646_none.png"));
faAudioFileIconImage = new Image(this.getClass().getResourceAsStream("assets/fa-file-audio-o_256_0_464646_none.png"));
faArchiveFileIconImage = new Image(this.getClass().getResourceAsStream("assets/fa-file-archive-o_256_0_464646_none.png"));
// text files
iconMap.put("txt", faTextFileIconImage);
iconMap.put("doc", faTextFileIconImage);
iconMap.put("docx", faTextFileIconImage);
iconMap.put("rtf", faTextFileIconImage);
iconMap.put("asc", faTextFileIconImage);
iconMap.put("cfg", faTextFileIconImage);
iconMap.put("log", faTextFileIconImage);
iconMap.put("ini", faTextFileIconImage);
iconMap.put("odt", faTextFileIconImage);
// pdf
iconMap.put("pdf", faPdfFileIconImage);
// movie files
String[] movie_formats = new String[] {"webm", "mkv", "flv", "vob", "ogv", "drc", "avi", "mov", "wmv", "yuv",
"rm", "rmvb", "asf", "mp4", "m4p", "m4v", "mpg", "mp2", "mpeg", "mpe", "mpv", "svi",
"3gp", "mxf", "roq", "nsv"};
for(String format : movie_formats) {
iconMap.put(format, faMovieFileIconImage);
}
// image files
String[] image_formats = new String[] {"png", "bmp", "jpg", "jpeg", "tiff", "gif", "raw"};
for(String format : image_formats) {
iconMap.put(format, faImageFileIconImage);
}
// excel
iconMap.put("xls", faExcelFileIconImage);
iconMap.put("ods", faExcelFileIconImage);
iconMap.put("xlsx", faExcelFileIconImage);
// code
iconMap.put("rb", faCodeFileIconImage);
iconMap.put("js", faCodeFileIconImage);
iconMap.put("html", faCodeFileIconImage);
iconMap.put("htm", faCodeFileIconImage);
iconMap.put("css", faCodeFileIconImage);
iconMap.put("xml", faCodeFileIconImage);
iconMap.put("php", faCodeFileIconImage);
iconMap.put("exe", faCodeFileIconImage);
iconMap.put("sh", faCodeFileIconImage);
iconMap.put("py", faCodeFileIconImage);
iconMap.put("bat", faCodeFileIconImage);
iconMap.put("jar", faCodeFileIconImage);
iconMap.put("java", faCodeFileIconImage);
iconMap.put("c", faCodeFileIconImage);
iconMap.put("cpp", faCodeFileIconImage);
iconMap.put("h", faCodeFileIconImage);
iconMap.put("makefile", faCodeFileIconImage);
iconMap.put("make", faCodeFileIconImage);
// audio
iconMap.put("asf", faAudioFileIconImage);
iconMap.put("mp3", faAudioFileIconImage);
iconMap.put("flac", faAudioFileIconImage);
iconMap.put("ogg", faAudioFileIconImage);
iconMap.put("wav", faAudioFileIconImage);
iconMap.put("wma", faAudioFileIconImage);
iconMap.put("webm", faAudioFileIconImage);
// archive
iconMap.put("7z", faArchiveFileIconImage);
iconMap.put("zip", faArchiveFileIconImage);
iconMap.put("rar", faArchiveFileIconImage);
iconMap.put("tar", faArchiveFileIconImage);
iconMap.put("gz", faArchiveFileIconImage);
iconMap.put("bz", faArchiveFileIconImage);
VBox accountAltVbox = new VBox();
HBox accountAltHbox = new HBox();
accountAltHbox.setAlignment(Pos.CENTER);
accountAltVbox.setLayoutX(60.0);
accountAltVbox.setLayoutY(40.0);
accountAltVbox.setSpacing(8);
accountEmailLabel.setText("test");
accountEmailLabel.setFont(new Font(18));
accountAltContent.setPrefWidth(800);
accountAltContent.setPrefHeight(800);
accountAltContent.getChildren().add(accountAltVbox);
accountAltVbox.getChildren().add(new Label("Logged in as:"));
accountAltHbox.getChildren().add(accountEmailLabel);
accountAltVbox.getChildren().add(accountAltHbox);
accountAltVbox.getChildren().add(accountLogoutButton);
UIFonts.setFontAwesomeGlyph(upButton, FontAwesomeIcon.LEVEL_UP);
UIFonts.setFontAwesomeGlyph(refreshButton, FontAwesomeIcon.REFRESH);
UIFonts.setFontAwesomeGlyph(openButton, FontAwesomeIcon.FOLDER_OPEN);
UIFonts.setFontAwesomeGlyph(saveButton, FontAwesomeIcon.DOWNLOAD);
UIFonts.setFontAwesomeGlyph(deleteButton, FontAwesomeIcon.TRASH);
UIFonts.setFontAwesomeGlyph(addButton, FontAwesomeIcon.PLUS);
UIFonts.setFontAwesomeGlyph(backupDirectoriesButton, FontAwesomeIcon.CLOUD);
loginEmailField.setOnKeyPressed(this::handleEmailFieldEnter);
loginPasswordField.setOnKeyPressed(this::handlePasswordFieldEnter);
loginButton.setOnAction(this::handleLoginButtonAction);
forgotPasswordLink.setOnAction(this::visitForgotPassword);
accountLogoutButton.setOnAction(this::handleLogoutButton);
refreshButton.setOnAction(this::handleRefreshButton);
upButton.setOnAction(this::handleUpButton);
addButton.setOnAction(this::handleAddButton);
deleteButton.setOnAction(this::handleDeleteButton);
fileBrowser.setCellFactory(new Callback<ListView<BrowserItem>, ListCell<BrowserItem>>() {
@Override
public ListCell<BrowserItem> call(ListView<BrowserItem> param) {
return new BrowserItemCell();
}
});
fileBrowser.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
if(event.getClickCount() == 2) {
BrowserItem selected = fileBrowser.getSelectionModel().getSelectedItem();
if(selected != null) {
if(selected.isFile) {
downloadSelected();
} else {
currentDirectoryId = selected.file.file_id;
refresh();
}
}
}
}
});
openButton.setDisable(true);
saveButton.setDisable(true);
deleteButton.setDisable(false);
if(!AccountManager.loggedIn()) {
mainTabPane.getSelectionModel().select(accountTab);
optionsTab.setDisable(true);
myFilesTab.setDisable(true);
}
}
答案 0 :(得分:0)
所以事实证明这是一个与JavaFX无关的线程相关问题,一旦我在我的应用程序中重新组织了一些东西,它就消失了。事实证明,每当拖动窗口时,就会调用列表视图上的更新方法,从而导致计算成本高昂的方法运行。但有趣的是,性能差异 仅在Windows 10系统上显而易见,并且确实会导致一些重大的图形问题。
TLDR:在控制绘图代码中不要做昂贵的计算,特别是在Windows 10上。