简体   繁体   English

在 JavaFX 应用程序中将颜色保存为状态

[英]Saving color as state in a JavaFX application

I have an application that draws shapes.我有一个绘制形状的应用程序。 Shapes know their color and size (an integer).形状知道它们的颜色和大小(整数)。 I would like for this program to save shapes into a file.我希望这个程序将形状保存到文件中。 JavaFX's color class is not serializable. JavaFX 的颜色类不可序列化。

Should I not be serializing objects and should I forget about using ObjectOutputStreams and ObjectInputStreams?我不应该序列化对象,我应该忘记使用 ObjectOutputStreams 和 ObjectInputStreams 吗? Is there another preferred way to do this in JavaFX?在 JavaFX 中是否有另一种首选方法可以做到这一点?

Here is a quick arabesque around the problem.这是围绕这个问题的快速蔓藤花纹。

import java.io.Serializable;
import javafx.scene.paint.Color;
public class SerializableColor implements Serializable
{
    private double red;
    private double green;
    private double blue;
    private double alpha;
    public SerializableColor(Color color)
    {
        this.red = color.getRed();
        this.green = color.getGreen();
        this.blue = color.getBlue();
        this.alpha = color.getOpacity();
    }
    public SerializableColor(double red, double green, double blue, double alpha)
    {
        this.red = red;
        this.green = green;
        this.blue = blue;
        this.alpha = alpha;
    }
    public Color getFXColor()
    {
        return new Color(red, green, blue, alpha);
    }
}

I can´t tell you, which is the most common way to solve your usecase, but we have a simular one, where we serialize a shapes state.我不能告诉你,这是解决你的用例的最常见方法,但我们有一个类似的方法,我们序列化一个形状状态。 We use xStream to persist its state in XML.我们使用xStream将其状态保存在 XML 中。

For Color Attributes we created an own ColorConverter to make Color Serializable.对于颜色属性,我们创建了自己的 ColorConverter 以使颜色可序列化。 The converter just cares about the red, green and blue value of a color as well as its opacity.转换器只关心颜色的红色、绿色和蓝色值及其不透明度。 This way, the XML stays simple and clean, when it comes to color attributes.这样,XML 在颜色属性方面保持简单和干净。

Talking about serialization of shapes, the whole thing gets more complicated, since xStream serializes all dependencies of an object.谈到形状的序列化,整个事情变得更加复杂,因为 xStream 序列化了一个对象的所有依赖项。 Therefore you might want to create template objects for each shade to just store the information you need and ignore the rest.因此,您可能希望为每个阴影创建模板对象,以仅存储您需要的信息而忽略其余信息。 This will also insure, that you stay independent of possible future shape changes within the javafx api.这也将确保您不受 javafx api 中未来可能发生的形状变化的影响。

There is also a small javafx xstream converter collection called XStreamFX , which might holds interesting converters for you.还有一个名为XStreamFX的小型 javafx xstream 转换器集合,它可能为您提供有趣的转换器。

You can store a serializeable class instance to a file instead of your shapes.您可以将可序列化的类实例存储到文件而不是形状。 Let this class implement a method Object readResolve() throws ObjectStreamException that restores the shape.让这个类实现一个方法Object readResolve() throws ObjectStreamException来恢复形状。

Here's a simple example for Rectangle , that serializes the width, height and color:这是Rectangle的一个简单示例,它序列化了宽度、高度和颜色:

public class RectData implements Serializable {

    public RectData(Rectangle rect) {
        this.width = rect.getWidth();
        this.height = rect.getHeight();
        Color color = (Color) rect.getFill();
        this.color = (int) (color.getRed() * 0xFF) | 
                ((int) (color.getGreen() * 0xFF)) << 010 | 
                ((int) (color.getBlue() * 0xFF)) << 020 | 
                ((int) (color.getOpacity() * 0xFF)) << 030;
    }

    private final int color;
    private final double width;
    private final double height;

    private Object readResolve() throws ObjectStreamException {
        Rectangle rect = new Rectangle(width, height);
        rect.setFill(Color.rgb(
                color & 0xFF,
                (color >>> 010) & 0xFF,
                (color >>> 020) & 0xFF,
                (color >>> 030) / 255d));
        return rect;
    }

}

Example serialisation示例序列化

try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("data/shapeser.ser"))) {
    Rectangle rect = new Rectangle(100, 200);
    rect.setFill(Color.CHOCOLATE);
    oos.writeObject(new RectData(rect));
}

Deserialisation反序列化

Node node;
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("data/shapeser.ser"))) {
    node = (Node) ois.readObject();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM