如何将JavaFX对象保存到文件并重新加载

时间:2018-08-18 01:14:55

标签: java javafx serialization

我正在尝试将一些JavaFX SimpleDoublePropertyImagePolygonPathGroup保存到文件中,并也将其保存为文件能够再次加载它们。

我尝试序列化我的类,并且尝试覆盖Field和Obstacle和FieldBorder类中的writeObject和readObject方法,但是由于所有JavaFX对象都不可序列化,因此事实证明很难序列化我的字段。我还尝试了Google gson库,但是,由于我不太了解该库,因此无法将对象转换为JSON(冗余名称过多存在问题)错过了一种简单的方法。

我成功保存了Image以及SimpleDoubleProperty UNIT和SCALE,但是,当保存AbstractObstacleFieldBorder的列表时,我没有成功。 我要保存的字段位于Field.java中:

  • robotWidth
  • SCALE
  • UNIT
  • fieldObstacles
  • 图片
  • obstacleGroup
  • fieldBorder

Field.java

import static calibration.Helper.PIXELS;
import static calibration.Helper.getImage;

import calibration.obstacle.AbstractObstacle;
import calibration.obstacle.FieldBorder;
import calibration.obstacle.Obstacle;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Pattern;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.WritableObjectValue;
import javafx.scene.Group;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.ButtonType;
import javafx.scene.image.Image;
import javax.imageio.ImageIO;
import org.waltonrobotics.motion.Path;

public class Field {

  private static final Field instance = new Field();
  private static final String SUFFIX = ".field";
  private static final String MATCH_PATTERN = "[0-9.]+ [a-zA-Z]+";
  private static final Alert useFieldValue = new Alert(AlertType.CONFIRMATION);
  public final double robotWidth = 0.8171;
  public final SimpleDoubleProperty SCALE = new SimpleDoubleProperty(1);
  public final WritableObjectValue<String> UNIT = new SimpleStringProperty(PIXELS);
  private final List<AbstractObstacle> fieldObstacles = new ArrayList<>();
  public File imageFile;
  public Image image;
  public Group obstacleGroup = new Group();
  private FieldBorder fieldBorder = null;

  static {
    useFieldValue
        .setContentText(
            "This file already has field information inside of it do you wish to load it?");


  }

  private Field() {
    Path.setRobotWidth(robotWidth);
  }

  public static Field getInstance() {
    return instance;
  }

  public  FieldBorder getFieldBorder() {
    return fieldBorder;
  }

  public  List<AbstractObstacle> getFieldObstacles() {
    return fieldObstacles;
  }

  public  Image loadData(File loadFile) throws IOException, java.io.FileNotFoundException {
    Image image = getImage(loadFile);

    imageFile = loadFile;
    Field.getInstance().image = image;

    try (BufferedReader bufferedReader = new BufferedReader(
        new InputStreamReader(new FileInputStream(loadFile), StandardCharsets.UTF_8))) {
      AtomicReference<String> lastLine = new AtomicReference<>();

      bufferedReader.lines().forEach(lastLine::set);
      lastLine.set(lastLine.get().trim());

      if (Pattern.matches(MATCH_PATTERN, lastLine.get())) {
        String[] data = lastLine.get().split("\\s");

        SCALE.set(Double.parseDouble(data[0]));
        UNIT.set(data[1]);
      } else {
        SCALE.set(1.0);
        UNIT.set(PIXELS);
      }

    }

    return image;
  }

  public  void saveData(File saveFile) throws IOException {
    if (saveFile.exists()) {
      System.out.println((saveFile.delete() ? "M" : "Did not m") + "anage to delete the file");
    }
    if (saveFile.createNewFile()) {

      {
        String splits = imageFile.getAbsolutePath()
            .substring(imageFile.getAbsolutePath().lastIndexOf('.') + 1);
        ImageIO.write(ImageIO.read(imageFile), "jpg".equals(splits) ? "jpeg" : "png", saveFile);
      }

      try (BufferedWriter bufferedWriter = Files
          .newBufferedWriter(saveFile.toPath(), StandardOpenOption.APPEND)) {

        bufferedWriter.newLine();
        bufferedWriter.write(String.format("%f %s", SCALE.get(), UNIT.get()));
      }
    }
  }

  public  boolean isFieldFile(File file) {
    if (file.getName().endsWith(SUFFIX)) {
      Optional<ButtonType> buttonTypeOptional = useFieldValue.showAndWait();

      return buttonTypeOptional.isPresent() && (buttonTypeOptional.get() == ButtonType.OK);
    }

    return false;
  }

  public  void addObstacle(Obstacle obstacle) {
    fieldObstacles.add(obstacle);
    obstacleGroup.getChildren().add(obstacle);

  }

  public  void addObstacle(FieldBorder obstacle) {

    if (fieldBorder != null) {
      fieldObstacles.remove(fieldBorder);
      obstacleGroup.getChildren().remove(fieldBorder);
    }

    fieldObstacles.add(obstacle);
    obstacleGroup.getChildren().add(obstacle);
    fieldBorder = obstacle;
  }

}

以下是与“障碍物”列表一起使用的“障碍物”类。

AbstractObstacle.java

import javafx.scene.Group;
import javafx.scene.shape.Shape;

public class AbstractObstacle extends Group {

  private final ThreatLevel threatLevel;
  private final Shape definingShape;

  public AbstractObstacle(ThreatLevel threatLevel, Shape definingShape) {
    this.threatLevel = threatLevel;
    this.definingShape = definingShape;

    getChildren().add(definingShape);
  }


  public ThreatLevel getThreatLevel() {
    return threatLevel;
  }

  public Shape getDefiningShape() {
    return definingShape;
  }
}

Obstacle.java

import javafx.scene.shape.Polygon;

public class Obstacle extends AbstractObstacle {
      public Obstacle(ThreatLevel threatLevel, Polygon definingShape) {
    super(threatLevel, new Polygon(definingShape.getPoints().stream().mapToDouble(value -> value).toArray()));

    this.getDefiningShape().setFill(definingShape.getFill());
    this.getDefiningShape().setStroke(definingShape.getStroke());
    this.getDefiningShape().setStrokeWidth(definingShape.getStrokeWidth());
  }
}

FieldObstacle.java

import javafx.scene.shape.Path;

public class FieldBorder extends AbstractObstacle {

  public FieldBorder(Path definingShape) {
    super(ThreatLevel.ERROR, new Path(definingShape.getElements()));

    this.getDefiningShape().setFill(definingShape.getFill());
    this.getDefiningShape().setStroke(definingShape.getStroke());
    this.getDefiningShape().setStrokeWidth(definingShape.getStrokeWidth());
  }
}

完整代码为here

0 个答案:

没有答案