繁体   English   中英

将jlist的菜单项编组为XML并解组加载菜单项

[英]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 ,因为您的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);

这还将DefaultListModel的使用更改为ProductListModel 从技术上讲,这仅对于rightList是必需的,但是由于我已经更改了ListModeladdremove方法名称(这将导致您出现编译器错误,因此您需要更新这些名称),这只会使工作变得更轻松。

现在我们需要的只是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();
    }
}

您需要从注册到loadsave JMenuItemActionListener调用该方法

看一下JAXB hello world示例 (我用来设计解决方案的示例 )和JAXB简介以获得更多详细信息。

您可能还想看看如何使用列表如何使用滚动窗格以及在容器中布置组件以帮助改善UI

现在,当您加载ProductList ,您将需要弄清楚如何修改leftList以删除现在显示在右侧的项目;)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM