2017-09-15 126 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 –