2014-05-20 3 views
1

내가 JavaFXLineChart에 몇 가지 기능을 추가하고 있는데 차트 Axis에서 대부분이 방법을 사용하고 있습니다 :차트 데이터가 표시되는시기를 아는 방법은 무엇입니까?

  • 축 # getDisplayPosition
  • 축 # getValueForDisplay

문제를이 방법입니다 차트에 추가 한 새 데이터가 렌더링 될 때만 올바른 값을 반환합니다. 그래서 지금이 추한 해결 방법이 있습니다

new Timer().schedule(new TimerTask() { 
      @Override 
      public void run() { 
       Platform.runLater(new Runnable() { 
        @Override 
        public void run() { 
         // Axis#getDisplayPosition and Axis#getValueForDisplay usage 
        } 
       }); 
      } 
     }, 10); 

적어도 내가이 방법을 사용할 수 있습니다 새로운 데이터가 화면에 렌더링 할 내 PC에 충분한 코드 10mS에의 실행을 지연 타이머. 차트가 렌더링 될 때를 알 수있는 다른 방법이 있습니까? 나는 LineChart에서 오버 라이딩 할 수있는 모든 메소드를 찾고 있었지만, 차트 작성이 완료되면 알 수있는 도움말을 찾을 수 없습니다. 여기

내가 말하고 무엇을 재현하는 간단한 코드 :

import javafx.application.Application; 
import javafx.collections.FXCollections; 
import javafx.collections.ObservableList; 
import javafx.event.EventHandler; 
import javafx.scene.Scene; 
import javafx.scene.chart.LineChart; 
import javafx.scene.chart.NumberAxis; 
import javafx.scene.chart.XYChart; 
import javafx.scene.input.MouseEvent; 
import javafx.scene.layout.Pane; 
import javafx.stage.Stage; 

import java.util.Random; 

public class Main extends Application { 

    @Override 
    public void start(final Stage primaryStage) throws Exception{ 

     final LineChart lineChart = new LineChart(new NumberAxis(), new NumberAxis()); 
     final XYChart.Series<Integer, Integer> series = new XYChart.Series<Integer, Integer>(); 
     ObservableList<XYChart.Series<Integer, Integer>> seriesDataSet = FXCollections.observableArrayList(); 

     lineChart.setAnimated(false); 
     lineChart.setPrefWidth(800); 
     lineChart.setPrefHeight(600); 
     seriesDataSet.add(series); 
     lineChart.setData(seriesDataSet); 

     for (int n = 0; n < 50; ++n) { 
      series.getData().add(new XYChart.Data<Integer, Integer>(n, new Random().nextInt(20))); 
     } 

     Pane pane = new Pane(); 
     pane.getChildren().add(lineChart); 

     primaryStage.setScene(new Scene(pane, 800, 600)); 
     primaryStage.show(); 

     // Get a display 
     System.out.println(lineChart.getXAxis().getDisplayPosition(2)); 
     // The value is now correct and different from the previous one 
     System.out.println(lineChart.getXAxis().getDisplayPosition(2)); 

     // Add data to the chart 
     for (int n = 51; n < 80; ++n) { 
      series.getData().add(new XYChart.Data<Integer, Integer>(n, new Random().nextInt(20))); 
     } 

     // Get a display 
     System.out.println(lineChart.getXAxis().getDisplayPosition(2)); 
     // The value is now correct and different from the previous one 
     System.out.println(lineChart.getXAxis().getDisplayPosition(2)); 

     pane.setOnMouseClicked(new EventHandler<MouseEvent>() { 
      @Override 
      public void handle(MouseEvent mouseEvent) { 
       System.out.println(lineChart.getXAxis().getDisplayPosition(2)); 
      } 
     }); 
    } 


    public static void main(String[] args) { 
     launch(args); 
    } 
} 

처음 두 숫자를, 나는 일부 데이터를 같은 추가되어 인쇄, 숫자는 여전히 그들이해야 잘못되는 동일 데이터를 추가 했으므로 이전의 것과 다를 수 있습니다. 이제 차트의 어딘가를 클릭하면 차트가 이미 렌더링되었으므로 올바른 번호를 읽을 수 있습니다.

