加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

如何将Java 2D Shape对象序列化为XML?

发布时间:2020-12-14 16:28:24 所属栏目:Java 来源:网络整理
导读:Shape界面由 Java 2D(Arc2D,Area,CubicCurve2D,Ellipse2D,GeneralPath等)的对象实现. 一些具体对象被标记为Serializable,可以使用对象序列化存储和恢复,但像Area这样的其他对象不会实现接口并抛出错误. 但是由于我们经常被警告,这种天真的序列化在Java实现或
Shape界面由 Java 2D(Arc2D,Area,CubicCurve2D,Ellipse2D,GeneralPath等)的对象实现.

一些具体对象被标记为Serializable,可以使用对象序列化存储和恢复,但像Area这样的其他对象不会实现接口并抛出错误.

但是由于我们经常被警告,这种天真的序列化在Java实现或版本中不一定稳定,所以我更喜欢使用某种形式的序列化.

这导致我们使用XMLEncoder和XMLDecoder从XML存储/恢复,但是它能够处理更少的Java 2D Shape对象.

两者的一些结果可以在下面看到.我们从6个形状开始,并尝试通过对象序列化和标准XML序列化来存储/恢复它们.

我们将如何通过XML正确存储所有Shape对象?

import java.awt.*;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import java.beans.*;
import java.io.*;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.border.TitledBorder;

public class Serialize2D {

    private JPanel ui;

    Serialize2D() {
        initUI();
    }

    public void initUI() {
        if (ui != null) {
            return;
        }
        ui = new JPanel(new GridLayout(0,1));

        int[] xpoints = {205,295,205,295};
        int[] ypoints = {5,25,45};
        Polygon polygon = new Polygon(xpoints,ypoints,xpoints.length);

        ArrayList<Shape> shapes = new ArrayList<Shape>();
        int w = 45;
        shapes.add(new Rectangle2D.Double(5,5,90,40));
        shapes.add(new Ellipse2D.Double(105,40));
        shapes.add(polygon);
        shapes.add(new GeneralPath(new Rectangle2D.Double(5,55,40)));
        shapes.add(new Path2D.Double(new Rectangle2D.Double(105,40)));
        shapes.add(new Area(new Rectangle2D.Double(205,40)));

        addTitledLabelToPanel(shapes,"Original Shapes");
        addTitledLabelToPanel(
                serializeToFromObject(shapes),"Serialize via Object");
        addTitledLabelToPanel(
                serializeToFromXML(shapes),"Serialize via XML");
    }

    public JComponent getUI() {
        return ui;
    }

    public ArrayList<Shape> serializeToFromObject(ArrayList<Shape> shapes) {
        ArrayList<Shape> shps = new ArrayList<Shape>();
        try {
            ObjectOutputStream oos = null;
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(baos);
            for (Shape shape : shapes) {
                try {
                    oos.writeObject(shape);
                } catch (Exception ex) {
                    System.err.println(ex.toString());
                }
            }
            oos.flush();
            oos.close();
            System.out.println("length Obj: " + baos.toByteArray().length);
            ByteArrayInputStream bais = new ByteArrayInputStream(
                    baos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bais);

            Object o = null;
            try {
                o = ois.readObject();
            } catch (NotSerializableException ex) {
                System.err.println(ex.getMessage());
            } catch (ClassNotFoundException ex) {
                ex.printStackTrace();
            }
            while (o != null) {
                shps.add((Shape) o);
                try {
                    o = ois.readObject();
                } catch (NotSerializableException ex) {
                    System.err.println(ex.getMessage());
                } catch (ClassNotFoundException ex) {
                    ex.printStackTrace();
                }
            }
            return shps;
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return shps;
    }

    public ArrayList<Shape> serializeToFromXML(ArrayList<Shape> shapes) {
        ArrayList<Shape> shps = new ArrayList<Shape>();
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            XMLEncoder xmle = new XMLEncoder(baos);
            for (Shape shape : shapes) {
                xmle.writeObject(shape);
            }
            xmle.flush();
            xmle.close();

            System.out.println("length XML: " + baos.toByteArray().length);
            ByteArrayInputStream bais
                    = new ByteArrayInputStream(baos.toByteArray());
            XMLDecoder xmld = new XMLDecoder(bais);
            Shape shape = (Shape) xmld.readObject();
            while (shape != null) {
                shps.add(shape);
                try {
                    shape = (Shape) xmld.readObject();
                } catch (ArrayIndexOutOfBoundsException aioobe) {
                    // we've read last object
                    shape = null;
                }
            }
            xmld.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return shps;
    }

    private final static String getType(Object o) {
        String s = o.getClass().getName();
        String[] parts = s.split(".");
        s = parts[parts.length - 1].split("$")[0];
        return s;
    }

    public static void drawShapesToImage(
            ArrayList<Shape> shapes,BufferedImage image) {
        Graphics2D g = image.createGraphics();
        g.setRenderingHint(
                RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

        g.setColor(Color.WHITE);
        g.fillRect(0,image.getWidth(),image.getHeight());
        for (Shape shape : shapes) {
            String s = getType(shape);
            g.setColor(Color.GREEN);
            g.fill(shape);
            g.setColor(Color.BLACK);
            g.draw(shape);
            Rectangle r = shape.getBounds();
            int x = r.x + 5;
            int y = r.y + 16;
            if (r.width * r.height != 0) {
                g.drawString(s,x,y);
            }
        }

        g.dispose();
    }

    private void addTitledLabelToPanel(ArrayList<Shape> shapes,String title) {
        int w = 300;
        int h = 100;
        BufferedImage bi = new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);
        drawShapesToImage(shapes,bi);
        JLabel l = new JLabel(new ImageIcon(bi));
        l.setBorder(new TitledBorder(title));
        ui.add(l);
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                Serialize2D ss = new Serialize2D();
                JOptionPane.showMessageDialog(null,ss.getUI());
            }
        };
        SwingUtilities.invokeLater(r);
    }
}

