【问题标题】:How to set Axis range in Java FX using SampleController?如何使用示例控制器在 Javafx 中设置轴范围?
【发布时间】:2015-03-24 08:39:49
【问题描述】:

我使用scene builder v2.0 创建了一个fxml 布局。我正在修改控制器文件中的图表,即 SampleController.java 文件。我能够使用 .setTitle 方法设置图表标题。我需要动态设置 xAxis (Start, End, Ticks) 和 yAxis 的范围。在 CSS 中,使用 lowerBound 和 upperBound 属性很容易设置。但这是一个永久的解决方案。请提供您宝贵的建议和解决方案。

Main.java:

package application;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.SplitPane;
import javafx.stage.Stage;
public class Main extends Application{
    @Override
    public void start(Stage primaryStage) { 
        try {
            SplitPane root = (SplitPane)FXMLLoader.load(getClass().getResource("Sample.fxml"));
            Scene scene = new Scene(root,800,400);          
            scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
            primaryStage.setScene(scene);
            primaryStage.show();            
        } catch(Exception e) {
            e.printStackTrace();
        }
    }   
    public static void main(String[] args) {
        launch(args);



    }
}

Sample.fxml

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

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

<SplitPane dividerPositions="0.7892976588628763" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="400.0" minWidth="800.0" prefHeight="400.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.SampleController">
  <items>
    <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
         <children>
            <LineChart fx:id="Ch" alternativeColumnFillVisible="true" layoutX="14.0" prefHeight="398.0" prefWidth="500.0">
              <xAxis>
                <NumberAxis side="BOTTOM" />
              </xAxis>
              <yAxis>
                <NumberAxis layoutX="10.0" side="LEFT" />
              </yAxis>
            </LineChart>
         </children></AnchorPane>
    <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
         <children>
            <Button fx:id="sine" layoutX="21.0" layoutY="101.0" mnemonicParsing="false" text="Sinusoidal" />
            <Button fx:id="triangle" layoutX="21.0" layoutY="148.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="70.0" text="Triangle" />
            <Button fx:id="square" layoutX="21.0" layoutY="187.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="70.0" text="Square" />
            <Label layoutX="20.0" layoutY="40.0" prefHeight="17.0" prefWidth="83.0" text="Controls" />
         </children></AnchorPane>
  </items>
</SplitPane>

SampleController.java

package application;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.chart.Axis;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.chart.XYChart.Series;
import javafx.scene.control.Button;
import javafx.util.Duration;


public class SampleController implements Initializable {

     final NumberAxis xAxis = new NumberAxis(0,24,3);

     final NumberAxis yAxis = new NumberAxis(0,1,0.1);

    @FXML //  fx:id="Ch"
    private LineChart<Number, Number> Ch= new LineChart<>(xAxis, yAxis); // No use of using a constructor.
    @FXML//  fx:id="sine"
    private Button sine; // Value injected by FXMLLoader
    @FXML//  fx:id="triangle"
    private Button triangle; // Value injected by FXMLLoader
    @FXML//  fx:id="Square"
    private Button square; // Value injected by FXMLLoader




    @Override // This method is called by the FXMLLoader when initialization is complete
    public void initialize(URL fxmlFileLocation, ResourceBundle resources) {
        assert Ch != null : "fx:id=\"Ch\" was not injected: check your FXML file 'sample.fxml'.";

        // initialize your logic here: all @FXML variables will have been injected
        sine.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                System.out.println("Sinusoidal Signal Selected /n/n");
            }
        });

        triangle.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                System.out.println("Triangle Signal Selected /n/n");
            }
        });

        square.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                System.out.println("Square Signal Selected /n/n");
            }
        });



        //Ch = new LineChart<>(xAxis, yAxis); // This sadly loads a new chart but is not visible

        Ch.setTitle("PiScope Demo");

        //Need to set xAxis range Dynamically

        //Need to set yAxis range Dynamically

        /*
         * In CSS we can use lowerBound and upperBound Property.
         *          */     

    }
}

【问题讨论】:

  • 你试过getXAxis 并调用 set tickUnit 和 bounds 方法吗?请注意,您可能必须将其转换为 ValueAxis。我也不知道你为什么要在控制器文件中重新创建轴和图表。
  • @brian 无法使用 getXAxis 方法设置 Axis。我正在做一个电子项目,需要动态更改轴以在正确的位置获得电压或频率。
  • 好吧,我认为 james_d 有适合您的方法,但我的建议是没有 fx:id 作为轴,您仍然可以从图表中获得对轴的引用。获得参考后,您可以设置范围和刻度单位。

标签: java javafx javafx-2


【解决方案1】:

将轴注入控制器:

        <LineChart fx:id="Ch" alternativeColumnFillVisible="true" layoutX="14.0" prefHeight="398.0" prefWidth="500.0">
          <xAxis>
            <NumberAxis side="BOTTOM" fx:id="xAxis" />
          </xAxis>
          <yAxis>
            <NumberAxis layoutX="10.0" side="LEFT" fx:id="yAxis" />
          </yAxis>
        </LineChart>

public class SampleController implements Initializable {

    @FXML
    private NumberAxis xAxis ;

    @FXML
    private NumberAxis yAxis ;

    // never initialize fields that are injected by @FXML:
    // they are initialized by the FXMLLoader
    @FXML //  fx:id="Ch"
    private LineChart<Number, Number> Ch ;

    // ...
}

然后你可以在initialize()方法中设置范围:

public void initialize() {

    // ...

    xAxis.setAutoRanging(false);
    xAxis.setLowerBound(0);
    xAxis.setUpperBound(24);
    xAxis.setTickUnit(3);

    yAxis.setAutoRanging(false);
    yAxis.setLowerBound(0);
    yAxis.setUpperBound(1);
    yAxis.setTickUnit(0.1);

    // ...
}

【讨论】:

  • 非常感谢。我将尽快对上述答案进行投票(需要声誉)。它就像一个魅力。
  • 我必须在每个轴上 setAutoRanging(false) 才能使其工作。
  • @NonlinearFruit 谢谢:将其添加到答案中。
【解决方案2】:

有几种与 javafx 图表相关的“轴”。我发现 fxml 中的 LineChart 初始化导致了 Axis。 Axis 类没有 设置下限和上限的方法。所以我通过显式转换为 NumberAxis 找到了一个解决方案,确实有这些设置方法。

public void setAxisBounds(LineChart<Number, Number> myChart, double min, double max, boolean isXAxis) {
    NumberAxis axis;
    if (isXAxis)
        axis=(NumberAxis) myChart.getXAxis();
    else
        axis=(NumberAxis) myChart.getYAxis();
    axis.setAutoRanging(false);
    axis.setLowerBound(min);
    axis.setUpperBound(max);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-23
    • 2011-02-20
    • 2019-09-06
    • 1970-01-01
    • 2012-03-03
    相关资源
    最近更新 更多