java - 如何使 xml 模式与 JTable、xml java 相关(链接)?

标签 java swing jaxb xsd jtable

在这里你可以看到我的申请: enter image description here

那么我需要做什么:

我不知道如何通过代码将 xml 模式与所有类型(int、string、float)的 JTable 链接起来。比如说 Year 是 int 类型,在模式中是 int,我如何链接它?我不知道英文链接或关联如何。 在这个应用程序中,我将所有数据写入 xml 文件,当应用程序加载时,它从 xml 文件加载所有数据。

我在这里创建 xml 模式:

      public void CreateSchema(String FileName){

        file=FileName;
        JAXBContext jc;
        try {
            jc = JAXBContext.newInstance(XmlSchemaType.class);

                jc.generateSchema(new SchemaOutputResolver() {

                    @Override
                    public javax.xml.transform.Result createOutput(String namespaceURI, String suggestedFileName)throws IOException {
                        suggestedFileName=file+".xsd";
                        return new StreamResult(suggestedFileName);
                    }

                });
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JAXBException e) {
            e.printStackTrace();
        }

  }

这里是所有类型:

   import javax.xml.bind.annotation.XmlAccessType;
   import javax.xml.bind.annotation.XmlAccessorType;
   import javax.xml.bind.annotation.XmlAttribute;
   import javax.xml.bind.annotation.XmlElement;
   import javax.xml.bind.annotation.XmlRootElement;

   @XmlAccessorType(XmlAccessType.FIELD)
   @XmlRootElement(name = "Auto")
   public class XmlSchemaType {
    row[] Row;
   }


   class row {
    @XmlAttribute
    byte ID;

    @XmlElement
    String VIN;
    @XmlElement
    String Make;
    @XmlElement
    String Model;
    @XmlElement
    int Year;
    @XmlElement
    String Description;
    @XmlElement
    float Cost;
   }

这里是写入xml文件:

