javafx and serializability

前端 未结 1 1932
误落风尘
误落风尘 2021-01-28 08:19

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 Dr

1条回答
  •  离开以前
    2021-01-28 08:53

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

    0 讨论(0)
提交回复
热议问题