首页 > 解决方案 > JavaFX 复杂的自拟态设计导致应用程序滞后

问题描述

我正在为我的应用程序创建一个加载屏幕,该应用程序使用 InnerShadow 进行了复杂的 Neumorphism 设计,尽管 CPU 和 RAM 使用量较少,但该应用程序会导致动画的滞后效果,例如 Gluon charm-glisten.jar 的循环进度指示器以及 PathTransition 动画。在这个加载屏幕中,您可以看到一个红色矩形在设计周围移动,最内层的蓝色进度指示器

Java 代码:

package application;
    
import java.net.URL;
import java.util.*;

import com.gluonhq.charm.glisten.control.ProgressIndicator;

import javafx.animation.*;
import javafx.animation.PathTransition.*;
import javafx.application.*;
import javafx.concurrent.*;
import javafx.event.*;
import javafx.fxml.*;
import javafx.stage.*;
import javafx.util.*;
import javafx.scene.*;
import javafx.scene.input.*;
import javafx.scene.layout.*;
import javafx.scene.paint.*;
import javafx.scene.shape.*;

public class Main extends Application implements Initializable
{
    private double xOffset = 0;
    private double yOffset = 0;
    
    @FXML
    ProgressIndicator pg1;
    static AnchorPane root;
    private PathTransition pathTransitionCircle;
    public void start(Stage primaryStage) 
    {
        try 
        {
            primaryStage.initStyle(StageStyle.TRANSPARENT);
            root = FXMLLoader.load(getClass().getResource("Test1.fxml"));
            Scene scene = new Scene(root,600,400);
            scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
            scene.setFill(javafx.scene.paint.Color.TRANSPARENT);
            primaryStage.setScene(scene);
            
            primaryStage.show();
            
            root.setOnMousePressed(new EventHandler<MouseEvent>() 
            {
                public void handle(MouseEvent e)
                {
                    xOffset = e.getSceneX();
                    yOffset = e.getSceneY();
                    
                }
            });
            
            root.setOnMouseDragged(new EventHandler<MouseEvent>() 
            {
                public void handle(MouseEvent e) 
                {
                    primaryStage.setX(e.getScreenX() - xOffset);
                    primaryStage.setY(e.getScreenY() - yOffset);
                }
            });
            
             Rectangle rect2 = new Rectangle(0, 0, 20, 20);
             rect2.setArcHeight(10);
             rect2.setArcWidth(10);
             rect2.setFill(Color.RED);
             root.getChildren().add(rect2);
                
             Path path2 = createEllipsePath(400, 200, 150, 150, 0);
             path2.setLayoutX(57);
             path2.setLayoutY(10);
             root.getChildren().add(path2);

             pathTransitionCircle = new PathTransition();
             pathTransitionCircle.setDuration(Duration.seconds(6));
             pathTransitionCircle.setPath(path2);
             pathTransitionCircle.setNode(rect2);
             pathTransitionCircle.setOrientation(OrientationType.ORTHOGONAL_TO_TANGENT);
             pathTransitionCircle.setCycleCount(PathTransition.INDEFINITE);
             pathTransitionCircle.setInterpolator(Interpolator.LINEAR);
             pathTransitionCircle.setAutoReverse(false);
             pathTransitionCircle.play();
        }
        catch(Exception e) 
        {
            e.printStackTrace();
        }
    }
    
    public static void main(String[] args) 
    {
        launch(args);
    }