解决方法

不幸的是,使用XMLEncoder / Decoder的Shape to XML的天真编码/解码通常会破坏Shape的所有重要信息!

所以要做到这一点,仍然使用上面提到的类,我们序列化和恢复正确构造的bean,它们表示从PathIterator获得的形状部分.这些豆是:

> PathBean,它存储形成Java-2D Shape形状的PathSegment对象的集合.
> PathSegment,其存储路径的特定部分的细节(段类型,绕组规则和协调).

SerializeShapes GUI

用于演示存储和恢复形状的GUI.

>单击椭圆(Ellipse2D),Rectangle(Rectangle2D)或Face(Area)按钮几次.
>退出GUI.形状将被序列化到磁盘.
>重新启动GUI.上次随机绘制的形状将从磁盘&重新出现在GUI中.

所选形状将以绿色填充,其他形状将以红色填充.

package serialize2d;

import java.awt.*;
import java.awt.event.*;
import java.awt.font.FontRenderContext;
import java.awt.geom.AffineTransform;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Random;
import java.util.Vector;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.*;


/** A GUI to make it easy to add/remove shapes from a canvas. 
 It should persist the shapes between runs.  */
public class SerializeShapes {

    JPanel ui;
    JPanel shapePanel;
    Random rand;
    JPanel shapeCanvas;
    DefaultListModel<Shape> allShapesModel;
    ListSelectionModel shapeSelectionModel;
    RenderingHints renderingHints;

    SerializeShapes() {
        initUI();
    }

