2017-09-15 122 views
1

我正在研究一个简单的应用程序,它具有饼图。我的目标是,如果用户将鼠标悬停在图表的任何部分上,它将展开并呈现更多信息。在我的程序中,图表由3个弧组成。这是我的代码。如何在Javafx中动画圆弧

import javafx.scene.Group; //Maybe too many imports, I just use em all 
import javafx.scene.Scene; //because I'm lazy 
import javafx.stage.Stage; 
import javafx.util.Duration; 
import javafx.scene.paint.Color; 
import javafx.scene.shape.Arc; 
import javafx.scene.shape.Rectangle; 
import javafx.event.EventHandler; 
import javafx.event.ActionEvent; 
import javafx.event.Event; 
import javafx.application.Application; 
import javafx.scene.shape.*; 
import javafx.scene.shape.Line; 
import javafx.scene.text.Text; 
import javafx.scene.text.Font; 
import javafx.scene.text.FontWeight; 
import javafx.scene.input.MouseEvent; 
import javafx.animation.ScaleTransition; 
import java.lang.Thread; 

public class AnimatingDemo extends Application{ 
    public static void main(String[] args) { 
     launch(args); 
    } 
    @Override 
    public void start(Stage stage) { 
     //create 3 arc variables 
     Arc arc1 = new Arc(); 
     Arc arc2 = new Arc(); 
     Arc arc3 = new Arc(); 
      //set up arc1 in place and to right color 
     arc1.setFill(Color.rgb(35,25,43,1.0)); 
     arc1.setCenterX(250); 
     arc1.setCenterY(250); 
     arc1.setRadiusX(100.0f); 
     arc1.setRadiusY(100.0f); 
     arc1.setStartAngle(315); 
     arc1.setLength(-90); 
     arc1.setType(ArcType.ROUND); 
     //set up and color arc2 
     arc2.setFill(Color.rgb(39,70,144,1.0)); 
     arc2.setCenterX(250); 
     arc2.setCenterY(250); 
     arc2.setRadiusX(100.0f); 
     arc2.setRadiusY(100.0f); 
     arc2.setStartAngle(90); 
     arc2.setLength(-135); 
     arc2.setType(ArcType.ROUND); 
     //set up and color arc3 
     arc3.setFill(Color.rgb(54,65,86,1.0)); 
     arc3.setCenterX(250); 
     arc3.setCenterY(250); 
     arc3.setRadiusX(100.0f); 
     arc3.setRadiusY(100.0f); 
     arc3.setStartAngle(225); 
     arc3.setLength(-135); 
     arc3.setType(ArcType.ROUND); 

     //create root group 
     Group root = new Group(); 
     //set up window 
     //add nodes to root 
     root.getChildren().addAll(arc1,arc2,arc3); 
     Scene scene = new Scene(root, 500,500); 
     stage.setTitle("Testing arc animation"); 
     stage.setScene(scene); 
     stage.show(); 
    } 
} 

这仅仅是我提出的一个例子,所以我可以重新创建问题,但它得到了重点。我在Javafx中研究了各种动画方法。动画课程似乎最可行,所以我在我的课程中尝试过。我用下面的代码:

arc1.addEventFilter(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() { 
     @Override 
     public void handle(MouseEvent mouseEvent) { 
      ScaleTransition st = new ScaleTransition(Duration.millis(1500),arc1); 
      st.setByX(0.3); 
      st.setByY(0.3); 
      st.setCycleCount(1); 
      st.setAutoReverse(false); 
      st.play(); 

     } 
    }); 

我重复了3次每个弧,但这是多余的。

无论如何,结果是圆弧的两端缩放,所以pi图看起来很乱并且不再居中,缩放比例也随圆弧的大小而增加,因此不一致。

然后我决定转移到更基本的方法,使用thread.sleep()。

arc1.addEventFilter(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() { 
     @Override 
     public void handle(MouseEvent mouseEvent) { 
      for(int a = 0; a < 10; a++) { 
       try { 
        arc1.setRadiusX(arc1.getRadiusX() + 1); 
        arc1.setRadiusY(arc1.getRadiusY() + 1); 
        Thread.sleep(100); 
       } 
       catch(InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 

     } 
    }); 

这也行不通,这个圆圈就会立刻按照我想要的(立即)的单位数量扩展。

所以我的问题是,我能做什么?有没有一种方法来防止动画类中的歪斜?我能以某种方式使thread.sleep动画流畅吗?任何建议帮助,感谢您的时间!

P.S.如果需要更多的评论让我知道

回答

0

我不知道这是你在找什么,因为你Arc的,而不是一个适当的PieChart去了,但是我用了PieChart类,做你所做的一切它工作得很好。

在这里,我拿了PieChart.Data类,并做了三个单独的测试。

我在PieChart.Data变量上通过调用.getNode()添加了一个EventFilter,然后粘贴上面提供的方法。

再一次,我认为有一个原因,你使用Arc而不是PieChart,但我得到它的工作方式。

@Override 
    public void start(Stage stage) { 
     ObservableList<PieChart.Data> data = FXCollections.observableArrayList(); 
     PieChart pieChart = new PieChart(data); 
     PieChart.Data one = new PieChart.Data("one", 50.0); 
     PieChart.Data two = new PieChart.Data("two", 33.0); 
     PieChart.Data three = new PieChart.Data("three", 17.0); 
     data.addAll(one, two, three); 
     one.getNode().addEventFilter(MouseEvent.MOUSE_PRESSED, mouseEvent -> { 
      ScaleTransition st = new ScaleTransition(Duration.millis(1500),one.getNode()); 
      st.setByX(0.3); 
      st.setByY(0.3); 
      st.setCycleCount(1); 
      st.setAutoReverse(false); 
      st.play(); 

     }); 
     two.getNode().addEventFilter(MouseEvent.MOUSE_PRESSED, mouseEvent -> { 
      ScaleTransition st = new ScaleTransition(Duration.millis(1500),two.getNode()); 
      st.setByX(0.3); 
      st.setByY(0.3); 
      st.setCycleCount(1); 
      st.setAutoReverse(false); 
      st.play(); 

     }); 
     three.getNode().addEventFilter(MouseEvent.MOUSE_PRESSED, mouseEvent -> { 
      ScaleTransition st = new ScaleTransition(Duration.millis(1500),three.getNode()); 
      st.setByX(0.3); 
      st.setByY(0.3); 
      st.setCycleCount(1); 
      st.setAutoReverse(false); 
      st.play(); 

     }); 

     //create root group 
     Group root = new Group(); 
     //set up window 
     //add nodes to root 
     root.getChildren().addAll(pieChart); 
     Scene scene = new Scene(root, 500,500); 
     stage.setTitle("Testing arc animation"); 
     stage.setScene(scene); 
     stage.show(); 
    } 
+0

这看起来很有希望!我知道一个piechart类已经存在了,所以我自己使用了弧线。然而,我要为平面UI设计,所以我需要能够自定义图表。感谢您的帮助,我想提高您的答案,但我的声誉还不够高 –

+0

您可以使用CSS使其看起来像您喜欢的样子。 –

+0

没问题。另外请注意,JavaFX不使用完整的CSS命令套件,所以我建议查看JavaFX特定的CSS。 https://docs.oracle.com/javase/8/javafx/api/javafx/scene/doc-files/cssref.html –