File io javafx与可序列化性
在旧的AWT库中,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轰击。 最佳的替代行动方案是什么?我所有的绘图表都知道
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,我不是说通过网络编组对象,更容易展平复杂对象图以进行保存,比如在游戏中:例如,可能有几十个复杂集合需要手动展平到一个文件。