+0

[차트에서 애니메이션 끄기] (http://docs.oracle.com/javase/8/javafx/api/javafx/scene/chart/Chart.html#setAnimated-boolean-)를 시도 했습니까? – jewelsea

+0

예, 차트에 애니메이션이 적용되지 않았습니다. – Andres

+0

[최소, 완전 검증 가능한 예제 (mcve)] (http://stackoverflow.com/help/mcve)를 제공하기 위해 질문을 편집 할 수 있습니까? – jewelsea

답변

0

이에 대한 트릭은 차트에 배입니다 :

    데이터를 수정하기 전에 animation을 해제
  1. .
  2. applyCSS.
  3. 요청 layout.

그런 다음 JavaFX 시스템은 차트 구성 요소의 모든 위치를 계산해야합니다. 그런 다음 구성 요소를 쿼리하여 현재 레이아웃 위치와 경계를 확인할 수 있습니다.

실제 렌더링을 수행하는 방법은 차트를 임시 장면에 배치하고 snapshot입니다. 그러나 실제로 다른 목적으로 렌더링 된 이미지가 필요하지 않은 경우 applyCSS/layout 조합은 일반적으로 위치 계산 용도로 모두 필요합니다.

+0

고마워요! BTW는 JavaFX 8에서만 사용할 수 있습니다. – Andres

0

자바 8에서 stage.show를 약간 움직이면 제대로 작동합니다. 더 많은 데이터를 추가하도록 업데이트되었습니다.

// Add data to the chart 
    for (int n = 0; n < 50; ++n) { 
     series.getData().add(new XYChart.Data<Integer, Integer>(n, new Random().nextInt(20))); 
    } 

    Pane pane = new Pane(); 
    pane.getChildren().add(lineChart); 

    primaryStage.setScene(new Scene(pane, 800, 600)); 
    primaryStage.show(); 

    // Get a display 
    System.out.println(lineChart.getXAxis().getDisplayPosition(2)); 
    // The value is now correct and different from the previous one 
    System.out.println(lineChart.getXAxis().getDisplayPosition(2)); 

    // Add data to the chart 
    for (int n = 51; n < 80; ++n) { 
     series.getData().add(new XYChart.Data<Integer, Integer>(n, new Random().nextInt(20))); 
    } 

    // Get a display 
    System.out.println(lineChart.getXAxis().getDisplayPosition(5)); 
    // The value is now correct and different from the previous one 
    System.out.println(lineChart.getXAxis().getDisplayPosition(5)); 

sout은 실행 한 방식대로 0 30 대신 30, 30을 표시합니다. 이제 데이터를 추가 한 후 30, 30, 74,74가 표시됩니다.

방금 ​​작업 및 runlater를 제거했습니다. GUI 쓰레드가 엉망이라고 생각합니다. 차트에 추가하는 작업은 GUI 스레드에서 수행해야하므로 리턴하고 위치를 물을 때까지 기다릴 것이라고 추측합니다.

나는 애니메이션을 켜면 아직도 올바른 금액을 얻습니다. 흥미롭게도, 애니메이션이 완료되기 전에 금액이 정확하게 인쇄됩니다.

+0

나는 이것이 데이터를 추가하고 무대를 보여줄 때만 발생한다고 생각합니다. 이 코드를 시도하십시오 : http://pastebin.com/24yrmA2E. 두 숫자를 모두 얻은 후에 더 많은 데이터를 추가합니다. 그리고 당신이 볼 수 있듯이 새로운 두 숫자는 서로 다릅니다. – Andres

+0

나는 대답을 편집했다. – brian

+0

미안하지만 틀렸어. 데이터를 추가 한 직후에 메서드를 사용하고 있지만 시간이 지나면 테스트하지 않는 경우이 코드를 참조하십시오. http://pastebin.com/H191qyWN 처음 두 숫자가 동일하면 일부 데이터를 추가합니다. , 숫자는 여전히 동일합니다. 이제 차트의 어딘가를 클릭하면 올바른 번호 – Andres

관련 문제