    @Override
    public void initialize(URL arg0, ResourceBundle arg1) 
    {
        Task<Void> task = new Task<Void>()
        {
            protected Void call() throws Exception 
            {
                for (int i = 0; i <= 100; i++) 
                {
                    updateProgress(i, 100);
                    Thread.sleep(40);
                }
                //Platform.runLater(() -> primaryStage.close());
                return null;
            }
        };
        pg1.progressProperty().unbind();
        pg1.progressProperty().bind(task.progressProperty());
        
        Thread th = new Thread(task);
        th.setDaemon(true);
        th.start();
        task.setOnSucceeded(new EventHandler<WorkerStateEvent>() 
        {
            public void handle(WorkerStateEvent arg0) 
            {
                try 
                {
                        /*primaryStage.close();
                        primaryStage = null;
                        System.gc();
                        FXML_Loader f1 = new FXML_Loader();
                        f1.intermediate();*/
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
            }
            
        });
    }
    private Path createEllipsePath(double centerX, double centerY, double radiusX, double radiusY, double rotate)
    {
        ArcTo arcTo = new ArcTo();
        arcTo.setX(centerX - radiusX + 1); // to simulate a full 360 degree celcius circle.
        arcTo.setY(centerY - radiusY);
        arcTo.setSweepFlag(false);
        arcTo.setLargeArcFlag(true);
        arcTo.setRadiusX(radiusX);
        arcTo.setRadiusY(radiusY);
        arcTo.setXAxisRotation(rotate);

        Path path = new Path();
        path.getElements().addAll(
                new MoveTo(centerX - radiusX, centerY - radiusY),
                arcTo,
                new ClosePath()); // close 1 px gap.
        path.setStroke(Color.BLUE);
        path.getStrokeDashArray().setAll(5d, 5d);
        return path;
    }
}

FXML 代码:

<?xml version="1.0" encoding="UTF-8"?>

<?import com.gluonhq.charm.glisten.control.ProgressIndicator?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.effect.InnerShadow?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" style="-fx-background-color: transparent;" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.Main">
   <children>
      <VBox alignment="CENTER" layoutX="163.5" layoutY="63.5" prefHeight="290.0" prefWidth="290.0" style="-fx-background-color: #3D4956; -fx-background-radius: 150;">
         <effect>
            <InnerShadow color="#00000070" offsetX="-4.0" offsetY="-4.0">
               <input>
                  <InnerShadow color="#a7a7a7bf" offsetX="4.0" offsetY="4.0" />
               </input>
            </InnerShadow>
         </effect>
         <children>
            <VBox alignment="CENTER" prefHeight="200.0" prefWidth="100.0" style="-fx-background-color: #3D4956; -fx-background-radius: 150;" VBox.vgrow="ALWAYS">
               <VBox.margin>
                  <Insets bottom="15.0" left="15.0" right="15.0" top="15.0" />
               </VBox.margin>
               <effect>
                  <InnerShadow color="#0000008c" offsetX="4.0" offsetY="4.0">
                     <input>
                        <InnerShadow color="#a6a6a65c" offsetX="-4.0" offsetY="-4.0" />
                     </input>
                  </InnerShadow>
               </effect>
               <children>
                  <VBox alignment="CENTER" prefHeight="200.0" prefWidth="100.0" style="-fx-background-color: #3D4956; -fx-background-radius: 150;" VBox.vgrow="ALWAYS">
                     <VBox.margin>
                        <Insets bottom="15.0" left="15.0" right="15.0" top="15.0" />
                     </VBox.margin>
                     <effect>
                        <InnerShadow color="#0000008c" offsetX="-4.0" offsetY="-4.0">
                           <input>
                              <InnerShadow color="#a6a6a65c" offsetX="4.0" offsetY="4.0" />
                           </input>
                        </InnerShadow>
                     </effect>
                     <children>
                        <VBox prefHeight="200.0" prefWidth="100.0" style="-fx-background-color: #3D4956; -fx-background-radius: 150;" VBox.vgrow="ALWAYS">
                           <VBox.margin>
                              <Insets bottom="15.0" left="15.0" right="15.0" top="15.0" />
                           </VBox.margin>
                           <effect>
                              <InnerShadow color="#0000008c" offsetX="4.0" offsetY="4.0">
                                 <input>
                                    <InnerShadow color="#a6a6a65c" />
                                 </input>
                              </InnerShadow>
                           </effect>
                           <children>
                              <VBox alignment="CENTER" prefHeight="200.0" prefWidth="100.0" style="-fx-background-color: #3D4956; -fx-background-radius: 150;" VBox.vgrow="ALWAYS">
                                 <VBox.margin>
                                    <Insets bottom="15.0" left="15.0" right="15.0" top="15.0" />
                                 </VBox.margin>
                                 <effect>
                                    <InnerShadow color="#0000008c" offsetX="-4.0" offsetY="-4.0">
                                       <input>
                                          <InnerShadow color="#a6a6a65c" offsetX="4.0" offsetY="4.0" />
                                       </input>
                                    </InnerShadow>
                                 </effect>
                                 <children>
                                    <AnchorPane prefHeight="58.0" prefWidth="141.0" style="-fx-background-color: #3D4956; -fx-background-radius: 150;" VBox.vgrow="ALWAYS">
                                       <VBox.margin>
                                          <Insets bottom="15.0" left="15.0" right="15.0" top="15.0" />
                                       </VBox.margin>
                                       <effect>
                                          <InnerShadow color="#0000008c" offsetX="4.0" offsetY="4.0">
                                             <input>
                                                <InnerShadow color="#a6a6a65c" offsetX="-4.0" offsetY="-4.0" />
                                             </input>
                                          </InnerShadow>
                                       </effect>
                                       <children>
                                          <ImageView fitHeight="42.0" fitWidth="50.0" layoutX="49.0" layoutY="40.0" pickOnBounds="true" preserveRatio="true">
                                             <image>
                                                <Image url="@logo/database1.png" />
                                             </image>
                                          </ImageView>
                                          <Label layoutX="57.0" layoutY="81.0" prefHeight="19.0" prefWidth="34.0" text="SQL" textFill="YELLOW">
                                             <font>
                                                <Font name="System Bold Italic" size="14.0" />
                                             </font>
                                          </Label>
                                          <Label layoutX="38.0" layoutY="97.0" prefHeight="20.0" prefWidth="73.0" text="Developer" textFill="YELLOW">
                                             <font>
                                                <Font name="System Bold Italic" size="14.0" />
                                             </font>
                                          </Label>
                                          <ProgressIndicator fx:id="pg1" layoutX="8.0" layoutY="7.0" prefHeight="108.0" prefWidth="122.0" progress="1.0" radius="60.0" />
                                       </children>
                                    </AnchorPane>
                                 </children>
                              </VBox>
                           </children>
                        </VBox>
                     </children>
                  </VBox>
               </children>
            </VBox>
         </children>
      </VBox>
   </children>
</AnchorPane>

载入画面设计

标签: javafxjavafx-11

解决方案


推荐阅读