javafx和可序列化

时间:2016-01-27 14:06:39

标签: file-io graphics javafx

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

import javafx.scene.canvas.GraphicsContext;

public interface Drawable
{
    public void draw(GraphicsContext g);
}

当我尝试这个时,我被NotSerializableExcepton s轰炸。 什么是最好的替代行动方案?我的所有绘图都知道它们的颜色和大小。

1 个答案:

答案 0 :(得分:2)

使用自定义可序列化表单并序列化您需要的数据。 E.g。

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,而defaultReadObjectdefaultWriteObject将处理它们。如果您有不可序列化的字段,请将它们标记为transient并以可以序列化的形式序列化数据,如示例所示。

显然,由于你有多个这个接口的实现,可能都需要这个功能,所以用一些静态方法创建一个helper类可能会对你有所帮助:

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