public void CreateXml(JTable tb,JTable tb2,String FileName){
      try {

        file=FileName;
        DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder = docFactory.newDocumentBuilder();


        Document doc = docBuilder.newDocument();
        Element rootElement = doc.createElement("Auto");
        doc.appendChild(rootElement);


        int i=0,j=0,k=0;

        while (i<tb.getRowCount()){

            j=0;
            Element rows = doc.createElement("Row");
            rootElement.appendChild(rows);

            Attr attr = doc.createAttribute("id");
            attr.setValue((i+1)+"");
            rows.setAttributeNode(attr);

            //Pirma lentele
            while (j<tb.getColumnCount()-1){

                Element element = doc.createElement(tb.getTableHeader().getColumnModel().getColumn(j).getHeaderValue()+"");
                element.appendChild(doc.createTextNode(tb.getModel().getValueAt(i, j)+""));
                rows.appendChild(element);

                j++;
            }

            //Antra lentele
            j=2;//pirmu lauku nereikia
            while (j<tb2.getColumnCount()-1){
                        Element element2 = doc.createElement(tb2.getTableHeader().getColumnModel().getColumn(j).getHeaderValue()+"");
                        element2.appendChild(doc.createTextNode(tb2.getModel().getValueAt(i, j)+""));
                        rows.appendChild(element2); 
                        if (j==2){
                                tb2.getModel().setValueAt(tb.getModel().getValueAt(i, 0),i,1);  

                        }

                j++;
            }



            i++;
        }

        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        DOMSource source = new DOMSource(doc);
        StreamResult result;
        try {
        FileOutputStream fileOutputStream = null;

        fileOutputStream = new FileOutputStream(
                new File(file+".xml"));


        result = new StreamResult(fileOutputStream);//new FileOutputStream(file+".xml"));
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");//new line... kad butu naujoje eiluteje
        transformer.transform(source, result);
        try {
            fileOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }


      } catch (ParserConfigurationException pce) {
        pce.printStackTrace();
      } catch (TransformerException tfe) {
        tfe.printStackTrace();
      }
      //file.renameTo(FileName+".xml");

   }

在这里加载我的 xml 文件:

    public void PopulateDataSet(JTable tb,JTable tb2,String FileName){


      file=FileName;
      File f= new File(file+".xml");
      if (f.exists()){ 
          try {
          DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(f);

            doc.getDocumentElement().normalize();

            NodeList nList = doc.getElementsByTagName("Row");
            for (int temp = 0; temp < nList.getLength(); temp++) {

                Node nNode = nList.item(temp);


                if (nNode.getNodeType() == Node.ELEMENT_NODE) {

                    Element eElement = (Element) nNode;

                    DefaultTableModel model = (DefaultTableModel) tb.getModel();
                    model.addRow(new Object[] { "", "","","","Delete" });
                    tb.getModel().setValueAt(eElement.getElementsByTagName("VIN").item(0).getTextContent(),temp, 0);
                    tb.getModel().setValueAt(eElement.getElementsByTagName("Make").item(0).getTextContent(),temp, 1);
                    tb.getModel().setValueAt(eElement.getElementsByTagName("Make").item(0).getTextContent(),temp, 2);
                    tb.getModel().setValueAt(eElement.getElementsByTagName("Year").item(0).getTextContent(),temp, 3);
                    tb.getModel().setValueAt("Delete",temp, 4);

                    DefaultTableModel model2 = (DefaultTableModel) tb2.getModel();
                    model2.addRow(new Object[] { (tb2.getRowCount()+1), "","","","Delete" });
                     tb2.getModel().setValueAt(eElement.getElementsByTagName("VIN").item(0).getTextContent(),temp, 1);
                    tb2.getModel().setValueAt(eElement.getElementsByTagName("Description").item(0).getTextContent(),temp, 2);
                    tb2.getModel().setValueAt(eElement.getElementsByTagName("Cost").item(0).getTextContent(),temp, 3);
                    tb2.getModel().setValueAt("Delete",temp, 4);

                }

            }

          } catch (Exception e) {
                e.printStackTrace();
                }
      }
      if (!f.exists()){ 
          CreateXml(tb,tb2,file);
          CreateSchema(file); 
      }


  }

但是如何将xml shema与JTable、xml一起使用呢?

最佳答案

“这里正在写入 xml 文件:” ---- “这里正在加载我的 xml 文件:”

当您已经在使用 JAXB 映射时,为什么还要使用 DOM 来读取和写入 xml。如果您正确地进行了映射 1,那么只需分别使用 MarshallerUnmarshaller 进行写入和读取即可。确保查看那些 API 链接以查看示例用法。只需大约 5 行代码即可处理每个操作。

(1)有关 JAXB 映射的更多信息,请参阅 JAXB tutorial

此外,您可以创建自己的 AbstractTableModel 并直接对表模型进行解码和编码。这可能是保持一切同步的最有效方法。创建一个 Auto 类来表示每一行,以及一个 AutoModel 类,它将成为 xml 文档中的根元素,以及 TableModel 用于 JTable。像这样的东西:

自动

@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

@XmlRootElement(name = "AutoList")
public class AutoModel extends AbstractTableModel {
    String[] columnNames = {"VIN", "Make", "Model", "Year"};

    @XmlElement(name = "Auto")
    protected List<Auto> autos;

    public AutoModel() {
        autos = new ArrayList<Auto>();
    }

    @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;
    }
}

测试,使用这个xml文件

<?xml version="1.0" encoding="UTF-8"?>
<AutoList>
    <Auto>
        <id>1</id>
        <VIN>123456788910FASDE</VIN>
        <Make>Mercedes</Make>
        <Model>CL 550</Model>
        <Year>2012</Year>
        <Description>Hello World</Description>
        <Cost>80000.00</Cost>
    </Auto>
</AutoList>

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;
    }
}

AutoModel 而言,它只适用于您的第一个表。您将需要为您的维修表创建另一个模型。此外,该模型目前仅提供只读。您将需要添加其他功能来添加一行并设置单独的值。

这里有一些资源可供查看:


注意: 使用上面的 JAXB 注释,您可以创建模式,并且您想要根据它验证 xml,您可以在解码时设置模式。像这样的东西:

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;
}

关于java - 如何使 xml 模式与 JTable、xml java 相关(链接)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25963403/

相关文章:

java - JDBC中CreateStatement和PreparedStatement的区别

java - DNA序列的计算

java - 扫描仪跳过输入,可能有空格?

java - 为什么相同的字体在从 Netbeans 运行的 Java 应用程序和从 Jar 运行的 Java 应用程序中看起来不同?

enums - OSGi 依赖 hell : ClassNotFoundException: org. eclipse.persistence.internal.jaxb.WrappedValue

Javafx 将舞台/场景保存到文件中

ant - schemagen ant 任务忽略 package-info.java

java文件阅读器奇怪的输出

java - 在 javafx 中 Swing JTextPane

java - DocumentFilter 不监听变化怎么办?