    public void initUI() {
        if (ui != null) {
            return;
        }
        renderingHints = new RenderingHints(RenderingHints.KEY_DITHERING,RenderingHints.VALUE_DITHER_ENABLE);
        renderingHints.put(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        renderingHints.put(RenderingHints.KEY_ALPHA_INTERPOLATION,RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
        renderingHints.put(RenderingHints.KEY_COLOR_RENDERING,RenderingHints.VALUE_COLOR_RENDER_QUALITY);
        renderingHints.put(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);
        renderingHints.put(RenderingHints.KEY_STROKE_CONTROL,RenderingHints.VALUE_STROKE_NORMALIZE);
        ui = new JPanel(new BorderLayout(4,4));
        ui.setBorder(new EmptyBorder(4,4,4));

        JPanel controls = new JPanel(new FlowLayout(FlowLayout.CENTER,4));
        ui.add(controls,BorderLayout.PAGE_START);
        shapeCanvas = new ShapeCanvas();
        ui.add(shapeCanvas);
        rand = new Random();

        allShapesModel = new DefaultListModel<Shape>();
        JList<Shape> allShapes = new JList<Shape>(allShapesModel);
        allShapes.setCellRenderer(new ShapeListCellRenderer());
        shapeSelectionModel = allShapes.getSelectionModel();
        shapeSelectionModel.setSelectionMode(
                ListSelectionModel.SINGLE_SELECTION);
        ListSelectionListener shapesSelectionListener
                = new ListSelectionListener() {

                    @Override
                    public void valueChanged(ListSelectionEvent e) {
                        shapeCanvas.repaint();
                    }
                };
        allShapes.addListSelectionListener(shapesSelectionListener);

        JScrollPane shapesScroll = new JScrollPane(
                allShapes,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER
        );
        // TODO fix this hack..
        shapesScroll.getViewport().setPreferredSize(new Dimension(60,200));
        ui.add(shapesScroll,BorderLayout.LINE_START);

        Action addEllipse = new AbstractAction("Ellipse") {

            @Override
            public void actionPerformed(ActionEvent e) {
                int w = rand.nextInt(100) + 10;
                int h = rand.nextInt(100) + 10;
                int x = rand.nextInt(shapeCanvas.getWidth() - w);
                int y = rand.nextInt(shapeCanvas.getHeight() - h);
                Ellipse2D ellipse = new Ellipse2D.Double(x,y,w,h);
                addShape(ellipse);
            }
        };
        addEllipse.putValue(Action.MNEMONIC_KEY,KeyEvent.VK_E);

        Action addRectangle = new AbstractAction("Rectangle") {

            @Override
            public void actionPerformed(ActionEvent e) {
                int w = rand.nextInt(100) + 10;
                int h = rand.nextInt(100) + 10;
                int x = rand.nextInt(shapeCanvas.getWidth() - w);
                int y = rand.nextInt(shapeCanvas.getHeight() - h);
                Rectangle2D rectangle = new Rectangle2D.Double(x,h);
                addShape(rectangle);
            }
        };
        addRectangle.putValue(Action.MNEMONIC_KEY,KeyEvent.VK_R);

        final int faceStart = 128513;
        final int faceEnd = 128528;
        final int diff = faceEnd - faceStart;
        StringBuilder sb = new StringBuilder();
        for (int count = faceStart; count <= faceEnd; count++) {
            sb.append(Character.toChars(count));
        }
        final String s = sb.toString();
        Vector<Font> compatibleFontList = new Vector<Font>();
        GraphicsEnvironment ge
                = GraphicsEnvironment.getLocalGraphicsEnvironment();
        Font[] fonts = ge.getAllFonts();
        for (Font font : fonts) {
            if (font.canDisplayUpTo(s) < 0) {
                compatibleFontList.add(font);
            }
        }
        JComboBox fontChooser = new JComboBox(compatibleFontList);
        ListCellRenderer fontRenderer = new DefaultListCellRenderer() {

            @Override
            public Component getListCellRendererComponent(
                    JList list,Object value,int index,boolean isSelected,boolean cellHasFocus) {
                Component c = super.getListCellRendererComponent(
                        list,value,index,isSelected,cellHasFocus);
                JLabel l = (JLabel) c;
                Font font = (Font) value;
                l.setText(font.getName());
                return l;
            }
        };
        fontChooser.setRenderer(fontRenderer);
        final ComboBoxModel<Font> fontModel = fontChooser.getModel();

        BufferedImage bi = new BufferedImage(1,1,BufferedImage.TYPE_INT_RGB);
        Graphics2D g = bi.createGraphics();
        final FontRenderContext fontRenderContext = g.getFontRenderContext();

        Action addFace = new AbstractAction("Face") {

            @Override
            public void actionPerformed(ActionEvent e) {
                int codepoint = faceStart + rand.nextInt(diff);
                String text = new String(Character.toChars(codepoint));

                Font font = (Font) fontModel.getSelectedItem();
                Area area = new Area(
                        font.deriveFont(80f).
                        createGlyphVector(fontRenderContext,text).
                        getOutline());
                Rectangle bounds = area.getBounds();
                float x = rand.nextInt(
                        shapeCanvas.getWidth() - bounds.width) - bounds.x;
                float y = rand.nextInt(
                        shapeCanvas.getHeight() - bounds.height) - bounds.y;
                AffineTransform move = AffineTransform.
                        getTranslateInstance(x,y);
                area.transform(move);
                addShape(area);
            }
        };
        addFace.putValue(Action.MNEMONIC_KEY,KeyEvent.VK_F);

        Action delete = new AbstractAction("Delete") {

            @Override
            public void actionPerformed(ActionEvent e) {
                int idx = shapeSelectionModel.getMinSelectionIndex();
                if (idx < 0) {
                    JOptionPane.showMessageDialog(
                            ui,"Select a shape to delete","Select a Shape",JOptionPane.ERROR_MESSAGE);
                } else {
                    allShapesModel.removeElementAt(idx);
                    shapeCanvas.repaint();
                }
            }
        };
        delete.putValue(Action.MNEMONIC_KEY,KeyEvent.VK_D);

        controls.add(new JButton(addEllipse));
        controls.add(new JButton(addRectangle));
        controls.add(new JButton(addFace));
        controls.add(fontChooser);
        controls.add(new JButton(delete));

        try {
            ArrayList<Shape> shapes = deserializeShapes();
            for (Shape shape : shapes) {
                allShapesModel.addElement(shape);
            }
        } catch (Exception ex) {
            System.err.println("If first launch,this is as expected!");
            ex.printStackTrace();
        }
    }

    private void addShape(Shape shape) {
        allShapesModel.addElement(shape);
        int size = allShapesModel.getSize() - 1;
        shapeSelectionModel.addSelectionInterval(size,size);
    }

    class ShapeCanvas extends JPanel {

        ShapeCanvas() {
            setBackground(Color.WHITE);
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D) g;
            g2.setRenderingHints(renderingHints);
            Stroke stroke = new BasicStroke(1.5f);
            g2.setStroke(stroke);
            int idx = shapeSelectionModel.getMinSelectionIndex();
            Shape selectedShape = null;
            if (idx > -1) {
                selectedShape = allShapesModel.get(idx);
            }
            Enumeration en = allShapesModel.elements();
            while (en.hasMoreElements()) {
                Shape shape = (Shape) en.nextElement();
                if (shape.equals(selectedShape)) {
                    g2.setColor(new Color(0,255,191));
                } else {
                    g2.setColor(new Color(255,191));
                }
                g2.fill(shape);
                g2.setColor(new Color(0,224));
                g2.draw(shape);
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(500,300);
        }
    }

    public JComponent getUI() {
        return ui;
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                SerializeShapes se = new SerializeShapes();

                JFrame f = new JFrame("Serialize Shapes");
                f.addWindowListener(new SerializeWindowListener(se));
                f.setDefaultCloSEOperation(JFrame.DO_NOTHING_ON_CLOSE);
                f.setContentPane(se.getUI());
                f.setResizable(false);
                f.pack();
                f.setLocationByPlatform(true);
                f.setVisible(true);
            }
        };
        SwingUtilities.invokeLater(r);
    }

