javafx 用颜色序列化包装器

javafx serialize wrapper with color

编辑: 我正在尝试使用这些数据字段序列化 class:

    private int radius;
    private int strokeWidth;
    private String colorName;
    private CannonBallDrawModeEnum cannonBallDrawModeEnum;

有一些方法可以将 colorName 转换为 Color。在我序列化之前,我调用一个方法将 colorName 转换回 String 以确保没有问题。序列化后,我注意到文本文件中的标签 <color/>。当我删除标签时,我可以毫无问题地反序列化 class 。如何阻止此标签被序列化?

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<serializeWrapper>
    <cannonBallData>
        <cannonBallDrawModeEnum>CIRCLE</cannonBallDrawModeEnum>
        </color>                     //<--------------This line does not belong.
        <colorName>RED</colorName>
        <radius>40</radius>
        <strokeWidth>1</strokeWidth>
    </cannonBallData>
    <pyramidData>
        <height>4</height>
        <name>MyPyramid_1</name>
        <stackingOrder>LeftJustified</stackingOrder>
    </pyramidData>
</serializeWrapper>

由于您使用的是 JAXB,因此您应该使用 XmlAdapterColor 映射到 String 中,反之亦然。这是一个例子:

Main.java:

import java.io.File;
import javafx.scene.paint.Color;
import javax.xml.bind.JAXB;

public class Main {

  public static void main(String[] args) {
    File file = new File("entity.xml").getAbsoluteFile();
    System.out.println("XML FILE       : " + file);

    Entity entity = new Entity();
    entity.setRadius(24);
    entity.setStrokeWidth(2);
    entity.setColor(Color.RED);

    System.out.println("BEFORE MARSHAL : " + entity);
    JAXB.marshal(entity, file);
    System.out.println("AFTER UNMARSHAL: " + JAXB.unmarshal(file, Entity.class));
  }
}

Entity.java:

import javafx.scene.paint.Color;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlRootElement
public class Entity {

  private Color color;
  private int radius;
  private int strokeWidth;

  @XmlElement
  @XmlJavaTypeAdapter(ColorXmlAdapter.class) // apply adapter
  public Color getColor() {
    return color;
  }

  public void setColor(Color color) {
    this.color = color;
  }

  @XmlElement
  public int getRadius() {
    return radius;
  }

  public void setRadius(int radius) {
    this.radius = radius;
  }

  @XmlElement
  public int getStrokeWidth() {
    return strokeWidth;
  }

  public void setStrokeWidth(int strokeWidth) {
    this.strokeWidth = strokeWidth;
  }

  @Override
  public String toString() {
    return "Entity{radius=" + radius + ", strokeWidth=" + strokeWidth + ", color=" + color + "}";
  }
}

ColorXmlAdapter.java:

import javafx.scene.paint.Color;
import javax.xml.bind.annotation.adapters.XmlAdapter;

public class ColorXmlAdapter extends XmlAdapter<String, Color> {

  @Override
  public Color unmarshal(String v) throws Exception {
    return Color.valueOf(v); // capable of parsing hex color strings
  }

  @Override
  public String marshal(Color v) throws Exception {
    int red = toInt(v.getRed()) << 24;
    int green = toInt(v.getGreen()) << 16;
    int blue = toInt(v.getBlue()) << 8;
    int alpha = toInt(v.getOpacity());

    // Convert to hex color string
    int rgba = red + green + blue + alpha;
    return String.format("#%08X", rgba);
  }

  private static int toInt(double rgbaComponent) {
    return (int) Math.round(255 * rgbaComponent);
  }
}

上面会输出如下XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<entity>
    <color>#FF0000FF</color>
    <radius>24</radius>
    <strokeWidth>2</strokeWidth>
</entity>