【问题标题】:JavaFX loading performance problems with FXMLFXML 的 JavaFX 加载性能问题
【发布时间】:2016-10-11 20:45:24
【问题描述】:

我有一个带有切换按钮的主文件,单击其中一个按钮时,我会启动一个新的FXMLLoader,其中包含大约 10 个 SVG、15 个文本字段和 6 个微调器。此外,它还具有相应地渲染节点的 CSS……它可以正常加载,没有错误或任何问题,但在显示场景之前需要一两秒。

我猜这是由于同时初始化的节点数量。有没有办法在节点开始初始化之前显示场景?

注意:我的项目需要我在点击时导航到不同的场景。

切换按钮的选择位置

   if(settings.isSelected()){
        Stage stage = (Stage) mainWrapper.getScene().getWindow();
        Parent root = FXMLLoader.load(getClass().getResource("/fxmlFiles/settings.fxml"));
        stage.setScene(new Scene(root, Screen.getPrimary().getVisualBounds().getWidth(),
                Screen.getPrimary().getVisualBounds().getHeight()));
        stage.centerOnScreen();
        //stage.setMaximized(true);
        stage.show();
    }

fxml文件

    <FlowPane xmlns:fx="http://javafx.com/fxml"
    fx:controller="controllers.motelInfoController"
    stylesheets="/cssFiles/motelInfo.css"
    fx:id="content">

    <VBox fx:id="mainWrapper">
    <VBox fx:id="validationWrapper">
        <Label fx:id="validationLabel" visible="false"/>
    </VBox>
    <VBox fx:id="generalInfo">
    <HBox> <!--First Row-->
            <HBox>
            <Group>
                <SVGPath fx:id="iconMotelName" scaleX="0.05" scaleY="0.05" fill="white"/>
            </Group>
            <Group>
                <TextField fx:id="miName" promptText="Motel Name"/>
            </Group>
            </HBox>
            <HBox>
                <Group>
                    <TextField fx:id="miFranchiseName" promptText="Franchise Name"/>
                </Group>
            </HBox>
        </HBox>
    <HBox> <!--Second Row-->
            <HBox>
                <Group>
                    <SVGPath fx:id="iconMotelAddress" scaleX="0.05" scaleY="0.05" fill="white"/>
                </Group>
                <Group>
                    <TextField fx:id="miAddress" promptText="Street Name"/>
                </Group>
            </HBox>
            <HBox>
                <Group>
                <TextField fx:id="miCity" promptText="City/Town Name"/>
                </Group>
            </HBox>
        </HBox>
    <HBox><!--Third Row-->
            <HBox style="-fx-spacing: 25px;">
                <Label></Label> <!--Empty label for purpose of leaving icon gap since N/A here-->
                <Group>
                    <TextField fx:id="miState" promptText="State"/>
                </Group>
            </HBox>
            <HBox>
                <Group>
                    <TextField fx:id="miZipCode" promptText="Zip Code"/>
                </Group>
            </HBox>
            <HBox>
                <Group>
                    <SVGPath fx:id="iconMotelContact" scaleX="0.05" scaleY="0.05" fill="white"/>
                </Group>
                <Group>
                    <TextField fx:id="miContact" promptText="Contact no."/>
                </Group>
            </HBox>
        </HBox>
    <HBox> <!--Fourth Row-->
            <HBox>
                <Group>
                    <SVGPath fx:id="iconMotelFax" scaleX="0.05" scaleY="0.05" fill="white"/>
                </Group>
                <Group>
                    <TextField fx:id="miFax" promptText="Fax no."/>
                </Group>
            </HBox>
            <HBox>
                <Group>
                    <SVGPath fx:id="iconMotelEmail" scaleX="0.05" scaleY="0.05" fill="white"/>
                </Group>
                <Group>
                    <TextField fx:id="miEmail" promptText="Email id"/>
                </Group>
            </HBox>
            <HBox>
                <Group>
                    <SVGPath fx:id="iconMotelNoOfRooms" scaleX="0.05" scaleY="0.05" fill="white"/>
                </Group>
                <Group>
                    <TextField fx:id="miNOR" promptText="No. of Rooms"/>
                </Group>
            </HBox>
        </HBox>
    <HBox style="-fx-spacing: 50px"> <!--Fifth Row-->
            <HBox>
                <Group>
                    <SVGPath fx:id="iconMotelCheckInTime" scaleX="0.05" scaleY="0.05" fill="white"/>
                </Group>
                <Group>
                    <Spinner fx:id="hourSpinnerCIT"/>
                </Group>
                <Group>
                    <Spinner fx:id="minSpinnerCIT"/>
                </Group>
                <Group>
                    <Spinner fx:id="secSpinnerCIT"/>
                </Group>
            </HBox>
            <HBox>
                <Group>
                    <SVGPath fx:id="iconMotelCheckOutTime" scaleX="0.05" scaleY="0.05" fill="white"/>
                </Group>
                <Group>
                    <Spinner fx:id="hourSpinnerCOT"/>
                </Group>
                <Group>
                    <Spinner fx:id="minSpinnerCOT"/>
                </Group>
                <Group>
                    <Spinner fx:id="secSpinnerCOT"/>
                </Group>
            </HBox>
        </HBox>
    </VBox>
    <VBox fx:id="roomOccupancy">
    <HBox> <!--First Row-->
            <Label fx:id="labelMaxGuestSelection"
                   text="Maximum Allowed Guest in individual Rooms. Please state the max count in adjacent cells"/>
            <VBox>
                <HBox>
                    <Group>
                        <SVGPath fx:id="iconMotelSingleBed" scaleX="0.05" scaleY="0.05" fill="white"/>
                    </Group>
                    <Group>
                        <TextField fx:id="miSB" promptText="Single Bed"/>
                    </Group>
                </HBox>
                <HBox>
                    <Group>
                        <SVGPath fx:id="iconMotelTwoBeds" scaleX="0.05" scaleY="0.05" fill="white"/>
                    </Group>
                    <Group>
                        <TextField fx:id="miTB" promptText="Two Beds"/>
                    </Group>
                </HBox>
                <HBox>
                    <Group>
                        <SVGPath fx:id="iconMotelfamilyRoom" scaleX="0.05" scaleY="0.05" fill="white"/>
                    </Group>
                    <Group>
                        <TextField fx:id="miFR" promptText="Family Room"/>
                    </Group>
                </HBox>
            </VBox>
        </HBox>
    <HBox> <!--Second Row-->
            <Label fx:id="labelMaxGuestCharged"
                    text="Rate Charged per Guest after max. allowed guest exceeds in a room"/>
            <HBox>
                <Group>
                    <SVGPath fx:id="iconMotelGuestExceedRate" scaleX="0.05" scaleY="0.05" fill="white"/>
                </Group>
                <Group>
                    <TextField fx:id="miGER" promptText="Rate/Guest Exceeded"/>
                </Group>
            </HBox>
        </HBox>
    </VBox>
    <VBox fx:id="submissionWrapper">
    <Group>
    <Button fx:id="submit" text="UPDATE" onAction="#saveData"/>
    </Group>
    </VBox>
    </VBox>

    </FlowPane>

