javafx和可串行化 [英] javafx and serializability
问题描述
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 Drawable
s 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 NotSerializableExcepton
s.
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屋!