Reputation: 1446
I would like to know why My chart doesn't get new settings after my set ups, is not update the axis.
Main 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);
}
}
Controller class ; after Apply button click u can set the variables which u want have on Axis X and Y, also using some validations,
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 Is for setting every variable which i want to have on my 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 file, every thing i created in the scene builder.
<?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>
At the center of the Border Pane should be for the start application default Axis and after clicking the Apply button should showed the Axis which I want to. It doesn't update it, so my question is : What I am doing wrong ? Or what I am missing in the code ? Thanks.
Upvotes: 2
Views: 449
Reputation: 45456
The first problem you have is that you are adding new instances of NumberAxis
and LineChart
every time you click on the apply button. Those instances are not added to the scene graph, and the one you already have (those annotated with @FXML and created by the FXMLLoader
), don't get any notifications.
So you have to remove this:
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);
}
and just set:
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);
}
The second problem: by default the axes have auto ranging enabled, so any change applied will be overridden.
So just disable it:
public void initialize() {
axes = new Axes();
xAxis.setAutoRanging(false);
yAxis.setAutoRanging(false);
}
And finally, you can't bind the layoutX property, since it's already bound. Instead use the translateX property:
yAxis.translateXProperty().bind(Bindings.subtract((axes.getAxesWidth() / 2) + 1, yAxis.widthProperty()));
Upvotes: 3