我一直在努力使用MVC
很难理解Swing
所以我决定尝试制作一个非常基本的项目,我认为我很接近,但现在JList
isn没有像我想象的那样做出反应,我没有看到它。可能累了,可能缺乏知识。可能两者都有。
我的视图类JList
反映了添加或删除Person,但是当我单击它时,它将恢复为旧值,根据控制台窗口 - 它甚至不再存在。视图类代码如下,整个项目可以找到here
我做错了什么?我是否能以一种好的方式“刷新”JList
?
这是我的观点类:
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));
}
}
}
}
任何帮助和/或见解都会像往常一样受到高度赞赏。
答案 0 :(得分:1)
假设您正在正确调用update方法,问题可能是z顺序问题,因为您正在使用布局管理器。
基本上可能发生的事情是当您添加新列表时,它实际上是在现有列表下面绘制的(之前已添加)
您应该根据需要使用适当的布局管理器或管理器,而不是使用null布局。这个旧的突出显示了多个pone被添加到屏幕的问题
此外,不是在模型更改时创建新的JList
,而只需更改当前列表模型,例如
listPersons.setModel(((PersonList)model).toArray());
这是Swing中MVC范例的核心......你不需要创建一个新视图,但可以简单地改变它的模型;)
请查看Laying Out Components Within a Container和How to use Lists了解详情