0

I am trying to have a class with an Image (javaFX) property saved in a binary file but when the Image is different than null I get an IOException.

Is it possible to make this work either by using an Image object or in some other way?

Here is a Demo class showing the problem.

import java.io.*;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.image.Image;

public class Demo extends Application {
  public static void main(String[] args) {
    launch(args);
  }

  public void start(Stage stage) {
    TheObject obj1 = new TheObject(1, new Image("image1.jpg"));
    TheObject obj2 = new TheObject(2, new Image("image2.jpg"));
    TheObject obj3 = new TheObject(3, new Image("image3.jpg"));

    ObjectOutputStream outputStream;

    try {
      outputStream = new ObjectOutputStream(new FileOutputStream("file"));

      outputStream.writeObject(obj1);
      outputStream.writeObject(obj2);
      outputStream.writeObject(obj3);
    }
    catch(IOException e) {
      System.out.println("IOException");
      System.exit(0);
    }
  }

  public static class TheObject {
    private int id;
    private Image img;

    TheObject(int id, Image img) {
      this.id = id;
      this.img = img;
    }

    public int getID() { return id; }

    public Image getImg() { return img; }

    public void setID(int id) { this.id = id; }

    public void setImg(Image img) { this.img = img; }
  }
}
Thanasis
  • 25
  • 4

2 Answers2

0

First, take a look at this and i dont know why you dont print your stacktrace.

And in order to help you, you need

public static class TheObject implements Serializable

Also, add this to theobject:

TheObject() { //default constructor

 }

Finally if import javafx.scene.image.Image does not implement serializable interface you must do something like this

I really have a problem with it though (posted it 5 mins ago). You might face it too...Take a look: Serialize Obj with 2 BufferedImage transient fields, second image won't be read

EDIT: If you would have printed your stacktrace, google would show you the way to this...

George Z.
  • 6,643
  • 4
  • 27
  • 47
0

Image is not serializable so you need to implement custom (de)serialisation. You can convert the image to a BufferedImage and use ImageIO to write the data to the ObjectOutputStream to do this.

Also TheObject needs to implement Serializable:

public static class TheObject implements Serializable {
    private int id;
    private transient Image img; // not written to stream via default serialisation

    TheObject(int id, Image img) {
      this.id = id;
      this.img = img;
    }

    ...

    // custom serialisation
    private void writeObject(ObjectOutputStream out) throws IOException {
        out.defaultWriteObject(); // write non-transient data

        // write image if not null
        out.writeBoolean(img != null);
        if (img != null) {
            ImageIO.write(SwingFXUtils.fromFXImage(img, null), "png", out);
        }
    }

    // custom deserialisation
    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        // read non-transient data
        in.defaultReadObject();

        // read image if not null
        if (in.readBoolean()) {
            img = new Image(in);
        } else {
            img = null;
        }
    }
}

also remember to close the output stream or better: use try-with-resources:

try (FileOutputStream fos = new FileOutputStream("file");
     ObjectOutputStream outputStream = new ObjectOutputStream()) {

    outputStream.writeObject(obj1);
    outputStream.writeObject(obj2);
    outputStream.writeObject(obj3);
} catch(IOException e) {
    System.out.println("IOException");
    System.exit(0);
}
fabian
  • 80,457
  • 12
  • 86
  • 114