2016-07-11 12 views
0

Ich habe einen Fehler mit der Aktualisierung von Daten auf LineChart bekommen. Nach dem Aktualisieren von LineChart x Werte nicht gut aktualisiert. Sieht so aus, als ob neue Werte aus der Funktion "gemischt" sind. Nach der Implementierung von Wave packetJavaFX Liniendiagramm wird nicht gut aktualisiert. Datenprobleme

Mit dispersive und ohne es, sollte auf der aktuellen Animation aus Wikipedia rechten Seite der Seite für beide Fälle aussehen. Ich versuche dieses Problem zu finden, was falsch ist, aber ehrlich gesagt kann ich das nicht sehen. Zählen von Daten ist ziemlich sicher in 100% gut. Ich rötete mich irgendwo über diese Art von Problemen, konnte aber mein Problem nicht lösen.

Hauptklasse:

package sample; 

import javafx.application.Application; 
import javafx.fxml.FXMLLoader; 
import javafx.scene.Parent; 
import javafx.scene.Scene; 
import javafx.stage.Stage; 

public class Main extends Application { 

    @Override 
    public void start(Stage primaryStage) throws Exception{ 
     Parent root = FXMLLoader.load(getClass().getResource("sample.fxml")); 
     primaryStage.setTitle("Animation 1D"); 
     primaryStage.setScene(new Scene(root, 1200, 800)); 
     primaryStage.show(); 
    } 

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

Achsen Klasse:

package sample; 

import javafx.scene.chart.NumberAxis; 

public class Axes { 
    private NumberAxis xAxis; 
    private NumberAxis yAxis; 
    private double xMin, xMax, yMin, yMax, xTickUnit, yTickUnit; 
    private int axesWidth, axesHeight; 

    public Axes() { 
     this.xMin = 0; 
     this.xMax = 0; 
     this.yMin = 0; 
     this.yMax = 0; 
     this.xTickUnit = 0; 
     this.yTickUnit = 0; 
     this.axesWidth = 0; 
     this.axesHeight = 0; 
    } 

    public NumberAxis getXAxis() { 
     return xAxis; 
    } 

    public NumberAxis getYAxis() { 
     return yAxis; 
    } 

    public int getAxesWidth() { 
     return axesWidth; 
    } 

    public void setAxesWidth(int axesWidth) { 
     this.axesWidth = axesWidth; 
    } 

    public int getAxesHeight() { 
     return axesHeight; 
    } 

    public void setAxesHeight(int axesHeight) { 
     this.axesHeight = axesHeight; 
    } 

    public double getxMin() { 
     return xMin; 
    } 

    public void setxMin(double xMin) { 
     this.xMin = xMin; 
    } 

    public double getxMax() { 
     return xMax; 
    } 

    public void setxMax(double xMax) { 
     this.xMax = xMax; 
    } 

    public double getyMin() { 
     return yMin; 
    } 

    public void setyMin(double yMin) { 
     this.yMin = yMin; 
    } 

    public double getyMax() { 
     return yMax; 
    } 

    public void setyMax(double yMax) { 
     this.yMax = yMax; 
    } 

    public double getxTickUnit() { 
     return xTickUnit; 
    } 

    public void setxTickUnit(double xTickUnit) { 
     this.xTickUnit = xTickUnit; 
    } 

    public double getyTickUnit() { 
     return yTickUnit; 
    } 

    public void setyTickUnit(double yTickUnit) { 
     this.yTickUnit = yTickUnit; 
    } 

} 

Controller-Klasse:

package sample; 

import javafx.animation.Timeline; 
import javafx.event.ActionEvent; 
import javafx.fxml.FXML; 
import javafx.fxml.FXMLLoader; 
import javafx.geometry.Side; 
import javafx.scene.Node; 
import javafx.scene.Parent; 
import javafx.scene.Scene; 
import javafx.scene.SceneAntialiasing; 
import javafx.scene.chart.LineChart; 
import javafx.scene.chart.NumberAxis; 
import javafx.scene.control.ComboBox; 
import javafx.scene.chart.XYChart; 
import javafx.scene.chart.XYChart.Series; 
import javafx.scene.control.Label; 
import javafx.scene.control.TextField; 
import javafx.stage.Stage; 
import sample.packet3D.Window3DController; 

import java.io.IOException; 


public class Controller { 

