javafx和可串行化 [英] javafx and serializability

查看:166
本文介绍了javafx和可串行化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在旧的AWT库中, Point 类和 Color 类是可序列化的。在JavaFX中都不是。我想将 Drawable 的数组列表保存到一个文件中;这里是接口

  import javafx.scene.canvas.GraphicsContext; 

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

$ / code>

当我尝试这个时,我被 NotSerializableExcepton 秒。
什么是最佳替代方案?我所有的drawables都知道它们的颜色和大小。使用自定义的可序列化表单并序列化你需要的数据。例如:

  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;

公共类DrawableRect实现Drawable,可序列化{

私有瞬态颜色颜色;
私有瞬态Rectangle2D界限;

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

$ b $ private void writeObject(ObjectOutputStream s)throws IOException {
s.defaultWriteObject();
//写入颜色:
s.writeDouble(color.getRed());
s.writeDouble(color.getGreen());
s.writeDouble(color.getBlue());
s.writeDouble(color.getOpacity());

//写入界限:
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 会处理它们。如果您的字段不是可序列化的,请将它们标记为 transient ,并按照示例中的序列化形式序列化数据。



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

< pre $ public $ {
$ public $ {
$ b 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());

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

返回新的颜色(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();

返回新的Rectangle2D(x,y,w,h);


$ / code $ / pre

然后在可绘制的实现简化为类似于

私有空间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);
}


In the old AWT libraries, the Point class and the Color class were serializable. Neither is in JavaFX. I would like to save an array list of Drawables to a file; here is the interface

import javafx.scene.canvas.GraphicsContext;

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

When I attempt to to this, I get bombarded by NotSerializableExceptons. What is the best alternate course of action? All of my drawables know their color and size.

解决方案

Use a custom serializable form and serialize the data you need. 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);
    }
}

If you have fields that are serializable (or primitive types), you don't mark them transient, and the defaultReadObject and defaultWriteObject will handle them. If you have fields that are not serializable, mark them transient and serialize the data in a form that can be serialized as in the example.

Obviously, since you have multiple implementations of this interface which may all need this functionality, it might benefit you to create a helper class with some static methods:

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

and then of course the methods in your Drawable implementations reduce to something like

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

这篇关于javafx和可串行化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