问题
In JavaFX, the first time a stage is shown with Stage#show
takes a long time. I'm not talking about the time it takes to load FXML (which is a different issue altogether), but simply the time it takes between calling Stage#show
and the call returning (and the window shown to the user).
I have created this sample application, which creates a random scene with a few tabs, grid panes and table views, then times how long it takes to call Stage#show
:
package sample;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.util.Random;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("Speed test");
primaryStage.setScene(createScene(3, 3, 6, 8));
long start = System.nanoTime();
primaryStage.show();
long end = System.nanoTime();
System.out.println("Total seconds: " + ((double) (end - start)) / 1000000000);
}
private Scene createScene(int tabs, int rows, int columns, int tableColumns) {
TabPane tp = new TabPane();
for (int t = 0; t < tabs; t++) {
GridPane gp = new GridPane();
for (int r = 0; r < rows; r++) {
for (int c = 0; c < columns; c++) {
gp.add(getRandomControl(), c, r);
}
}
TableView<Object> tv = new TableView<>();
for (int i = 0; i < tableColumns; i++)
tv.getColumns().add(new TableColumn<>(getRandomString()));
VBox vb = new VBox(gp, tv);
tp.getTabs().add(new Tab(getRandomString(), vb));
}
return new Scene(tp);
}
private final String[] randomStrings = new String[]{
"foo",
"bar",
"baz",
"lorem",
"ipsum",
"dolor",
"sit",
"amet",
"adipiscing",
"elit",
"morbi",
"quis",
"tempus",
"justo",
"faucibus",
"justo",
"risus",
"nec",
"commodo",
"sem",
"congue"
};
private final Random random = new Random();
private String getRandomString() {
return randomStrings[random.nextInt(randomStrings.length)];
}
private Control getRandomControl() {
switch (random.nextInt(4)) {
case 0:
return new Label(getRandomString());
case 1:
return new TextField();
case 2:
return new PasswordField();
case 3:
ComboBox<String> cb = new ComboBox<>();
cb.getItems().addAll(randomStrings);
return cb;
default:
return null;
}
}
public static void main(String[] args) {
launch(args);
}
}
My results vary, of course, but they are always around 1.2 seconds, which doesn't sound like a lot, but is certainly noticeable, and not too much expected, considering my machine loads comparably complex UIs in a fraction of this time (as long as they're not written in JavaFX, that is).
So my question is - what causes this poor performance? Are there some tricks or hacks to minimize this time, similar to what is done to accelerate FXML loading?
来源:https://stackoverflow.com/questions/35214022/why-is-stageshow-so-slow-and-what-can-be-done-to-accelerate-it