2015-03-26 2 views
1

Итак, вот сделка, я пытаюсь закодировать графический интерфейс, который отображает данные в реальном времени на линейной диаграмме. Пока все хорошо, я могу заставить линейку работать, но не в графический интерфейс.scenebuilder javafx linechart

Используя сцену-конструктор, я сделал вид с помощью объекта линейной строки, чтобы связать его с моей сгенерированной диаграммой. Но по какой-то причине это не похоже на работу с этим кодом в моем 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(); 
    } 
} 

Это просто показывает вид с пустой линией. Я знаю, что диаграмма должна знать, потому что я могу использовать ее для создания сцены и показать ее в графическом интерфейсе, но в представлении, которое я сделал в сценарии, также есть некоторые другие поля, которые я хочу показать ...

У кого-нибудь есть идея?

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(); 

} 
+0

Ошибка в коде/fxml, который вы не видите. Предоставьте [mcve] (http://stackoverflow.com/help/mcve). – jewelsea

+0

Я немного обновил его, я думаю, что у меня есть весь соответствующий код. – Wouter

ответ

2

Не создавать новые объекты для @FXML инъекционных членов

Никогда не используйте new в сочетании с @FXML, т.е. никогда не пишут:

@FXML 
private CategoryAxis xAxis = new CategoryAxis(); 

Вместо этого, просто написать:

@FXML 
private CategoryAxis xAxis; 

FXMLLoader будет автоматически генерировать, т.е., создать новый объект для каждого элемента в файле FXML и ввести ссылку на это в свой контроллер, где вы предоставляете @FXML аннотаций. Поэтому, если вы сбросите ссылку на элемент @FXML на новый объект, созданный в контроллере, не будет никакой связи между этим объектом и объектами, созданными загрузчиком.

Кроме того, не создавайте еще один новый LineChart в вашей функции initGraph(). У вас уже есть LineChart, созданный FXMLLoader, просто ссылайтесь на него. То же самое для NumberAxis и других элементов, с которыми вы используете инъекцию @FXML.

Если вы используете @FXML аннотаций также использовать <fx:id>

У вас есть:

@FXML 
private CategoryAxis xAxis; 

Так что в вашем FXML, вы должны определить:

<xAxis fx:id="xAxis"> 

В противном случае FXMLLoader будет не сможете ввести ссылку на ось, определенную в вашем FXML.

Помимо

Вы можете иметь другие ошибки в коде (например, вокруг параллельности и нарезание резьбы). Таким образом, приведенные выше могут быть не все ваши ошибки. В общем, при создании mcve попытайтесь устранить все, что не имеет отношения к рассматриваемому вопросу (например,код потока и нестрочные строки FXML), но включают все, что кто-то может использовать для копирования и вставки вашего кода для компиляции и запуска его для репликации вашей проблемы.

Примечание: Образец приложения Ensemble содержит пример программы, которая обновляет график в режиме реального времени на основе входных данных звукового спектра.

+0

hmm, ну, действительно ли это исправить, но график пока не отображается в режиме реального времени. Это происходит только тогда, когда я устанавливаю только график как сцену. Есть идеи? Не могу дать полный исходный код для репликации, поскольку он основан на входах, созданных arduino yun ... Вы можете попытаться использовать случайные данные, но поскольку график на его собственных работах, я предполагаю, что проблема не существует – Wouter

+0

Я думаю (надеюсь) ваш оригинальный вопрос (добавление некоторых данных в вашу программу к графику, который вы определили в SceneBuilder). Вы можете задать новый вопрос об обновлении данных графика в режиме реального времени. Если вы создаете новый вопрос, предоставляете mcve, полный исходный код не нужен или не нужен - только поставляйте минимальный исполняемый код, который реплицирует проблему. На самом деле попытайтесь отделить ваш код с резьбой и ваш код, связанный с JavaFX UI, - я не могу придумать, почему кто-то создавал новые потоки и объявлял BlockingQueues внутри контроллера JavaFX. – jewelsea

Смежные вопросы