    @FXML 
    private TextField xMin, xMax, yMin, yMax, xTick, yTick, width, height; 
    @FXML 
    private NumberAxis xAxis, yAxis; 
    @FXML 
    private ComboBox<String> comboBox; 
    @FXML 
    private LineChart<Double, Double> axesTest; 
    @FXML 
    private Label timeLabel; 

    private GaussianWave gaussianWave; 
    private GaussianWaveDispersive gaussianWaveDispersive; 


    private Axes axes; 

    private Series<Double, Double> series; 

    private Timeline timeLine; 
    @FXML 
    public void initialize() 
    { 
     System.out.println("Initialising..."); 
     axes = new Axes(); 

     yAxis.setAutoRanging(false); 
     xAxis.setAutoRanging(false); 

     xMin.setText("-30"); 
     xMax.setText("30"); 

     axesTest.setCreateSymbols(false); 

     comboBox.getItems().addAll("Gaussian Wave : non-Dispersive", "Gaussian Wave : Dispersive"); 
     //comboBox.getItems().addAll("Gaussian Wave : non-Dispersive"); 
     series = new XYChart.Series<Double, Double>(); 

     timeLine = new Timeline(); 

     applyButtonClicked(null); 
    } 

    public void applyButtonClicked(ActionEvent event) 
    { 
     System.out.println("Applying new parameters..."); 

     axes.setxMin(Double.parseDouble(xMin.getText())); 
     axes.setxMax(Double.parseDouble(xMax.getText())); 
     axes.setyMin(Double.parseDouble(yMin.getText())); 
     axes.setyMax(Double.parseDouble(yMax.getText())); 
     axes.setxTickUnit(Double.parseDouble(xTick.getText())); 
     axes.setyTickUnit(Double.parseDouble(yTick.getText())); 
     axes.setAxesWidth(Integer.parseInt(width.getText())); 
     axes.setAxesHeight(Integer.parseInt(height.getText())); 

     xAxis.setSide(Side.BOTTOM); 
     xAxis.setMinorTickVisible(false); 
     xAxis.setPrefWidth(axes.getAxesWidth()); 
     xAxis.setLayoutY(axes.getAxesHeight()/2); 
     xAxis.autosize(); 

     xAxis.setLowerBound(axes.getxMin()); 
     xAxis.setUpperBound(axes.getxMax()); 
     xAxis.setTickUnit(axes.getxTickUnit()); 

     yAxis.setSide(Side.LEFT); 
     yAxis.setMinorTickVisible(false); 
     yAxis.setPrefHeight(axes.getAxesHeight()); 

     yAxis.setLowerBound(axes.getyMin()); 
     yAxis.setUpperBound(axes.getyMax()); 
     yAxis.setTickUnit(axes.getyTickUnit()); 


    } 
    @FXML 
    public void startButtonClicked(ActionEvent event) 
    { 
     if (comboBox.getValue() == null) 
     { 
      System.out.print("Nie wybrano opcji."); 
     } 
     else 
     { 
      if(comboBox.getValue().equals("Gaussian Wave : non-Dispersive")) 
      { 
       System.out.println("Gaussian Wave : non-Dispersive"); 
       axesTest.setTitle("Gaussian Wave : non-Dispersive"); 

       if (series != null) 
       { 
        series = new XYChart.Series<Double, Double>(); 
       } 
       timeLine = new Timeline(); 
       gaussianWave = new GaussianWave(series, axes, timeLine); 
       series = gaussianWave.draw(); 
       System.out.println("Rozmiar series: "+series.getData().size()); 
       gaussianWave.update(axesTest); 


       axesTest.getData().add(series); 
      } 
      else if(comboBox.getValue().equals("Gaussian Wave : Dispersive")) 
      { 
       System.out.println("Gaussian Wave : Dispersive"); 
       axesTest.setTitle("Gaussian Wave : Dispersive"); 

       if (series != null) 
       { 
        series = new XYChart.Series<Double, Double>(); 
       } 
       timeLine = new Timeline(); 
       gaussianWaveDispersive = new GaussianWaveDispersive(series, axes, timeLine); 
       series = gaussianWaveDispersive.draw(); 
       System.out.println("Rozmiar series: "+series.getData().size()); 
       gaussianWaveDispersive.update(axesTest); 

       axesTest.getData().add(series); 
    //   axesTest.setTitle("Gaussian Wave : Dispersive"); 
    //   gaussianWaveDispersive = new GaussianWaveDispersive(series, axes); 
    //   series = gaussianWaveDispersive.draw(); 
    // 
    //   gaussianWaveDispersive.update(axesTest); 
    // 
    //   axesTest.getData().add(series); 
      } 
     } 
    } 
    @FXML 
    public void restartButtonClicked() { 
     System.out.println("Restarting..."); 
     timeLine.getKeyFrames().clear(); 
     axesTest.getData().clear(); 
    } 

