简体   繁体   English

JavaFX:如何反序列化动态创建Area Chart Series?

[英]JavaFX: How to deserialize dynamically create Area Chart Series?

I am adding series dynamically using list in Area Chart. 我正在使用面积图中的列表动态添加序列。 I want to unwrap the series. 我想拆开系列。 I need this because I want to save Area Chart series data in db. 我需要这样做,因为我想将面积图系列数据保存在db中。

When app execute it's like this: 应用执行时如下所示:

在此处输入图片说明

User can add series by filling the textfields and by clicking the Add button: 用户可以通过填充文本字段并单击“添加”按钮来添加系列:

在此处输入图片说明

在此处输入图片说明

What I want is when user click on the Save button it should translate the already added series into data so I can store it in db. 我想要的是,当用户单击“保存”按钮时,它应该将已经添加的系列转换为数据,以便将其存储在db中。 But what I've tried it It's not giving me the accurate data. 但是我尝试过的操作并没有给我准确的数据。 According to series on chat I want to get output like this: 根据聊天系列,我想要这样的输出:

Series 0 Employees: 5
Series 0 Start: 1
Series 0 End: 7
Series 1 Employees: 3
Series 1 Start: 9
Series 1 End: 12

But I'm getting this: 但是我得到这个:

Series 0 Employees: 5
Series 0 Start: 1
Series 0 End: 5
Series 1 Employees: 3
Series 1 Start: 10
Series 1 End: 5

在此处输入图片说明

Code: 码:

import java.net.URL;
import java.util.LinkedList;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.chart.AreaChart;
import javafx.scene.chart.XYChart;
import javafx.scene.chart.XYChart.Series;
import javafx.scene.control.TextField;


/**
 *
 * @author blj0011
 */
public class SampleController implements Initializable {

    @FXML
    private AreaChart<Number, Number> areaChart;
    @FXML
    private TextField txtSt;
    @FXML
    private TextField txtEt;
    @FXML
    private TextField txtNb;


    LinkedList<XYChart.Series<Number, Number>> seriesContainer = new LinkedList<Series<Number, Number>>();

        //Button add functionality
        @FXML
        private void generateGraph() {

            Double start = Double.parseDouble(txtSt.getText());

            Double end = Double.parseDouble(txtEt.getText());
            double numberEmployees = Integer.parseInt(txtNb.getText());

            XYChart.Series<Number, Number> series= new XYChart.Series<>();

            for (int i = start.intValue(); i <= end.intValue(); i++) {
                series.getData().add(new XYChart.Data(i, numberEmployees));
            }


           // Add Series to series container.
           seriesContainer.add(series);

           //Add only new series to AreaChart
           for(XYChart.Series<Number, Number> entry : seriesContainer)
           {
               if(!areaChart.getData().contains(entry))
               {                    
                    areaChart.getData().add(entry);
                    entry.setName("XYChart.Series "+seriesContainer.size());               }
           }
        }

        //Button delete functionality
        @FXML
        private void deleteGraph() {

        }

        //Button Undo functionality
        @FXML
        private void undoGraph(){

            }

        //Button Save functionality
        @FXML
        private void saveGraph(){           
                int max = 0;

                for(int i =0; i< seriesContainer.size(); i++){
                    XYChart.Series<Number, Number> test = seriesContainer.get(i);
                        System.out.println("Series "+i+" Employees: "+test.getData().get(i).getYValue().intValue());
                        System.out.println("Series "+i+" Start: "+test.getData().get(i).getXValue().intValue());

                        // find maximal y value
                        int x = test.getData().get(i).getYValue().intValue();
                        if (x > max) {
                            max = x;
                        }
                        System.out.println("Series "+i+" End: "+max);
                }
            }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        areaChart.setTitle("Chronos");
        areaChart.getXAxis().setLabel("Heures");
        areaChart.getYAxis().setLabel("Employés");
    }
}

FXML XML文件

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

<?import javafx.scene.chart.AreaChart?>
<?import javafx.scene.chart.NumberAxis?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>

