How to make xml schema relate(link) to JTable,xml java?

前端 未结 1 1614
死守一世寂寞
死守一世寂寞 2020-12-20 04:18

Here you can see my application: \"enter

So what i need to do:

<
1条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2020-12-20 04:57

    "Here is writing to xml file:" ---- "And here loading my xml file:"

    Why are you using DOM to read and write the xml, when you are already using JAXB Mapping. If you are doing the mapping correctly 1, it's just a matter of using the Marshaller and Unmarshaller to write and read, respectively. Make sure to look at those API links yo see example usage. It's only around 5 lines of code to handle each operaion.

    (1) Please see the JAXB tutorial for more info about JAXB mapping.

    Also, you can just create your own AbstractTableModel and unmarshal and marshal straight to and from the table model. This is probably the most effective way to keep everything sync. Create a class Auto to represent each row, and a class AutoModel, that will be the root element in the xml document, as well as the TableModel for the JTable. Something like:

    Auto class

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "Auto", propOrder = {
            "id", "VIN", "Make", "Model", "Year", "Description", "Cost"
    })
    public class Auto {
        @XmlElement(name = "id")
        Integer id;
        @XmlElement(name = "VIN")
        String VIN;
        @XmlElement(name = "Make")
        String Make;
        @XmlElement(name = "Model")
        String Model;
        @XmlElement(name = "Year")
        Integer Year;
        @XmlElement(name = "Description")
        String Description;
        @XmlElement(name = "Cost")
        Float Cost;
    
        // === DON'T FORGET YOUR GETTERS and SETTERS
    }
    

    AutoModel class

    @XmlRootElement(name = "AutoList")
    public class AutoModel extends AbstractTableModel {
        String[] columnNames = {"VIN", "Make", "Model", "Year"};
    
        @XmlElement(name = "Auto")
        protected List autos;
    
        public AutoModel() {
            autos = new ArrayList();
        }
    
        @Override
        public int getRowCount() {
            return autos.size();
        }
    
        @Override
        public int getColumnCount() {
            return columnNames.length;
        }
    
        @Override
        public String getColumnName(int columnIndex) {
            return columnNames[columnIndex];
        }
    
        @Override
        public boolean isCellEditable(int row, int col) {
            return false;
        }
    
        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            Auto auto = autos.get(rowIndex);
            Object value = null;
            switch (columnIndex) {
                case 0 : value = auto.getVIN(); break;
                case 1 : value = auto.getMake(); break;
                case 2 : value = auto.getModel(); break;
                case 3 : value = auto.getYear(); break;
            }
            return value;
        }
    }
    

    Test, using this xml file

    
    
        
            1
            123456788910FASDE
            Mercedes
            CL 550
            2012
            Hello World
            80000.00
        
    
    

    enter image description here

    import java.awt.Dimension;
    import java.io.File;
    import javax.swing.*;
    import javax.xml.bind.*;
    
    public class TestTableMarshall {
    
        private static final String INPUT_FILE = "src/table/autos.xml";
        private static final String OUTPUT_FILE = "src/table/autos1.xml";
    
        public static void main(String[] args) throws Exception {
            AutoModel model = unmarshal(INPUT_FILE);
            JTable table = new JTable(model) {
                @Override
                public Dimension getPreferredScrollableViewportSize() {
                    return getPreferredSize();
                }
            };
            JOptionPane.showMessageDialog(null, new JScrollPane(table));
            marshal(model, OUTPUT_FILE);
    
        }
    
        private static void marshal(AutoModel model, String file) throws Exception {
            JAXBContext context = JAXBContext.newInstance(AutoModel.class);
            Marshaller marshaller = context.createMarshaller();
            File f= new File(file);
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(model, f);
        }
    
        private static AutoModel unmarshal(String file) throws Exception {
            JAXBContext context = JAXBContext.newInstance(AutoModel.class);
            Unmarshaller unmarshaller = context.createUnmarshaller();
            AutoModel model = (AutoModel)unmarshaller.unmarshal(new File(file));
            return model;
        }
    }
    

    As far the the AutoModel goes, it only works for your first table. You will need to create another model for your repairs table. Also, the model, currently only offered read-only. You will need to add other functionality to say add a row and set individual values.

    Here are some resources to look at:

    • How to Use Tables: Creating a Table Model
    • JAXB Specification toturial

    NOTE: With the JAXB annotations above you can create the schema, and you you want to validate the xml against it, you could just set the schema when you unmarshal. Something like:

    private static AutoModel unmarshal(String file) throws Exception {
        JAXBContext context = JAXBContext.newInstance(AutoModel.class);
        Unmarshaller unmarshaller = context.createUnmarshaller();
        SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        Schema schema = factory.newSchema(new File("src/table/autos.xsd"));
        unmarshaller.setSchema(schema);
        AutoModel model = (AutoModel)unmarshaller.unmarshal(new File(file));
        return model;
    }
    

    0 讨论(0)
提交回复
热议问题