    @FXML 
    public void stopButtonClicked() { 
     System.out.println("Stopping..."); 

     System.out.println("Restarting..."); 
     timeLine.getKeyFrames().clear(); 
     axesTest.getData().clear(); 
     timeLine.stop(); 
    } 

    @FXML 
    public void moveTo3DScene(ActionEvent event) throws IOException { 
     Stage stage3D = (Stage) ((Node) event.getSource()).getScene().getWindow(); 
     FXMLLoader loader = new FXMLLoader(getClass().getResource("packet3D/Window3DSceneView.fxml")); 
     Parent root = loader.load(); 
     Window3DController controller = loader.getController(); 
     stage3D.setTitle("Animation 3D"); 
     Scene scene = new Scene(root, 1200, 800, false, SceneAntialiasing.BALANCED); 
     scene.setOnKeyPressed(e -> controller.onKeyPressed(e)); 
     stage3D.setScene(scene); 
     stage3D.show(); 
    } 

    @FXML 
    public void comboBoxAction() { 

    } 


} 

Interfaceklasse:

package sample; 


import javafx.scene.chart.LineChart; 
import javafx.scene.chart.XYChart; 

public interface Countable { 
    public abstract void methodCounting(); 
    @SuppressWarnings("rawtypes") 
    public abstract XYChart.Series draw(); 
    public abstract void update(LineChart<Double, Double> lineChart); 
} 

FXML Klasse über Scene Builder generiert:

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

<?import java.lang.*?> 
<?import javafx.scene.chart.*?> 
<?import javafx.geometry.*?> 
<?import javafx.scene.text.*?> 
<?import javafx.scene.control.*?> 
<?import javafx.scene.layout.*?> 

<BorderPane fx:id="borderPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="650.0" prefWidth="1025.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller"> 
    <left> 
     <VBox prefHeight="574.0" prefWidth="270.0" spacing="10.0" BorderPane.alignment="CENTER"> 
      <children> 
       <GridPane hgap="10.0" vgap="10.0"> 
        <columnConstraints> 
        <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> 
         <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> 
        <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> 
         <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> 
        </columnConstraints> 
        <rowConstraints> 
         <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> 
         <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> 
         <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> 
         <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> 
        </rowConstraints> 
        <children> 
         <TextField promptText="xMin" text="-1" GridPane.columnIndex="1" fx:id="xMin" /> 
         <TextField promptText="xMax" text="1" GridPane.columnIndex="3" fx:id="xMax" /> 
         <TextField fx:id="yMin" promptText="yMin" text="-1" GridPane.columnIndex="1" GridPane.rowIndex="1" /> 
         <TextField fx:id="yMax" promptText="yMax" text="1" GridPane.columnIndex="3" GridPane.rowIndex="1" /> 
         <TextField fx:id="width" promptText="width" text="1" GridPane.columnIndex="1" GridPane.rowIndex="3" /> 
         <TextField fx:id="height" promptText="height" text="1" GridPane.columnIndex="3" GridPane.rowIndex="3" /> 
         <TextField promptText="xTick" text="0.1" GridPane.columnIndex="1" GridPane.rowIndex="2" fx:id="xTick" /> 
         <TextField fx:id="yTick" promptText="yTick" text="0.1" GridPane.columnIndex="3" GridPane.rowIndex="2" /> 
        <Label text="xMin" /> 
        <Label text="yMin" GridPane.rowIndex="1" /> 
        <Label text="xTick" GridPane.rowIndex="2" /> 
        <Label text="Width" GridPane.rowIndex="3" /> 
        <Label text="Height" GridPane.columnIndex="2" GridPane.rowIndex="3" /> 
        <Label text="yTick" GridPane.columnIndex="2" GridPane.rowIndex="2" /> 
        <Label text="yMax" GridPane.columnIndex="2" GridPane.rowIndex="1" /> 
        <Label text="xMax" GridPane.columnIndex="2" /> 
        </children> 
        <padding> 
         <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> 
        </padding> 
       </GridPane> 
        <Button mnemonicParsing="false" onAction="#applyButtonClicked" prefHeight="25.0" prefWidth="200.0" text="Zatwierdź"> 
       <VBox.margin> 
        <Insets left="25.0" right="25.0" /> 
       </VBox.margin> 
      </Button> 
       <VBox> 
        <children> 
         <ComboBox fx:id="comboBox" onAction="#comboBoxAction" prefHeight="25.0" prefWidth="200.0"> 
          <VBox.margin> 
           <Insets bottom="10.0" left="25.0" right="25.0" top="10.0" /> 
          </VBox.margin> 
         </ComboBox> 
         <HBox spacing="10.0"> 
          <children> 
           <Button fx:id="startButton" mnemonicParsing="false" onAction="#startButtonClicked" prefHeight="25.0" prefWidth="100.0" text="Rozpotrznij"> 
            <HBox.margin> 
             <Insets /> 
            </HBox.margin> 
           </Button> 
           <Button fx:id="restartButton" mnemonicParsing="false" onAction="#restartButtonClicked" prefHeight="25.0" prefWidth="100.0" text="Zatrzymaj" /> 
          </children> 
          <VBox.margin> 
           <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> 
          </VBox.margin> 
          <padding> 
           <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> 
          </padding> 
         </HBox> 
        <HBox> 
        <children> 
         <Button mnemonicParsing="false" onAction="#stopButtonClicked" prefHeight="25.0" prefWidth="200.0" text="Stop"> 
          <HBox.margin> 
           <Insets left="25.0" right="25.0" /> 
          </HBox.margin></Button> 
        </children> 
        </HBox> 
        </children> 
       </VBox> 
      <Button mnemonicParsing="false" onAction="#moveTo3DScene" prefHeight="25.0" prefWidth="200.0" text="Fala w przestrzeni 3D"> 
       <VBox.margin> 
        <Insets bottom="10.0" left="25.0" right="25.0" top="10.0" /> 
       </VBox.margin></Button> 
      <HBox prefHeight="100.0" prefWidth="200.0" /> 
      </children> 
      <BorderPane.margin> 
       <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> 
      </BorderPane.margin> 
      <padding> 
       <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> 
      </padding> 
     </VBox> 
    </left> 
    <center> 
     <LineChart fx:id="axesTest" prefHeight="500.0" prefWidth="500.0" stylesheets="@style.css" BorderPane.alignment="CENTER"> 
      <xAxis> 
       <NumberAxis lowerBound="-10.0" side="BOTTOM" fx:id="xAxis" /> 
      </xAxis> 
      <yAxis> 
       <NumberAxis fx:id="yAxis" lowerBound="-10.0" side="LEFT" /> 
      </yAxis> 
     </LineChart> 
    </center> 
    <top> 
     <ToolBar prefHeight="33.0" prefWidth="1025.0" BorderPane.alignment="CENTER"> 
     <items> 
      <Label alignment="CENTER" text="JavaFX Simulation" textAlignment="CENTER"> 
       <opaqueInsets> 
        <Insets /> 
       </opaqueInsets> 
      </Label> 
      <Region prefHeight="29.0" prefWidth="738.0" /> 
      <Label fx:id="timeLabel" text="Time : " /> 
     </items> 
     </ToolBar> 
    </top> 
</BorderPane> 

2 Logik Klassen zählen Wellen:

package sample; 

import javafx.animation.KeyFrame; 
import javafx.animation.Timeline; 
import javafx.scene.chart.LineChart; 
import javafx.scene.chart.XYChart; 
import javafx.scene.chart.XYChart.Series; 
import javafx.util.Duration; 

import java.util.function.Function; 


public class GaussianWave implements Countable{ 