<VBox alignment="CENTER" prefHeight="800.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.SampleController">
   <children>
      <AreaChart fx:id="areaChart" prefHeight="799.0" prefWidth="800.0" VBox.vgrow="ALWAYS">
         <xAxis>
            <NumberAxis autoRanging="false" minorTickCount="1" minorTickLength="1.0" side="BOTTOM" tickLabelGap="1.0" tickLength="1.0" tickUnit="1.0" upperBound="24.0" fx:id="xAxis" />
         </xAxis>
         <yAxis>
            <NumberAxis fx:id="yAxis" autoRanging="false" minorTickLength="1.0" side="LEFT" tickLabelGap="1.0" tickUnit="1.0" upperBound="10.0" />
         </yAxis>
      </AreaChart>
      <HBox alignment="CENTER" prefHeight="193.0" prefWidth="800.0">
         <children>
            <TextField fx:id="txtSt" promptText="Start Value" />
            <TextField fx:id="txtEt" promptText="End Value" />
            <TextField fx:id="txtNb" promptText="Number of Employees" />
         </children>
      </HBox>
      <HBox alignment="CENTER" prefHeight="71.0" prefWidth="800.0">
         <children>
            <Button mnemonicParsing="false" onAction="#generateGraph" prefHeight="31.0" prefWidth="137.0" text="Add" />
            <Button layoutX="342.0" layoutY="12.0" mnemonicParsing="false" onAction="#deleteGraph" prefHeight="31.0" prefWidth="137.0" text="Delete" />
            <Button layoutX="410.0" layoutY="12.0" mnemonicParsing="false" onAction="#undoGraph" prefHeight="31.0" prefWidth="137.0" text="Undo" />
            <Button layoutX="479.0" layoutY="10.0" mnemonicParsing="false" onAction="#saveGraph" prefHeight="31.0" prefWidth="137.0" text="Save" />
         </children>
      </HBox>
   </children>
</VBox>

Please someone guide me how can I resolve this and please I need some guidance how can store this data in H2 dB. 请有人指导我如何解决此问题,并需要一些指导如何将数据存储在H2 dB中。 I'm using JavaFX with Spring Boot. 我在Spring Boot中使用JavaFX。

There are various ways to accomplish this. 有多种方法可以实现此目的。 Some are faster than others. 有些比其他的快。 I will show you one simple way ti can be done, but please note there are several. 我将向您展示可以完成ti的一种简单方法,但是请注意有几种方法。

If speed is not a concern than I like to serialize objects into base64 text. 如果不关心速度,那么我想将对象序列化为base64文本。 This makes it very easy to mover around and store in DB's as text. 这样就很容易在文本中移动和存储在数据库中。 If I was working on a project that required moving a lot of data an speed mattered, then I might not go with this approach. 如果我在一个需要大量数据移动速度的项目中工作,那么我可能不会采用这种方法。

1) Use Java serialization to serialize the object into a byte[] . 1)使用Java序列化将对象序列化为byte[]

protected byte[] convertToBytes(Object object) throws IOException {
    try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutput out = new ObjectOutputStream(bos)) {
        out.writeObject(object);
        return bos.toByteArray();
    }
}

protected Object convertFromBytes(byte[] bytes) throws IOException, ClassNotFoundException {
    try (ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
            ObjectInput in = new ObjectInputStream(bis)) {
        return in.readObject();
    }
}

These methods can be used to convert Java objects to convert objects into and out of byte[]. 这些方法可用于转换Java对象,以将对象转换为byte []或转换为byte []。

2) Take the byte[] from step 1 and use it to serialize into base64 text. 2)从第1步中获取byte []并将其用于序列化为base64文本。 These two methods will turn your seriesContainer into base64 String, or will turn a base64 String into seriesContainer . 这两个方法会将您的seriesContainer转换为base64 String,或者将base64字符串转换为seriesContainer

public String toBase64() {
    try {
        return Base64.getEncoder().encodeToString(convertToBytes(seriesContainer));
    } catch (IOException ex) {
        throw new RuntimeException("Got exception while converting to bytes.", ex);
    }
}

public void initializeFromBase64(String b64) {
    byte[] bytes = Base64.getDecoder().decode(b64);
    try {
        this.seriesContainer = (LinkedList<XYChart.Series<Number, Number>>) convertFromBytes(bytes);
    } catch (Exception ex) {
        throw new RuntimeException("Got exception while converting from bytes.", ex);
    }
}

3) Take the String from step 2 and put it into a DB, or read it from a DB. 3)从第2步中获取字符串,并将其放入数据库中,或从数据库中读取。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM