scenebuilder javafx linechart

我是研究僧i 提交于 2019-12-02 07:57:23

问题


So here's the deal, i'm trying to code a GUI that shows live data on a linechart. So far so good, i can get the linechart working but not into the GUI.

Using scenebuilder, i made a view with a linechart object, in order to link it to my generated chart. But for some reason this does not seem to work with this code in my mainApp.

public void showSes() {
    try {
        // Load the fxml file and set into the center of the main layout
        FXMLLoader loader = new FXMLLoader();
        loader.setLocation(MainApp.class.getResource("view/Session.fxml"));

        AnchorPane Session = (AnchorPane) loader.load();
        rootLayout.setCenter(Session);

        SessionController controller = loader.getController();
        controller.setMainApp(this);
        controller.initGraph();

    } catch (IOException e) {
        // Exception gets thrown if the fxml file could not be loaded
        e.printStackTrace();
    }
}

This simply shows the view with an empty linechart. I know the chart should know however, because i can use it to create a scene, and show that into the GUI, but the view i made in scenebuilder also has some other fields i want to show...

Does anybody have an idea?

FXML

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

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

<AnchorPane prefHeight="900.0" prefWidth="1280.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="gui.view.SessionController">
   <children>
      <Pane prefHeight="900.0" prefWidth="1280.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
         <children>
            <LineChart fx:id="linechart" layoutX="29.0" layoutY="194.0" prefHeight="416.0" prefWidth="1222.0" title="Temperature of session">
              <xAxis>
                <CategoryAxis label="Time (s)" fx:id="xAxis" />
              </xAxis>
              <yAxis>
                <NumberAxis fx:id="yAxis" label="Temperature (°C)" side="LEFT" upperBound="160.0" />
              </yAxis>
            </LineChart>
            <GridPane layoutX="254.0" layoutY="87.0" prefHeight="150.0" prefWidth="771.0">
              <columnConstraints>
                <ColumnConstraints hgrow="SOMETIMES" maxWidth="274.0" minWidth="10.0" prefWidth="274.0" />
                  <ColumnConstraints hgrow="SOMETIMES" maxWidth="273.0" minWidth="10.0" prefWidth="273.0" />
                <ColumnConstraints hgrow="SOMETIMES" maxWidth="273.0" minWidth="10.0" prefWidth="273.0" />
              </columnConstraints>
              <rowConstraints>
                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
              </rowConstraints>
               <children>
                  <Label prefHeight="53.0" prefWidth="153.0" text="Temperature fluid:" GridPane.halignment="CENTER" GridPane.valignment="TOP">
                     <font>
                        <Font size="16.0" />
                     </font>
                  </Label>
                  <Label prefHeight="52.0" prefWidth="181.0" text="Temperature vapor:" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.valignment="TOP">
                     <font>
                        <Font size="16.0" />
                     </font>
                  </Label>
                  <TextField fx:id="fluidT" editable="false" />
                  <TextField fx:id="gasT" editable="false" GridPane.columnIndex="2" />
               </children>
            </GridPane>
            <Label layoutX="474.0" layoutY="14.0" text="TempTracker">
               <font>
                  <Font size="50.0" />
               </font>
            </Label>
            <TextArea editable="false" layoutX="190.0" layoutY="638.0" prefHeight="160.0" prefWidth="900.0" promptText="&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;------Warning log------- " wrapText="true" />
            <Button layoutX="540.0" layoutY="808.0" mnemonicParsing="false" onAction="#handleStop" prefHeight="65.0" prefWidth="200.0" text="STOP">
               <font>
                  <Font size="22.0" />
               </font>
            </Button>
         </children></Pane>
   </children>
</AnchorPane>

CONTROLLER

    private static final int MAX_DATA_POINTS = 50;
    private String xSeriesData = "";
    private XYChart.Series series1;
    private XYChart.Series series2;
    private ExecutorService executor;
    private BlockingQueue<Number> dataQ1 = new ArrayBlockingQueue<Number>(1024);
    private BlockingQueue<Number> dataQ2 = new ArrayBlockingQueue<Number>(1024);

    @FXML
    private CategoryAxis xAxis = new CategoryAxis();
    @FXML
    final NumberAxis yAxis = new NumberAxis();
    @FXML
    final LineChart<String, Number> linechart = new LineChart<String, Number>(xAxis, yAxis);


public void initGraph(){
    xAxis.setAutoRanging(false);

    xAxis.setTickLabelsVisible(false);
    xAxis.setTickMarkVisible(false);

    NumberAxis yAxis = new NumberAxis();
    yAxis.setAutoRanging(true);

    //Graph
    final LineChart<String, Number> lc = new LineChart<String, Number>(xAxis, yAxis){
            @Override 
            protected void dataItemAdded(Series<String, Number> series, int itemIndex, Data<String, Number> item){}
            };
    lc.setAnimated(false);
    lc.setId("liveLineChart");
    lc.setTitle("Animated Line Chart");

    //Graph Series
    series1 = new XYChart.Series<Number, Number>();
    series2 = new XYChart.Series<Number, Number>();
    linechart.getData().addAll(series1, series2);

    series1.setName("T1");
    series2.setName("T2");

    fluidT.setText("0000");
    gasT.setText("0000");

    prepareTimeline();

    Runnable con = new Consumer(this);
    Thread c = new Thread(con);
    c.start();

}

回答1:


Don't create new objects for @FXML injected members

Never use new in conjunction with @FXML, i.e., never write:

@FXML 
private CategoryAxis xAxis = new CategoryAxis();

Instead, just write:

@FXML 
private CategoryAxis xAxis;

The FXMLLoader will automatically generate, i.e., create, a new object for each element in the FXML file and inject a reference to that into your controller where you provide an @FXML annotation. So if you reset the @FXML member reference to a new object you create in the controller there will be no association between that object and objects created by the loader.

Additionally, don't create another new LineChart within your initGraph() function. You already have a LineChart created by the FXMLLoader, just reference that. Same for NumberAxis and the other elements you are using @FXML injection with.

If you use an @FXML annotation also use <fx:id>

You have:

@FXML
private CategoryAxis xAxis;

So in your fxml, you should define:

<xAxis fx:id="xAxis">

Otherwise, the FXMLLoader will not be able to inject a reference to the axis you defined in your FXML.

Aside

You may have other errors in your code (e.g., around concurrency and threading). So the above might not be all of your errors. In general, when creating an mcve, try to eliminate anything which is not relevant to the question at hand (e.g. the threading code and non-linechart portions of the FXML), but include everything that somebody could use to copy and paste your code to compile and run it to replicate your issue.

Note: The Ensemble sample application contains a sample program which updates a graph in real-time based upon audio spectrum input data.



来源:https://stackoverflow.com/questions/29286698/scenebuilder-javafx-linechart

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!