    private Function<Double, Double> gaussFunction; 
    private XYChart.Series<Double, Double> series; 
    private Axes axes; 
    private Timeline timeline; 

    private double x; 
    private double y; 
    private double xInc; 
    private double time; 

    public GaussianWave(XYChart.Series<Double, Double> series, Axes axes, Timeline timeLine) { 
     this.axes = axes; 
     //this.series = new XYChart.Series<Number, Number>(); 
     this.series = series; 
     this.timeline = timeLine; 
     x = axes.getxMin(); 
     xInc = axes.getxTickUnit(); 
    } 


    @Override 
    public void methodCounting() { 
     double lambda = 1; 
      this.gaussFunction = x -> Math.sqrt(Math.pow(Math.exp(-(Math.pow((x - this.time), 2))) 
        * (Math.cos((2 * Math.PI * (x - this.time))/lambda)), 2) 
        + Math.pow(Math.exp(-(Math.pow((x - this.time), 2))) 
        * (Math.sin((2 * Math.PI * (x - this.time))/lambda)), 2)); 
    } 

    @Override 
    public Series<Double, Double> draw() { 
     methodCounting(); 
     while(x < axes.getxMax()) { 
      y = gaussFunction.apply(x); 
      series.getData().add(new XYChart.Data<Double, Double>(x , y)); 
      x += xInc; 
     } 
     return series; 
    } 

