java - 单击时 JList 显示旧值

标签 java swing model-view-controller jlist

我一直在努力尝试使用 Swing 来理解 MVC,所以我决定尝试制作一个非常基本的项目,我想我已经很接近了,但现在JList 的 react 并不像我想象的那样,而且我没有看到它。可能是累了,也可能是缺乏知识。可能两者都有。

我的 View 类JList反射(reflect)了添加或删除一个人,但是当我单击它时,它会恢复为旧值,根据控制台窗口,该值甚至不再存在。 View 类代码如下,整个项目可以参见here

我做错了什么?我是否以一种好的方式“刷新”JList

这是我的 View 类:

public class PersonView extends JFrame implements Observer, ActionListener {

    private static final long serialVersionUID = 1L;
    private JPanel contentPane;
    private JTextField textFieldFirstName;
    private JTextField textFieldLastName;
    private JButton btnAddPerson;
    private JButton btnDeletePerson;
    private JList listPersons;
    private Observable model;
    private ActionListener listener;

    public Observable getModel() {
        return model;
    }

    public void setModel(Observable model) {
        this.model = null;
        this.model = model;
    }

    public ActionListener getActionListener() {
        return listener;
    }

    public void setActionListener(ActionListener listener) {

        if (listener != null)
            this.listener = listener;
    }

    /**
     * Create the frame.
     */
    public PersonView(Observable model) {

        if (model != null)
            this.setModel(model);

        setResizable(false);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);

        JLabel lblFirstName = new JLabel("First Name");
        lblFirstName.setBounds(10, 11, 68, 14);
        contentPane.add(lblFirstName);

        JLabel lblLastName = new JLabel("Last Name");
        lblLastName.setBounds(10, 36, 68, 14);
        contentPane.add(lblLastName);

        textFieldFirstName = new JTextField();
        textFieldFirstName.setBounds(80, 8, 142, 20);
        contentPane.add(textFieldFirstName);
        textFieldFirstName.setColumns(10);

        textFieldLastName = new JTextField();
        textFieldLastName.setBounds(80, 33, 142, 20);
        contentPane.add(textFieldLastName);
        textFieldLastName.setColumns(10);

        btnAddPerson = new JButton("Add Person");
        btnAddPerson.setActionCommand("Add");
        btnAddPerson.addActionListener(this);
        btnAddPerson.setBounds(232, 7, 192, 46);
        contentPane.add(btnAddPerson);

        listPersons = new JList(((PersonList)model).toArray());
        listPersons.setBounds(10, 61, 414, 150);
        contentPane.add(listPersons);

        btnDeletePerson = new JButton("Delete Selected Person(s)");
        btnDeletePerson.setActionCommand("Delete");
        btnDeletePerson.addActionListener(this);
        btnDeletePerson.setBounds(10, 222, 414, 29);
        contentPane.add(btnDeletePerson);
    }

    @Override
    public void update(Observable changedModel, Object arg1) {

        if (changedModel != null) {

            PersonList personList = (PersonList)changedModel;

            //for debugging purposes
            StringBuilder builder = new StringBuilder();
            builder.append(personList.getPersonList().size() + " ( ");

            for(Person p : personList.getPersonList()) {

                builder.append(p.toString() + " ");

            }

            builder.append(")");

            System.out.println(builder.toString());

            setModel(changedModel);

            listPersons = new JList(((PersonList)model).toArray());
            listPersons.setBounds(10, 61, 414, 150);
            contentPane.add(listPersons);
            listPersons.repaint();
        }

    }

    @Override
    public void actionPerformed(ActionEvent e) {

        if (e.getSource() == btnAddPerson) {

            if(textFieldFirstName.getText().length() > 0 && textFieldLastName.getText().length() > 0) {

                Person p = new Person(textFieldFirstName.getText(),
                        textFieldLastName.getText());
                listener.actionPerformed(new PersonActionEvent(e.getSource(), e
                        .getID(), e.getActionCommand(), p));

            }

        }

        if(e.getSource() == btnDeletePerson) {

            ArrayList<Person> selectedPersons = new ArrayList<Person>(listPersons.getSelectedValuesList());

            for(Person p : selectedPersons) {

                listener.actionPerformed(new PersonActionEvent(e.getSource(), e
                        .getID(), e.getActionCommand(), p));

            }
        }

    }

}

像往常一样,非常感谢任何帮助和/或见解。

最佳答案

假设您正确调用了更新方法,则问题可能是 z 顺序问题,因为您正在使用布局管理器。

基本上可能发生的情况是,当您添加新列表时,它实际上是在现有列表(之前添加的)下方绘制的

您应该根据需要使用适当的布局管理器,而不是使用空布局。这个旧版本强调了将多个电话添加到屏幕的问题

此外,当模型更改时,无需创建新的 JList,只需更改当前的列表模型,例如

listPersons.setModel(((PersonList)model).toArray());

这是 Swing 中 MVC 范例的核心...事实上,您不需要创建新 View ,而只需更改其模型即可;)

看看Laying Out Components Within a ContainerHow to use Lists了解更多详情

关于java - 单击时 JList 显示旧值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20891355/

相关文章:

java - 在 Jlist 中选择多个项目

java - 从spring mvc中的ajax请求中检索包含名称值对的数组

c# - 如何通过代码在运行时添加迁移

Java 重绘问题 - 每次移动都会看到椭圆

java - 在 Eclipse 中将图像添加到 JPanel

java - 在最短时间内进行多次 API 调用并返回组合响应

java - 使用我的 JAVA 代码获取多个 JFrame

java - Java 中的工具提示管理器

java - 如何将数字分成多行?

java - 将 Delphi App 迁移到 Java 或 Web App