为什么`Stage#show`如此之慢,以及如何加速它

时间:2016-02-05 00:01:07

标签: java javafx

在JavaFX中,第一次使用Stage#show显示一个阶段需要很长时间。我不是在谈论加载FXML所需的时间(完全是一个不同的问题),而只是调用Stage#show和返回的呼叫(以及向用户显示的窗口)之间的时间。 。

我创建了这个示例应用程序,它创建了一个包含几个标签,网格窗格和表格视图的随机场景,然后计算调用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);
    }
}

我的结果当然有所不同,但它们总是大约1.2秒,这听起来不是很多,但肯定是显而易见的,并没有太多的预期,考虑到我的机器在一小部分加载相对复杂的UI这一次(只要它们不是用JavaFX编写的,那就是)。

所以我的问题是 - 导致这种糟糕表现的原因是什么?是否有一些技巧或黑客来缩短这个时间,类似于加速FXML加载所做的?

0 个答案:

没有答案