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,因此您应该使用 XmlAdapter
将 Color
映射到 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>
编辑: 我正在尝试使用这些数据字段序列化 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,因此您应该使用 XmlAdapter
将 Color
映射到 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>