我一直在努力尝试使用 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 Container和 How to use Lists了解更多详情
关于java - 单击时 JList 显示旧值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20891355/