在这里你可以看到我的申请:
那么我需要做什么:
我不知道如何通过代码将 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,那么只需分别使用 Marshaller
和 Unmarshaller
进行写入和读取即可。确保查看那些 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>
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/