更新滚动窗格的模型不会更新窗口

时间:2016-02-28 12:40:20

标签: java swing

使用javax.swing,我创建了一个显示列表的窗口。 此列表有两个按钮,允许删除或添加列表中显示的商店项目。商店商品存储在文件中。 我想在单击这些按钮时使用该列表,列表会通过列出其指定目录中的所有文件来更新自身(我需要这个方法而不是直接使用model.remove()直接修改列表。) 但是,当我执行model = new DefaultListModel()时,列表根本不会自行更新。 下面是显示商店项目列表的面板代码。

public class ShopWindowPanel extends JPanel
{
    private UserInterface window;
    private JList<String> jList;
    private DefaultListModel<String> model;
    private JButton addButton;
    private JButton deleteButton;
    private ArrayList<ShopItem> arrayList;
    private JScrollPane jScrollPane;

    /**
     * Constructor method.
     * @param window The window linked to the shop window panel. It is used for error pop-ups.
     */
    public ShopWindowPanel(UserInterface window) {
        this.window = window;
        initializePanel();
    }

    /**
     * This method initializes the panel.
     */
    public void initializePanel()
    {
        initializeButtons();
        initializeScrollPane();

        add(jScrollPane);

        //setting up the layout of the panel
        GroupLayout gl = new GroupLayout(this);
        this.setLayout(gl);

        gl.setAutoCreateContainerGaps(true);
        gl.setAutoCreateGaps(true);

        gl.setHorizontalGroup(gl.createParallelGroup(CENTER)
                .addComponent(jScrollPane)
                .addGroup(gl.createParallelGroup()
                        .addComponent(addButton)
                        .addComponent(deleteButton)
        ));

        gl.setVerticalGroup(gl.createSequentialGroup()
                .addComponent(jScrollPane)
                .addGroup(gl.createSequentialGroup()
                        .addComponent(addButton)
                        .addComponent(deleteButton)
        ));

        gl.linkSize(addButton, deleteButton);

        window.pack();
    }

    /**
     * This method initializes the buttons.
     */
    public void initializeButtons() {

        addButton = new JButton("Add");
        deleteButton = new JButton("Delete");

        addButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {

                String text = JOptionPane.showInputDialog("Add a new item and its price in pound (item name, price");

                try
                {
                    String[] itemDetails = text.split(", ");
                    ShopItem shopItemToAdd = new ShopItem();
                    shopItemToAdd.setName(itemDetails[0]);
                    shopItemToAdd.setPrice(Integer.parseInt(itemDetails[1]));
                    shopItemToAdd.save(); //create a new file
                    initializeScrollPane(); //supposed to update the scroll pane
                }
                catch(Exception exception)
                {

                    JOptionPane.showMessageDialog(window.getContentPane(), "An error has happened!" + exception.getClass() + ": " + exception.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
                }
            }
        });

        deleteButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent event) {

                ListSelectionModel selmodel = jList.getSelectionModel();
                int index = selmodel.getMinSelectionIndex();
                if (index >= 0) {
                    arrayList.get(index).delete(); //delete the file
                    initializeScrollPane(); //supposed to update the scroll pane
                }
            }

        });
    }

    /**
     * This method initializes the list of the items.
     */
    public void initializeScrollPane() {
        //listing all shop items
        model = new DefaultListModel<String>();
        File shopItemFileFolder = new File(ShopItem.shopItemsFolder);
        File[] shopItemsFiles = shopItemFileFolder.listFiles();
        arrayList = new ArrayList<ShopItem>();
        for(int i = 0; i<shopItemsFiles.length; i++)
        {
            try
            {
                ShopItem currentlyProcessedShopItem = new ShopItem();
                currentlyProcessedShopItem.load(shopItemsFiles[i].getName());

                model.addElement(currentlyProcessedShopItem.getName() + ": £" + (float) currentlyProcessedShopItem.getPrice()/100);
                arrayList.add(currentlyProcessedShopItem);
            }
            catch(Exception e)
            {
                System.err.println("A problem has happened with an item.");
            }
        }

        jList = new JList<>(model);
        jList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

        jScrollPane = new JScrollPane(jList);
    }
}

2 个答案:

答案 0 :(得分:1)

创建一个单独的方法,它不仅仅生成ListModel ...

public ListModel<String> initializeListModel() {
    //listing all shop items
    model = new DefaultListModel<String>();
    File shopItemFileFolder = new File(ShopItem.shopItemsFolder);
    File[] shopItemsFiles = shopItemFileFolder.listFiles();
    arrayList = new ArrayList<ShopItem>();
    for (int i = 0; i < shopItemsFiles.length; i++) {
        try {
            ShopItem currentlyProcessedShopItem = new ShopItem();
            currentlyProcessedShopItem.load(shopItemsFiles[i].getName());

            model.addElement(currentlyProcessedShopItem.getName() + ": £" + (float) currentlyProcessedShopItem.getPrice() / 100);
            arrayList.add(currentlyProcessedShopItem);
        } catch (Exception e) {
            System.err.println("A problem has happened with an item.");
        }
    }
    return model;
}

public void initializeScrollPane() {
    jList = new JList<>(model);
    jList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

    jScrollPane = new JScrollPane(jList);
}

然后在按钮的ActionListener中,调用此方法并将结果应用到JList ...

    addButton.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {

            String text = JOptionPane.showInputDialog("Add a new item and its price in pound (item name, price");

            try {
                String[] itemDetails = text.split(", ");
                shopItemToAdd.setName(itemDetails[0]);
                shopItemToAdd.setPrice(Integer.parseInt(itemDetails[1]));
                shopItemToAdd.save(); //create a new file
                jList.setModel(initializeListModel());
            } catch (Exception exception) {

                JOptionPane.showMessageDialog(ShopWindowPanel.this, "An error has happened!" + exception.getClass() + ": " + exception.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
            }
        }
    });

    deleteButton.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent event) {

            ListSelectionModel selmodel = jList.getSelectionModel();
            int index = selmodel.getMinSelectionIndex();
            if (index >= 0) {
                jList.setModel(initializeListModel());
            }
        }

    });

答案 1 :(得分:0)

看起来要更新滚动条,我们必须跟踪模型字段,而不是重新初始化它。因此,我们必须使用相同的模型对象及其方法。一种解决方案可能是:

/**
 * This method initializes the list of the items.
 */
public void initializeModel() {
    try
    {
        model.removeAllElements();
    }
    catch(NullPointerException exception)
    {
        //putting store items in the field model
        model = new DefaultListModel<String>();
    }

    try
    {
        ShopWindow.update();
    }
    catch(Exception e)
    {
        JOptionPane.showMessageDialog(window, "Problem updating the list of shop items!", "Error", JOptionPane.ERROR_MESSAGE);
        System.exit(0);
    }

    for(int i = 0; i<ShopWindow.getList().size(); i++)
    {
        try
        {
            model.addElement(ShopWindow.getItem(i).getName() + ": £" + (float) ShopWindow.getItem(i).getPrice()/100);
        }
        catch(Exception e)
        {
            System.err.println("A problem has happened with an item.");
        }
    }
}

/**
 * Initialize the scroll pane.
 */
public void initializeScrollPane()
{
    initializeModel();
    jList = new JList<String>(model);
    jList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

    jScrollPane = new JScrollPane(jList);
}