    @Override 
    public void update(LineChart<Double, Double> lineChart) { 
     System.out.println("Updating"); 
     this.timeline.getKeyFrames().add(
       new KeyFrame(Duration.millis(100), e -> { 
        for (XYChart.Series<Double, Double> series1 : lineChart.getData()) { 
         for (XYChart.Data<Double, Double> data : series1.getData()) { 
          Number y = gaussFunction.apply((double)data.getXValue()); 
          data.setYValue((Double) y); 
          increaseTime(); 
         } 
        } 
       }) 
     ); 
     timeline.setCycleCount(1000); 
     timeline.setAutoReverse(true); 
     timeline.play(); 
    } 


    public Function<Double, Double> getGaussFunction() { 
     return gaussFunction; 
    } 

    public void setGaussFunction(Function<Double, Double> gaussFunction) { 
     this.gaussFunction = gaussFunction; 
    } 

    public double getTime() { 
     return time; 
    } 

    public void setTime(double time) { 
     this.time = time; 
    } 

    public void increaseTime(){ 
     this.time += 0.001; 
    } 
    public double getY() { 
     return y; 
    } 

    public void setY(double y) { 
     this.y = y; 
    } 
} 

package sample; 

import javafx.animation.KeyFrame; 
import javafx.animation.Timeline; 
import javafx.scene.chart.LineChart; 
import javafx.scene.chart.XYChart; 
import javafx.scene.chart.XYChart.Series; 
import javafx.util.Duration; 

import java.util.function.Function; 


public class GaussianWaveDispersive implements Countable{ 



    private Function<Double, Double> gaussFunction; 
    private Series<Double, Double> series; 
    private Axes axes; 
    private Timeline timeline; 

    private double x; 
    private double y; 
    private double xInc; 
    private double time; 


