File io javafx与可序列化性

File io javafx与可序列化性,file-io,graphics,javafx,File Io,Graphics,Javafx,在旧的AWT库中,Point类和Color类是可序列化的。JavaFX中也没有。我想将Drawables的数组列表保存到一个文件中;这里是界面 import javafx.scene.canvas.GraphicsContext; public interface Drawable { public void draw(GraphicsContext g); } 当我尝试这样做时,我会被notserializableexptons轰击。 最佳的替代行动方案是什么?我所有的绘图表都知道

在旧的AWT库中,
Point
类和
Color
类是可序列化的。JavaFX中也没有。我想将
Drawable
s的数组列表保存到一个文件中;这里是界面

import javafx.scene.canvas.GraphicsContext;

public interface Drawable
{
    public void draw(GraphicsContext g);
}
当我尝试这样做时,我会被
notserializableexpton
s轰击。
最佳的替代行动方案是什么?我所有的绘图表都知道它们的颜色和大小。

使用自定义的可序列化表单并序列化所需的数据。例如

import javafx.scene.canvas.GraphicsContext ;
import javafx.scene.paint.Color ;
import javafx.geometry.Rectangle2D;
import java.io.Serializable ;
import java.io.ObjectInputStream ;
import java.io.ObjectOutputStream ;
import java.io.IOException ;

public class DrawableRect implements Drawable, Serializable {

    private transient Color color ;
    private transient Rectangle2D bounds ;

    public DrawableRect(Color color, Rectangle2D bounds) {
        this.color = color ;
        this.bounds = bounds ;
    }

    @Override
    public void draw(GraphicsContext g) {
        g.setFill(color);
        g.fillRect(bounds.getMinX(), bounds.getMinY(), bounds.getWidth(), bounds.getHeight());
    }

    private void writeObject(ObjectOutputStream s) throws IOException {
        s.defaultWriteObject();
        // write color:
        s.writeDouble(color.getRed());
        s.writeDouble(color.getGreen());
        s.writeDouble(color.getBlue());
        s.writeDouble(color.getOpacity());

        // write bounds:
        s.writeDouble(bounds.getMinX());
        s.writeDouble(bounds.getMinY());
        s.writeDouble(bounds.getWidth());
        s.writeDouble(bounds.getHeight());
    }

    private void readObject(ObjectInputStream s)
            throws IOException, ClassNotFoundException {
        s.defaultReadObject();
        double r = s.readDouble();
        double g = s.readDouble();
        double b = s.readDouble();
        double opacity = s.readDouble();

        color = new Color(r,g,b,opacity);

        double x = s.readDouble();
        double y = s.readDouble();
        double w = s.readDouble();
        double h = s.readDouble();

        bounds = new Rectangle2D(x,y,w,h);
    }
}
如果您有可序列化的字段(或基元类型),则不会将它们标记为
transient
,而
defaultReadObject
defaultWriteObject
将处理它们。如果有不可序列化的字段,请将其标记为“瞬态”,并以可序列化的形式序列化数据,如示例所示

显然,由于此接口的多个实现可能都需要此功能,因此使用一些静态方法创建帮助器类可能会对您有所帮助:

public class DrawableIO {

    public static void writeColor(Color color, ObjectOutputStream s) throws IOException {
        s.writeDouble(color.getRed());
        s.writeDouble(color.getGreen());
        s.writeDouble(color.getBlue());
        s.writeDouble(color.getOpacity());
    }

    public static Color readColor(ObectInputStream s) throws IOException {
        double r = s.readDouble();
        double g = s.readDouble();
        double b = s.readDouble();
        double opacity = s.readDouble();

        return new Color(r,g,b,opacity);
    }

    public static void writeBounds(Rectangle2D bounds, ObjectOutputStream s) throws IOException {
        s.writeDouble(bounds.getMinX());
        s.writeDouble(bounds.getMinY());
        s.writeDouble(bounds.getWidth());
        s.writeDouble(bounds.getHeight());
    }

    public static Rectangle2D readBounds(ObjectInputStream s)  throws IOException {
        double x = s.readDouble();
        double y = s.readDouble();
        double w = s.readDouble();
        double h = s.readDouble();

        return new Rectangle2D(x,y,w,h);
    }
}
当然,
Drawable
实现中的方法会简化为

private void writeObject(ObjectOutputStream s) throws IOException {
    s.defaultWriteObject();
    DrawableIO.writeColor(color, s);
    DrawableIO.writeBounds(bounds, s);
}

private void readObject(ObjectInputStream s)
        throws IOException, ClassNotFoundException {
    s.defaultReadObject();

    color = DrawableIO.readColor(s);
    bounds = DrawableIO.readBounds(s);
}

使用自定义可序列化表单并序列化所需的数据。例如

