元帅JList中的菜单项保存到XML和反编组负载菜单项(Marshal save menu item

2019-10-24 03:11发布

我已经在这里做研究,并一直在寻找一个解决问题的办法。 我是新来的Java,所以我不知道所有的语法。 我试图让我的代码传递从创建用于保存和加载菜单项方法项目。 保存事件处理程序应该调用保存(方法),并在右侧面板中保存零件列表到一个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);
}
}

Answer 1:

好了,所以你首先要明白,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可能会更好,但我要说这是扩展类很少或没有增益,当你试图将可能占了很多工作,并弄清楚如何序列化的缓冲区)

接下来,我们需要访问rightList的外initialize方法,因为你的loadsave方法会想这个。 我们可以使用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);

这也改变了使用的DefaultListModelProductListModel 。 从技术上讲,这只是需要rightList ,但因为我已经改变了addremove的方法名称ListModel (这将导致你一个编译器错误,那么你将需要更新的),它只是使生活更轻松。

现在我们需要的是saveload方法...

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

你需要从调用ActionListener的注册到你的loadsave JMenuItem小号

看看JAXB Hello World示例 (这在我以前设计的解决方案),并介绍JAXB的更多细节。

你可能也想看看如何使用列表 , 如何使用滚动窗格和布放组件内的容器 ,以帮助提高你的UI

现在,当你加载ProductList ,你需要弄清楚如何修改leftList删除现在出现在右边的项目;)



文章来源: Marshal save menu item of jlist to XML and unmarshal load menu items