【问题标题】:JavaFX thread makes the UI unresponsive , any alternative [Thread delay]JavaFX 线程使 UI 无响应,任何替代 [线程延迟]
【发布时间】:2016-07-06 08:14:45
【问题描述】:

JavaFX 线程使 UI 变慢并挂起。

这是代码,如果有人能提出原因或替代方案,那将很有帮助。

这是一个 MVC 应用程序。当代码到达这个线程时,它可以正常工作并且 UI 不会挂起,但不是这样,它会变成空白且无响应。

这是一个线程延迟问题。

Platform.runLater(new Runnable() {
    @Override
    public void run() {

        DecimalFormat df = new DecimalFormat("#,##0.00");
        setLabel(bidSide, viewResource_.getString(SELL), 95, 121, JFXConstants.jfxWhiteSmoke);
        setLabel(askSide, viewResource_.getString(BUY), 145, 121, JFXConstants.jfxWhiteSmoke);
        setLabel(bidAmount, df.format(0.0), 0, 122, JFXConstants.jfxGrey);
        setLabel(askAmount, df.format(0.0), 146, 122, JFXConstants.jfxGrey);

        bidAmount.setPrefWidth(110);
        bidAmount.setScaleX(0.87);
        bidAmount.setScaleY(0.87);
        bidAmount.setAlignment(Pos.CENTER_LEFT);

        askAmount.setPrefWidth(110);
        askAmount.setScaleX(0.87);
        askAmount.setScaleY(0.87);
        askAmount.setAlignment(Pos.CENTER_RIGHT);

        unlock.setVisible(false);
        lock.setVisible(false);
        lock.setOpacity(0.7);
        root.setStyle(FX_BACKGROUND_COLOR  + fxBlackString);
        greyPanel = createRectangle(310.0, 135.0, JFXConstants.jfxGrey, 0.0, 5.0);
        greyPanel.setOpacity(0.6);
        root.getChildren().add(greyPanel);
        if (getFastFXController().getModel() != null && getFastFXController().getModel()
                .getCurrency_() != null &&
                !getFastFXController().getModel().getCurrency_().equals(LNFConstants.EMPTY_STRING)) {
            try {
                javafx.scene.image.Image image =
                        new javafx.scene.image.Image(setImagePath(getFastFXController().getModel()
                                .getCurrency_()));
                flagView = new ImageView(image);
            } catch (Exception e) {
                flagView = new ImageView();
            }
            flagView.setLayoutX(6.0);
            flagView.setLayoutY(11.0);
            flagView.setFitWidth(242);
            flagView.setFitHeight(108);
            root.getChildren().add(flagView);
        }

        bidRect = new javafx.scene.shape.Rectangle();
        offerRect = new javafx.scene.shape.Rectangle();
        nearTenorGroup.getChildren().addAll(nearTenorRect,
                createJFxLabel(nearLabel, NEAR, 1, 0, JFXConstants.jfxWhite, javafx.scene.text.Font.font(FONT_ARIAL, FontWeight.NORMAL, 12)),
                createJFxLabel(tenor_, FastFXView.this.getFastFXController().getModel().getTenor_(), 9, 7, JFXConstants.jfxWhite, javafx.scene.text.Font.font(FONT_ARIAL, FontWeight.EXTRA_BOLD, 14))
        );
        nearLabel.setOpacity(0.4);
        tenor_.setOnMouseClicked(new EventHandler<javafx.scene.input.MouseEvent>() {
            @Override
            public void handle(javafx.scene.input.MouseEvent mouseEvent) {
                popUpGroups.get(NEAR_TENOR).requestFocus();
                popUpGroups.get(NEAR_TENOR).setVisible(true);
                popUpGroups.get(NEAR_TENOR).setLayoutX(219);
                popUpGroups.get(NEAR_TENOR).setLayoutY(1);
                popUpGroups.get(NEAR_TENOR).requestFocus();
                tenor_.setTextFill(JFXConstants.jfxGrey);
            }

        });
        tenor_.setOnMouseEntered(new EventHandler<javafx.scene.input.MouseEvent>() {
            @Override
            public void handle(javafx.scene.input.MouseEvent mouseEvent) {
                tenor_.setOpacity(0.8);
            }
        });
        tenor_.setOnMouseExited(new EventHandler<javafx.scene.input.MouseEvent>() {
            @Override
            public void handle(javafx.scene.input.MouseEvent mouseEvent) {
                tenor_.setOpacity(1);
            }
        });
        root.getChildren().add(nearTenorGroup);
        farTenorGroup.getChildren().addAll(farTenorRect,
                createJFxLabel(farLabel, FAR, 1, 0, JFXConstants.jfxWhite, javafx.scene.text.Font.font(FONT_ARIAL, FontWeight.NORMAL, 12)),
                createJFxLabel(tenorFar_, FastFXView.this.getFastFXController().getModel().getTenorFar_(), 9, 7, JFXConstants.jfxWhite, javafx.scene.text.Font.font(FONT_ARIAL, FontWeight.EXTRA_BOLD, 14))
        );

        farLabel.setOpacity(0.4);
        tenorFar_.setOnMouseClicked(new EventHandler<javafx.scene.input.MouseEvent>() {
            @Override
            public void handle(javafx.scene.input.MouseEvent mouseEvent) {
                popUpGroups.get(FAR_TENOR).requestFocus();
                popUpGroups.get(FAR_TENOR).setVisible(true);
                popUpGroups.get(FAR_TENOR).setLayoutX(219);
                popUpGroups.get(FAR_TENOR).setLayoutY(5);
                popUpGroups.get(FAR_TENOR).requestFocus();
                tenorFar_.setTextFill(JFXConstants.jfxGrey);
            }

        });
        tenorFar_.setOnMouseEntered(new EventHandler<javafx.scene.input.MouseEvent>() {
            @Override
            public void handle(javafx.scene.input.MouseEvent mouseEvent) {
                tenorFar_.setOpacity(0.8);
            }
        });
        tenorFar_.setOnMouseExited(new EventHandler<javafx.scene.input.MouseEvent>() {
            @Override
            public void handle(javafx.scene.input.MouseEvent mouseEvent) {
                tenorFar_.setOpacity(1);
            }
        });
        root.getChildren().add(farTenorGroup);
        nearTenorGroup.setLayoutX(257);
        nearTenorGroup.setLayoutY(10);
        farTenorGroup.setLayoutX(257);
        farTenorGroup.setLayoutY(25);
        setItemsForPopup(NEAR_TENOR, getFastFXController().getModel().getTenors_());
        setItemsForPopup(FAR_TENOR, getFastFXController().getModel().getTenorsFar_());
        mapRectToPane(bidRect, liveBid);
        mapRectToPane(offerRect, liveAsk);
        bidRect.setFill(JFXConstants.jfxTransparent);
        offerRect.setFill(JFXConstants.jfxTransparent);
        root.getChildren().addAll(liveBid, liveAsk);
        root.getChildren().addAll(flip, toggle, lock, unlock);
        root.getChildren().addAll(offerRect, bidRect);
        root.getChildren().addAll(bidSide, bidAmount, askSide, askAmount);
        mouseEvents();
    }
}

【问题讨论】:

  • 我什至不明白问题是什么。您发布的代码是否运行缓慢?或者?您已将所有代码放在 Platform.runLater 块中,因此,里面的任何内容都将在 JavaFX GUI 线程上执行,因此在这个问题中没有任何关于线程的内容。
  • 图片加载速度有多快?您加载的图像有多大?您从哪里加载它(硬盘驱动器/jar/web 网络...)?
  • Platform.runLater() 在代码中多次使用(100+)来更新 UI,从而使应用程序变慢,但我找不到任何替代方法。 stackoverflow.com/users/5966775/dvargastackoverflow.com/users/2991525/fabian

标签: java multithreading user-interface javafx


【解决方案1】:

两句话: 在后台的另一个线程中运行一些东西:使用Task。类似的东西

    Task loadDatesFromDB = new Task<Void>() {
        @Override
        protected Void call() throws Exception {
            List<Anfrage> list = ...something works slow...
            Platform.runLater(() -> {                   
                progressImage.setImage(null);
            }); 
            return null;
        }            
    };
    new Thread(loadDatesFromDB).start();  

请记住,您可以从 Platform.runLater 的另一个线程中的主线程(所有 UI 运行的地方)“工作”

而且你必须阅读它: Concurrency in JavaFX

【讨论】:

  • 我确实试过这个,但它给出了一个例外。见stackoverflow.com/questions/38299892/…
  • “不在 FX 应用程序线程上”意味着您尝试从另一个线程使用 GUI(几乎所有任务中的所有内容)执行某些操作。答案:“修改...应该在 JavaFX ...线程上进行”是正确的。仔细查看我的示例:您在 Task 中做了一些事情,工作缓慢(加载图像等)并且与 GUI 没有任何关系(!)。它使您的主要 JavaFX 线程负责。之后(在完成“缓慢”过程之后)您将其“结果”添加到 GUI(将此图像设置为标签或其他)内部(!)Platform.runLater(所有内部都将在主 FX 线程中执行) .
  • 我真的很抱歉,但我现在没有时间由我来代表您的问题并为您的代码制作一些 rafactor 以使其正常工作,但我在一些“慢”中使用任务放置在我的 JavaFX 中(在我的情况下,它是从 DB 加载以便将其添加到 TableVoew 中) - 它工作起来非常简单。对不起我的英语:)
猜你喜欢
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
  • 2011-10-18
  • 1970-01-01
  • 2011-07-28
  • 2013-08-31
  • 1970-01-01
相关资源
最近更新 更多