LineChartでデータを更新するとバグが発生します。 LineChartの更新後、x
の値はうまく更新されません。関数からの新しい値のように見える "混合"です。 Wave packetJavaFX折れ線グラフはうまく更新されません。データの問題
分散型ではなく、それがないと、どちらの場合もページの右側のウィキペディアの現在のアニメーションのようになります。何が間違っているこの問題をキャッチしようとしているが、正直なところ私はそれを見ることができません。データを数えることは100%良いことを確認しています。私はこの種の問題についてどこかに赤いが、私の問題を解決することはできなかった。
メインクラス:
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);
}
}
軸クラス:
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;
}
}
コントローラクラス:
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() {
}
}
インタフェースクラス:
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クラス:波をカウント
<?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ロジック・クラス:私たちはデータとヒュー混乱があると観察することができequantion x
値のこの種のextrimly高については
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;
}
}
、必要がありますウィキペディアのサンプルのようにスムーズに進んでいますが、そうはしません。誰かが問題がどこにあるか教えてもらえますか?小さなx/y
ダニと大きなx
とy
軸を使用しながらも、それは本当にラグです。それはどういう意味ですか? ありがとうございます。
SSは、線グラフを更新した後にどのように見えるかを示しています。この問題に近いラインが設定に移動解決するには