import javafx.scene.canvas.GraphicsContext ;
import javafx.scene.paint.Color ;
import javafx.geometry.Rectangle2D;
import java.io.Serializable ;
import java.io.ObjectInputStream ;
import java.io.ObjectOutputStream ;
import java.io.IOException ;

public class DrawableRect implements Drawable, Serializable {

    private transient Color color ;
    private transient Rectangle2D bounds ;

    public DrawableRect(Color color, Rectangle2D bounds) {
        this.color = color ;
        this.bounds = bounds ;
    }

    @Override
    public void draw(GraphicsContext g) {
        g.setFill(color);
        g.fillRect(bounds.getMinX(), bounds.getMinY(), bounds.getWidth(), bounds.getHeight());
    }

    private void writeObject(ObjectOutputStream s) throws IOException {
        s.defaultWriteObject();
        // write color:
        s.writeDouble(color.getRed());
        s.writeDouble(color.getGreen());
        s.writeDouble(color.getBlue());
        s.writeDouble(color.getOpacity());

        // write bounds:
        s.writeDouble(bounds.getMinX());
        s.writeDouble(bounds.getMinY());
        s.writeDouble(bounds.getWidth());
        s.writeDouble(bounds.getHeight());
    }

    private void readObject(ObjectInputStream s)
            throws IOException, ClassNotFoundException {
        s.defaultReadObject();
        double r = s.readDouble();
        double g = s.readDouble();
        double b = s.readDouble();
        double opacity = s.readDouble();

        color = new Color(r,g,b,opacity);

        double x = s.readDouble();
        double y = s.readDouble();
        double w = s.readDouble();
        double h = s.readDouble();

        bounds = new Rectangle2D(x,y,w,h);
    }
}
如果您有可序列化的字段(或基元类型),则不会将它们标记为
transient
,而
defaultReadObject
defaultWriteObject
将处理它们。如果有不可序列化的字段,请将其标记为“瞬态”,并以可序列化的形式序列化数据,如示例所示

显然,由于此接口的多个实现可能都需要此功能,因此使用一些静态方法创建帮助器类可能会对您有所帮助:

public class DrawableIO {

    public static void writeColor(Color color, ObjectOutputStream s) throws IOException {
        s.writeDouble(color.getRed());
        s.writeDouble(color.getGreen());
        s.writeDouble(color.getBlue());
        s.writeDouble(color.getOpacity());
    }

    public static Color readColor(ObectInputStream s) throws IOException {
        double r = s.readDouble();
        double g = s.readDouble();
        double b = s.readDouble();
        double opacity = s.readDouble();

        return new Color(r,g,b,opacity);
    }

    public static void writeBounds(Rectangle2D bounds, ObjectOutputStream s) throws IOException {
        s.writeDouble(bounds.getMinX());
        s.writeDouble(bounds.getMinY());
        s.writeDouble(bounds.getWidth());
        s.writeDouble(bounds.getHeight());
    }

    public static Rectangle2D readBounds(ObjectInputStream s)  throws IOException {
        double x = s.readDouble();
        double y = s.readDouble();
        double w = s.readDouble();
        double h = s.readDouble();

        return new Rectangle2D(x,y,w,h);
    }
}
当然,
Drawable
实现中的方法会简化为

private void writeObject(ObjectOutputStream s) throws IOException {
    s.defaultWriteObject();
    DrawableIO.writeColor(color, s);
    DrawableIO.writeBounds(bounds, s);
}

private void readObject(ObjectInputStream s)
        throws IOException, ClassNotFoundException {
    s.defaultReadObject();

    color = DrawableIO.readColor(s);
    bounds = DrawableIO.readBounds(s);
}

我很害怕。我不明白为什么像点和颜色这样简单的东西是不可序列化的,为什么你必须序列化它们的状态;大多数现代应用程序使用某种封送(例如XML或JSON)来传输和/或保持状态。这些解决方案更加灵活,因为相同的表示可以用于不同的实现类(例如,具有JavaBean或JavaFX属性的域类)。我可以看出这不值得支持。但是在某些情况下,James,我不是说通过网络编组对象,更容易展平复杂的对象图进行保存,比如在游戏中:,那里可能有几十个复杂的集合,否则就需要手动将它们展平到一个文件中。我很担心这一点。我不明白为什么像点和颜色这样简单的东西是不可序列化的,为什么你必须序列化它们的状态;大多数现代应用程序使用某种封送(例如XML或JSON)来传输和/或保持状态。这些解决方案更加灵活,因为相同的表示可以用于不同的实现类(例如,具有JavaBean或JavaFX属性的域类)。我可以看出这不值得支持。但是,在某些情况下,James,我不是说通过网络编组对象,更容易展平复杂对象图以进行保存,比如在游戏中:例如,可能有几十个复杂集合需要手动展平到一个文件。