为什么折线图没有获得新设置

Why Line Chart doesn't get new settings

我想知道为什么我的图表在设置后没有得到新的设置,也就是没有更新轴。

主要class:

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("Hello World");
        primaryStage.setScene(new Scene(root, 1200, 800));
        primaryStage.show();
    }


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

控制器class;单击“应用”按钮后,您可以设置您想要在 X 轴和 Y 轴上使用的变量,还可以使用一些验证,

package sample;

import javafx.beans.binding.Bindings;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.geometry.Side;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.control.TextField;
public class Controller {

    @FXML
    private TextField xMin, xMax, yMin, yMax, xTick, yTick, width, height;
    @FXML
    private LineChart<Number, Number> axesTest;
    @FXML
    private NumberAxis xAxis, yAxis;

    private Axes axes;

    public void applyButtonClicked(ActionEvent event) {
        System.out.println("Applyed...");
        axes = new Axes();

        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 = new NumberAxis(axes.getxMin(), axes.getxMax(), axes.getxTickUnit());
        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 = new NumberAxis(axes.getyMin(), axes.getyMax(), axes.getyTickUnit());
        yAxis.setSide(Side.LEFT);
        yAxis.setMinorTickVisible(false);
        yAxis.setPrefHeight(axes.getAxesHeight());
        yAxis.layoutXProperty().bind(Bindings.subtract((axes.getAxesWidth() / 2) + 1, yAxis.widthProperty()));

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

        axesTest = new LineChart<Number, Number>(xAxis, yAxis);

//        System.out.println("xMin : " + axes.getxMin() + "xMax : " + axes.getxMax() + "yMin :" + axes.getyMin() + "yMax : " + axes.getyMax()
//        + "xTick : " + axes.getxTickUnit() + "yTick : " + axes.getyTickUnit());
    }

    public void startButtonClicked() {

    }

}

Axes class 用于设置我想要在 Axes 上的每个变量。

package sample;

import javafx.scene.chart.NumberAxis;
import javafx.scene.layout.Pane;

public class Axes extends Pane {
    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;
    }

}

sample.fxml 文件,我在场景生成器中创建的所有内容。

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

<?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="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
   <top>
      <Label text="JavaFX Simulation" BorderPane.alignment="CENTER">
         <font>
            <Font name="Calibri" size="15.0" />
         </font>
      </Label>
   </top>
   <bottom>
      <Label text="\@Copyright by XXX" BorderPane.alignment="CENTER" />
   </bottom>
   <left>
      <VBox prefHeight="345.0" prefWidth="192.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>
              <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 minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                  <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
              </rowConstraints>
               <children>
                  <TextField promptText="xMin" fx:id="xMin" />
                  <TextField promptText="xMax" GridPane.columnIndex="1" fx:id="xMax" />
                  <TextField fx:id="yMin" promptText="yMin" GridPane.rowIndex="1" />
                  <TextField fx:id="yMax" promptText="yMax" GridPane.columnIndex="1" GridPane.rowIndex="1" />
                  <TextField fx:id="width" promptText="width" GridPane.rowIndex="3" />
                  <TextField fx:id="height" promptText="height" GridPane.columnIndex="1" GridPane.rowIndex="3" />
                  <TextField promptText="xTick" GridPane.rowIndex="2" fx:id="xTick" />
                  <TextField fx:id="yTick" promptText="yTick" GridPane.columnIndex="1" GridPane.rowIndex="2" />
                  <HBox prefHeight="100.0" prefWidth="200.0" GridPane.rowIndex="4">
                     <children>
                        <Button mnemonicParsing="false" onAction="#applyButtonClicked" text="Apply" />
                     </children>
                  </HBox>
                  <Button mnemonicParsing="false" onAction="#startButtonClicked" text="Start" GridPane.rowIndex="5" />
                  <Button mnemonicParsing="false" text="Restart" GridPane.columnIndex="1" GridPane.rowIndex="5" />
               </children>
               <padding>
                  <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
               </padding>
            </GridPane>
         </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" 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>
</BorderPane>

Border Pane 的中心应该是启动应用程序的默认轴,单击“应用”按钮后应该显示我想要的轴。它没有更新它,所以我的问题是:我做错了什么?或者我在代码中缺少什么?谢谢

您遇到的第一个问题是每次单击应用按钮时都会添加 NumberAxisLineChart 的新实例。这些实例不会添加到场景图中,而您已经拥有的实例(那些用@FXML 注释并由 FXMLLoader 创建的实例)不会收到任何通知。

所以你必须删除这个:

public void applyButtonClicked(ActionEvent event) {
    xAxis = new NumberAxis(axes.getxMin(), axes.getxMax(), axes.getxTickUnit());
    yAxis = new NumberAxis(axes.getyMin(), axes.getyMax(), axes.getyTickUnit());
    axesTest = new LineChart<Number, Number>(xAxis, yAxis);
}

然后设置:

public void applyButtonClicked(ActionEvent event) {
    //xAxis = new NumberAxis(axes.getxMin(), axes.getxMax(), axes.getxTickUnit());
    xAxis.setLowerBound(axes.getxMin());
    xAxis.setUpperBound(axes.getxMax());
    xAxis.setTickUnit(axes.getxTickUnit());

    //yAxis = new NumberAxis(axes.getyMin(), axes.getyMax(), axes.getyTickUnit());
    yAxis.setLowerBound(axes.getyMin());
    yAxis.setUpperBound(axes.getyMax());
    yAxis.setTickUnit(axes.getyTickUnit());

    //axesTest = new LineChart<Number, Number>(xAxis, yAxis);
}

第二个问题:默认情况下轴启用了自动量程,因此应用的任何更改都将被覆盖。

所以只需禁用它:

public void initialize() {
    axes = new Axes();

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

最后,您不能绑定 layoutX 属性,因为它已经绑定了。而是使用 translateX 属性:

yAxis.translateXProperty().bind(Bindings.subtract((axes.getAxesWidth() / 2) + 1, yAxis.widthProperty()));