    public void serializeShapes() throws FileNotFoundException {
        ArrayList<Shape> shapes
                = new ArrayList<Shape>();
        Enumeration en = allShapesModel.elements();
        while (en.hasMoreElements()) {
            Shape shape = (Shape) en.nextElement();
            shapes.add(shape);
        }
        ShapeIO.serializeShapes(shapes,this.getClass());
        try {
            Desktop.getDesktop().open(
                    ShapeIO.getSerializeFile(this.getClass()));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public ArrayList<Shape> deserializeShapes() throws FileNotFoundException {
        return ShapeIO.deserializeShapes(this.getClass());
    }

    class ShapeListCellRenderer extends DefaultListCellRenderer {

        @Override
        public Component getListCellRendererComponent(
                JList<? extends Object> list,boolean cellHasFocus) {
            Component c = super.getListCellRendererComponent(list,cellHasFocus);
            JLabel l = (JLabel) c;
            Shape shape = (Shape) value;
            ShapeIcon icon = new ShapeIcon(shape,40);
            l.setIcon(icon);
            l.setText("");

            return l;
        }
    }

    class ShapeIcon implements Icon {

        Shape shape;
        int size;

        ShapeIcon(Shape shape,int size) {
            this.shape = shape;
            this.size = size;
        }

        @Override
        public void paintIcon(Component c,Graphics g,int x,int y) {
            Graphics2D g2 = (Graphics2D) g;
            g2.setRenderingHints(renderingHints);
            Rectangle bounds = shape.getBounds();
            int xOff = -bounds.x;
            int yOff = -bounds.y;
            double xRatio = (double) bounds.width / (double) size;
            double yRatio = (double) bounds.height / (double) size;
            double ratio = xRatio > yRatio ? xRatio : yRatio;
            AffineTransform scale = AffineTransform.getScaleInstance(1 / ratio,1 / ratio);
            AffineTransform shift = AffineTransform.getTranslateInstance(xOff,yOff);

            AffineTransform totalTransform = new AffineTransform();

            totalTransform.concatenate(scale);
            totalTransform.concatenate(shift);

            Area b = new Area(shape).createTransformedArea(totalTransform);
            bounds = b.getBounds();

            g2.setColor(Color.BLACK);
            g2.fill(b);
        }

        @Override
        public int getIconWidth() {
            return size;
        }

        @Override
        public int getIconHeight() {
            return size;
        }
    }
}

class SerializeWindowListener extends WindowAdapter {

    SerializeShapes serializeShapes;

    SerializeWindowListener(SerializeShapes serializeShapes) {
        this.serializeShapes = serializeShapes;
    }

    @Override
    public void windowClosing(WindowEvent e) {
        try {
            serializeShapes.serializeShapes();
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
            System.exit(1);
        }
        System.exit(0);
    }
}

ShapeIO

对/从XML执行I / O.

package serialize2d;

import java.awt.Shape;
import java.beans.*;
import java.io.*;
import java.util.ArrayList;

public class ShapeIO {

    /** Save the list of shapes to the file system. */
    public static void serializeShapes(
            ArrayList<Shape> shapes,Class serializeClass) 
            throws FileNotFoundException {
        File f = getSerializeFile(serializeClass);
        XMLEncoder xmle = new XMLEncoder(new FileOutputStream(f));

        ArrayList<PathBean> pathSegmentsCollection = new ArrayList<>();
        for (Shape shape : shapes) {
            ArrayList<PathSegment> pathSegments = 
                    BeanConverter.getSegmentsFromShape(shape);
            PathBean as = new PathBean(pathSegments);
            pathSegmentsCollection.add(as);
        }

        xmle.writeObject(pathSegmentsCollection);
        xmle.flush();
        xmle.close();
    }

    /** Load the list of shapes from the file system. */
    public static ArrayList<Shape> deserializeShapes(Class serializeClass) 
            throws FileNotFoundException {
        File f = getSerializeFile(serializeClass);
        XMLDecoder xmld = new XMLDecoder(new FileInputStream(f));
        ArrayList<PathBean> pathSegmentsCollection
                = (ArrayList<PathBean>) xmld.readObject();
        ArrayList<Shape> shapes = new ArrayList<Shape>();
        for (PathBean pathSegments : pathSegmentsCollection) {
            shapes.add(BeanConverter.getShapeFromSegments(pathSegments));
        }

        return shapes;
    }

    /** Provide an unique,reproducible & readable/writable path for a class. */
    public static File getSerializeFile(Class serializeClass) {
        File f = new File(System.getProperty("user.home"));
        String[] nameParts = serializeClass.getCanonicalName().split(".");

        f = new File(f,"java");
        for (String namePart : nameParts) {
            f = new File(f,namePart);
        }
        f.mkdirs();
        f = new File(f,nameParts[nameParts.length-1] + ".xml");

        return f;
    }
}

BeanConverter

从Shape获取PathIterator并将其转换为可序列化的bean.将bean转换回GeneralPath.

package serialize2d;

import java.awt.Shape;
import java.awt.geom.*;
import java.util.ArrayList;

/** Utility class to convert bean to/from a Shape. */
public class BeanConverter {

    /** Convert a shape to a serializable bean.  */
    public static ArrayList<PathSegment> getSegmentsFromShape(Shape shape) {
        ArrayList<PathSegment> shapeSegments = new ArrayList<PathSegment>();
        for (
                PathIterator pi = shape.getPathIterator(null); 
                !pi.isDone(); 
                pi.next()) {
            double[] coords = new double[6];
            int pathSegmentType = pi.currentSegment(coords);
            int windingRule = pi.getWindingRule();
            PathSegment as = new PathSegment(
                    pathSegmentType,windingRule,coords);
            shapeSegments.add(as);
        }
        return shapeSegments;
    }

    /** Convert a serializable bean to a shape.  */
    public static Shape getShapeFromSegments(PathBean shapeSegments) {
        GeneralPath gp = new GeneralPath();
        for (PathSegment shapeSegment : shapeSegments.getPathSegments()) {
            double[] coords = shapeSegment.getCoords();
            int pathSegmentType = shapeSegment.getPathSegmentType();
            int windingRule = shapeSegment.getWindingRule();
            gp.setWindingRule(windingRule);
            if (pathSegmentType == PathIterator.SEG_MOVETO) {
                gp.moveTo(coords[0],coords[1]);
            } else if (pathSegmentType == PathIterator.SEG_LINETO) {
                gp.lineTo(coords[0],coords[1]);
            } else if (pathSegmentType == PathIterator.SEG_QUADTO) {
                gp.quadTo(coords[0],coords[1],coords[2],coords[3]);
            } else if (pathSegmentType == PathIterator.SEG_CUBICTO) {
                gp.curveTo(
                        coords[0],coords[3],coords[4],coords[5]);
            } else if (pathSegmentType == PathIterator.SEG_CLOSE) {
                gp.closePath();
            } else {
                System.err.println("Unexpected value! " + pathSegmentType);
            }
        }
        return gp;
    }
}

PathBean

在可序列化的bean中存储路径段的集合.

package serialize2d;

import java.awt.geom.*;
import java.util.ArrayList;

/** PathBean stores the collection of PathSegment objects
 that constitute the path of a Shape. */
public class PathBean {

    public ArrayList<PathSegment> pathSegments;

    public PathBean() {}

    public PathBean(ArrayList<PathSegment> pathSegments) {
        this.pathSegments = pathSegments;
    }

    public ArrayList<PathSegment> getPathSegments() {
        return pathSegments;
    }

    public void setPathSegments(ArrayList<PathSegment> pathSegments) {
        this.pathSegments = pathSegments;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder("{");
        for (PathSegment pathSegment : pathSegments) {
            sb.append(" nt");
            sb.append(pathSegment.toString());
        }
        sb.append(" n");
        sb.append("}");
        return "PathSegments: " + sb.toString();
    }
}

PathSegment

存储整个路径的一部分的路径段.

package serialize2d;

import java.util.Arrays;

/** PathSegment bean stores the detail on one segment of the path
 that constitutes a Shape. */
public class PathSegment {

    public int pathSegmentType;
    public int windingRule;
    public double[] coords;

    public PathSegment() {}

    public PathSegment(int pathSegmentType,int windingRule,double[] coords) {
        this.pathSegmentType = pathSegmentType;
        this.windingRule = windingRule;
        this.coords = coords;
    }

    public int getPathSegmentType() {
        return pathSegmentType;
    }

    public void setPathSegmentType(int pathSegmentType) {
        this.pathSegmentType = pathSegmentType;
    }

    public int getWindingRule() {
        return windingRule;
    }

    public void setWindingRule(int windingRule) {
        this.windingRule = windingRule;
    }

    public double[] getCoords() {
        return coords;
    }

    public void setCoords(double[] coords) {
        this.coords = coords;
    }

    @Override
    public String toString() {
        String sC = (coords != null ? "" : Arrays.toString(coords));
        String s = String.format(
                "PathSegment: Path Segment Type:- %d t"
                + "Winding Rule:- %d tcoords:- %s",getPathSegmentType(),getWindingRule(),sC);
        return s;
    }
}

笔记

这意味着与抛光方法相反的概念证明.

> XML序列化数据变得真实快速,通常会被压缩. Zip压缩可能会使序列化对象或类文件的字节大小减少30-40%,但是可以减少80-95%的XML.在任何情况下,zip也适用于下一个点.
>对于我们希望提供序列化和恢复形状的项目类型,我们可能还要包括更多的形状细节(例如填充颜色或纹理,绘制颜色或笔画等)以及其他数据,如图像或字体.这也是Zip派上用场的地方,因为我们可以将它们全部放在同一个存档中,每个都具有最好的压缩级别(例如XML的标准,图像的标准).

可以从我的云端驱动器下载zip archive of the source files in this answer.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读