FXML 控制器

@Override
public void initialize(URL location, ResourceBundle resources) {

    //Load the data if the motelInfo file exist
    File checkTemp = new File("motelDetails.ser");
    if(checkTemp.exists()){
        readDataFromFile();
    }

    //Getting Values for the spinner
    for(int i=0;i<24;i++){
        hourList.add(String.format("%02d", i));
    }
    final SpinnerValueFactory<String> hourValuesCIT = new SpinnerValueFactory.ListSpinnerValueFactory<>(hourList);
    final SpinnerValueFactory<String> hourValuesCOT = new SpinnerValueFactory.ListSpinnerValueFactory<>(hourList);
    for(int i=0; i<60; i++){
        minList.add(String.format("%02d", i));
        secList.add(String.format("%02d", i));
    }
    final SpinnerValueFactory<String> minValuesCIT = new SpinnerValueFactory.ListSpinnerValueFactory<>(minList);
    final SpinnerValueFactory<String> minValuesCOT = new SpinnerValueFactory.ListSpinnerValueFactory<>(minList);
    final SpinnerValueFactory<String> secValuesCIT = new SpinnerValueFactory.ListSpinnerValueFactory<>(secList);
    final SpinnerValueFactory<String> secValuesCOT = new SpinnerValueFactory.ListSpinnerValueFactory<>(secList);

    styleSpinner(hourSpinnerCIT, hourValuesCIT);
    styleSpinner(hourSpinnerCOT, hourValuesCOT);
    styleSpinner(minSpinnerCIT, minValuesCIT);
    styleSpinner(minSpinnerCOT, minValuesCOT);
    styleSpinner(secSpinnerCIT, secValuesCIT);
    styleSpinner(secSpinnerCOT, secValuesCOT);


} 

【问题讨论】:

  • 没有看到您的代码 - 很难帮助您。要尝试的一件事是在后台线程上创建所有这些对象,然后在创建完所有对象后将它们应用于场景图。
  • 我已经插入了加载 fxml 文件的代码。加载的 fxml 文件很简单,并且包含所有节点作为普通 fxml 文件
  • @purring pigeon 我编辑了我的帖子以适合所有文件...请您现在看一下...

标签: javafx-8 fxml


【解决方案1】:

看来你有两个问题:

  1. 在阻止更新的 UI 线程上运行长时间操作 (readDataFromFile())
  2. 在 FXMLoader.load() 中完成所有操作,在完成之前不允许绘制任何内容

我建议通过在不同的线程中运行加载并在它发生时显示加载屏幕来解决这两个问题。见下一个例子:

public class Main extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        StackPane loadingRoot = new StackPane();

        loadingRoot.getChildren().setAll(new ProgressIndicator());
        final Scene scene = new Scene(loadingRoot);

        stage.setWidth(400);
        stage.setHeight(400);
        stage.setScene(scene);
        stage.show();

        new Thread(() -> {
            veryLongOperation();

            // we need to wrap UI code in Platform
            Platform.runLater(() -> {
                Parent root;
                try {
                    root = FXMLLoader.load(Main.class.getResource("FXMLDocument.fxml"));
                    scene.setRoot(root);
                } catch (IOException ex) {
                }
            });
        }).start();
    }

    public static void veryLongOperation() {
            try {
                // long-long operation
                Thread.sleep(5000);
            } catch (Exception ex) {
            }

    }
}

【讨论】:

  • 我在这里推荐的一个改变是使用 JavaFX 并发来管理线程。使用 javafx.concurrent.Task 而不是 new Thread().
  • @purringpigeon 谢谢你们的意见......它现在就像一个魅力......几乎在那里,将在我的任务中完成......
  • 为什么要为超长操作声明一个静态方法?我认为使用非静态的是可以的。我只是想知道。
  • @ElyasHadizadeh,从技术上讲,它是一种实用方法,不需要知道任何关于 this 的信息即可工作。所以,我想,我在 5 年前自动给了他静态修饰符 :)
  • @SergeyGrinev 感谢您的回复,我明白了,今天您五年前的回答帮助了我 ;-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-08
  • 1970-01-01
  • 2013-07-22
  • 1970-01-01
  • 2015-08-31
相关资源
最近更新 更多