[英]Marshal save menu item of jlist to XML and unmarshal load menu items
我一直在这里进行研究,并一直在寻找解决问题的方法。 我是Java的新手,所以我不了解所有语法。 我正在尝试获取我的代码,以便从保存和加载菜单项的create方法转移项。 save事件处理程序应调用方法save()并将右侧面板中的零件列表保存到XML文件。 加载事件处理程序应调用方法load(),并应在右侧面板中显示未编组的数据。 我对JAXB或XML都不熟悉。 我试图看看是否有人做过类似的事情,但是我无法完成代码。 有人可以帮我吗? 以下是整个代码。 我已经找到了使它使用事件处理程序退出的解决方案,但是我被困于编组和解组保存和加载菜单项。
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
public class Window {
private final JFrame frame;
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
Window window = new Window();
window.frame.setVisible(true);
});
}
public Window() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
initialize();
}
public void initialize() {
//Creating the Panel for Menu Bar
JPanel panel = new JPanel();
panel.setBounds(0, 0, 434, 23);
frame.getContentPane().add(panel);
panel.setLayout(new BorderLayout(0, 0));
//Creating the Menu File Bar
JMenuBar bar = new JMenuBar();
panel.add(bar, BorderLayout.NORTH);
JMenu file = new JMenu("File");
JMenuItem load = new JMenuItem("Load");
JMenuItem save = new JMenuItem("Save");
JMenuItem exit = new JMenuItem("Exit");
file.add(load);
load.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event) {
}
});
file.add(save);
save.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event) {
}
});
file.add(exit);
exit.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event) {
System.exit(0);
}
});
bar.add(file);
//Populate Left List with part names
final DefaultListModel parts = new DefaultListModel();
parts.addElement("Case");
parts.addElement("Motherboard");
parts.addElement("CPU");
parts.addElement("GPU");
parts.addElement("PSU");
parts.addElement("RAM");
parts.addElement("HDD");
final JList leftList = new JList(parts);
leftList.setBounds(10, 26, 142, 224);
frame.getContentPane().add(leftList);
//create right list
final DefaultListModel partSelected = new DefaultListModel();
final JList rightList = new JList(partSelected);
rightList.setBounds(282, 26, 142, 224);
frame.getContentPane().add(rightList);
//add event to the button to move items from left list to right list
JButton btnNewButton = new JButton(">>");
btnNewButton.addActionListener((ActionEvent arg0) -> {
for (Object selectedValue : leftList.getSelectedValuesList()) {
partSelected.addElement(selectedValue);
parts.removeElement(selectedValue);
int iSelected = leftList.getSelectedIndex();
if (iSelected == -1) {
return;
}
}
});
btnNewButton.setBounds(172, 86, 89, 23);
frame.getContentPane().add(btnNewButton);
//Remove Button
JButton remove = new JButton("<<");
remove.addActionListener((ActionEvent arg0) -> {
for (Object selectedValue : rightList.getSelectedValuesList()) {
parts.addElement(selectedValue);
partSelected.removeElement(selectedValue);
int selected = rightList.getSelectedIndex();
if (selected == -1) {
return;
}
}
});
remove.setBounds(172, 140, 89, 23);
frame.getContentPane().add(remove);
}
}
好的,因此您首先需要了解JAXB是用于将对象与XML进行序列化(通过使用批注)的。
因此,您需要做的第一件事是对包含您的产品的对象进行序列化。 ListModel
似乎是一个完美的选择,除了它不是为任务设置的,它没有注释,JAXB可以通过该注释来决定应序列化或不序列化的内容
因此,我们需要创建一个...
@XmlRootElement
public static class ProductListModel extends AbstractListModel<String> {
private List<String> products;
public ProductListModel() {
products = new ArrayList<>(25);
}
@XmlElementWrapper
public List<String> getProducts() {
return products;
}
public void add(String product) {
products.add(product);
fireIntervalAdded(this, products.size() - 1, products.size() - 1);
}
public void remove(String product) {
int index = products.indexOf(product);
products.remove(product);
fireIntervalAdded(this, index, index);
}
@Override
public int getSize() {
return products.size();
}
@Override
public String getElementAt(int index) {
return products.get(index);
}
}
(现在,您可能会说像ArrayList
之类的东西可能会更好,但我想说这是在扩展类而几乎没有收获,或者在尝试找出如何序列化其缓冲区时可能会占用更多的工作)
接下来,我们需要访问initialize
方法外部的rightList
,因为您的load
和save
方法将需要此方法。 我们可以使用ListModel
,但是在加载它时,我们需要一些东西以任何方式将其应用...
//...
private JList rightList;
public void initialize() {
//...
final ProductListModel parts = new ProductListModel();
parts.add("Case");
parts.add("Motherboard");
parts.add("CPU");
parts.add("GPU");
parts.add("PSU");
parts.add("RAM");
parts.add("HDD");
leftList = new JList(parts);
leftList.setBounds(10, 26, 142, 224);
frame.getContentPane().add(leftList);
//create right list
final ProductListModel partSelected = new ProductListModel();
//JList rightList = new JList(partSelected);
rightList = new JList(partSelected);
这还将DefaultListModel
的使用更改为ProductListModel
。 从技术上讲,这仅对于rightList
是必需的,但是由于我已经更改了ListModel
的add
和remove
方法名称(这将导致您出现编译器错误,因此您需要更新这些名称),这只会使工作变得更轻松。
现在我们需要的只是save
和load
方法...
protected void save() {
ProductListModel model = (ProductListModel) rightList.getModel();
try {
File file = new File("Products.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(ProductListModel.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
// output pretty printed
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(model, file);
jaxbMarshaller.marshal(model, System.out);
} catch (JAXBException exp) {
exp.printStackTrace();
}
}
protected void load() {
try {
File file = new File("Products.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(ProductListModel.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
ProductListModel model = (ProductListModel) jaxbUnmarshaller.unmarshal(file);
rightList.setModel(model);
} catch (JAXBException exp) {
exp.printStackTrace();
}
}
您需要从注册到load
并save
JMenuItem
的ActionListener
调用该方法
看一下JAXB hello world示例 (我用来设计解决方案的示例 )和JAXB简介以获得更多详细信息。
您可能还想看看如何使用列表 , 如何使用滚动窗格以及在容器中布置组件以帮助改善UI
现在,当您加载ProductList
,您将需要弄清楚如何修改leftList
以删除现在显示在右侧的项目;)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.