    public GaussianWaveDispersive(XYChart.Series<Double, Double> series, Axes axes, Timeline timeLine) { 
     this.axes = axes; 
     //this.series = new XYChart.Series<Number, Number>(); 
     this.series = series; 
     this.timeline = timeLine; 
     x = axes.getxMin(); 
     xInc = axes.getxTickUnit(); 
    } 


    @Override 
    public void methodCounting() { 
     double lambda = 1; 
     double k = (2 * Math.PI)/lambda; 
      this.gaussFunction = x -> x = Math.sqrt(Math.pow(1/(Math.pow((1 + Math.pow(4 * time, 2)), (1/4))) 
        * Math.exp(-((1/Math.pow(1 + (4 * time), 2)) * Math.pow(x - (k * time), 2))) 
        * Math.cos((1/2) * Math.atan(-(2 * time)) + 1/Math.pow(1 + (4 * time), 2) 
        * ((k + (2 * time * x)) * x - Math.pow(1/2 * time * k, 2))), 2) 
        + Math.pow(1/(Math.pow((1 + Math.pow(4 * time, 2)), (1/4))) 
        * Math.exp(-((1/Math.pow(1 + (4 * time), 2)) * Math.pow(x - (k * time), 2))) 
        * Math.sin((1/2) * Math.atan(-(2 * time)) + 1/Math.pow(1 + (4 * time), 2) 
        * ((k + (2 * time * x)) * x - Math.pow(1/2 * time * k, 2))), 2)); 
    } 

    @Override 
    public XYChart.Series<Double, Double> draw() { 
     methodCounting(); 
     double count = 0; 
     while(x < axes.getxMax()) { 
      y = gaussFunction.apply(x); 
      series.getData().add(new XYChart.Data<Double, Double>(x , y)); 
      x += xInc; 
      count ++; 
      System.out.println("Ilosc : " + count + "x : " +x); 
     } 
     return series; 
    } 

    @Override 
    public void update(LineChart<Double, Double> lineChart) { 
     System.out.println("Updating"); 
     this.timeline.getKeyFrames().add(
       new KeyFrame(Duration.millis(100), e -> { 
        for (XYChart.Series<Double, Double> series1 : lineChart.getData()) { 
         for (XYChart.Data<Double, Double> data : series1.getData()) { 
          Number y = gaussFunction.apply((double)data.getXValue()); 
          data.setYValue((Double) y); 
          increaseTime(); 
         } 
        } 
       }) 
     ); 
     timeline.setCycleCount(1000); 
     timeline.setAutoReverse(true); 
     timeline.play(); 
    } 


    public Function<Double, Double> getGaussFunction() { 
     return gaussFunction; 
    } 

    public void setGaussFunction(Function<Double, Double> gaussFunction) { 
     this.gaussFunction = gaussFunction; 
    } 

    public double getTime() { 
     return time; 
    } 

    public void setTime(double time) { 
     this.time = time; 
    } 

    public void increaseTime(){ 
     this.time += 0.001; 
    } 
    public double getY() { 
     return y; 
    } 

    public void setY(double y) { 
     this.y = y; 
    } 
} 

Für extrimly hoch für diese Art von equantion x Werte, die wir dort beobachten können, ist hugh Chaos mit Daten, sollten geht reibungslos wie bei Wikipedia Sample, aber es nicht. Kann mir jemand sagen, wo das Problem ist? Es ist auch sehr schlaff während der Verwendung kleiner x/y Tick und größer x und y Achsen. Was dafür? Vielen Dank im Voraus.

P.S.

SS zeigt, wie es nach einiger Aktualisierung des Liniendiagramms aussieht.

Antwort

0

Um dieses Problem zu beheben, gehen Sie zu den Einstellungen scrollen Sie nach unten zu den Apps Zeile auswählen deaktivieren mobile Daten offene Linie etwas kommt zu sagen, Mobile Data ist ausgeschaltet wählen Sie OK, dann schließen Sie Linie zurück zu den Einstellungen scrollen Sie nach unten zu den Apps wählen Linie dann schalten Sie die mobilen Daten wieder ein und schließen Sie die Einstellungen und öffnen Sie die Zeile