gpt4 book ai didi

java - JComboBox 并不总是将值保存到 TableModel

转载 作者:行者123 更新时间:2023-12-02 01:43:44 30 4
gpt4 key购买 nike

我创建了一个包含人员列表的 JTable。一个 Person 总是可以包含另一个 Person(或者可能是它自己)。因此,用户可以单击该列,然后会出现一个 JComboBox。此 JComboBox 包含 JTable 的所有人员。

用户完成 JTable 编辑后,可以单击 JButton“保存”。在此示例中,它将仅将 TableModel 的值打印到控制台。

问题:最后的更改没有“转移”到 TableModel。
例如。用户为每一行选择 Kim。对于他来说,它看起来是正确的,但如果您单击该按钮,您将看到最后一行“Person”列的值仍然是 John。当用户单击另一列时,在更改第三列中的人员后,然后单击按钮,输出是正确的。

我认为我遗漏了一些东西,但我不知道问题出在哪里。

对于 JTable,我使用了本教程: https://www.codejava.net/java-se/swing/how-to-create-jcombobox-cell-editor-for-jtable

这是我的代码:

public class Person {
private String name;
private Person person;
private String job;

public Person(String name, String job) {
this.name = name;
this.job = job;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Person getPerson() {
return person;
}

public void setPerson(Person person) {
this.person = person;
}

public String getJob() {
return job;
}

public void setJob(String job) {
this.job = job;
}

}

public class PersonTable extends JTable {

private PersonTableModel tableModel;

public PersonTable(List<Person> listPerson) {
tableModel = new PersonTableModel(listPerson);
this.setModel(tableModel);
this.setDefaultRenderer(Person.class, new PersonCellRenderer());
this.setDefaultEditor(Person.class, new PersonCellEditor(listPerson));
}

public Set<Person> getAllPersons() {
Set<Person> set = new HashSet<Person>();
for (int i = 0; i < tableModel.getRowCount(); i++) {
set.add(tableModel.getPerson(i));
}
return set;
}

}

public class PersonCellEditor extends AbstractCellEditor
implements TableCellEditor, ActionListener {

private Person Person;
private List<Person> listPerson;

public PersonCellEditor(List<Person> listPerson) {
this.listPerson = listPerson;
}

@Override
public Object getCellEditorValue() {
return this.Person;
}

@Override
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column) {
if (value instanceof Person) {
this.Person = (Person) value;
}

JComboBox<Person> comboPerson = new JComboBox<Person>();
comboPerson.setRenderer(new PersonComboBoxRenderer());

for (Person aPerson : listPerson) {
comboPerson.addItem(aPerson);
}

comboPerson.setSelectedItem(Person);
comboPerson.addActionListener(this);

if (isSelected) {
comboPerson.setBackground(table.getSelectionBackground());
} else {
comboPerson.setBackground(table.getSelectionForeground());
}

return comboPerson;
}

@Override
public void actionPerformed(ActionEvent event) {
JComboBox<Person> comboPerson = (JComboBox<Person>) event.getSource();
this.Person = (Person) comboPerson.getSelectedItem();
}

}

public class PersonCellRenderer extends DefaultTableCellRenderer {

public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
if (value instanceof Person) {
Person Person = (Person) value;
setText(Person.getName());
}

if (isSelected) {
setBackground(table.getSelectionBackground());
} else {
setBackground(table.getSelectionForeground());
}

return this;
}

}

public class PersonTableModel extends AbstractTableModel {
private String[] columnNames = {"No.", "Name", "Person", "Job"};
private List<Person> listPerson = new ArrayList<>();

public PersonTableModel(List<Person> listPerson) {
this.listPerson.addAll(listPerson);
}

@Override
public int getColumnCount() {
return columnNames.length;
}

public String getColumnName(int column) {
return columnNames[column];
}

public Class getColumnClass(int column) {
return getValueAt(0, column).getClass();
}

@Override
public int getRowCount() {
return listPerson.size();
}

@Override
public void setValueAt(Object value, int rowIndex, int columnIndex) {
Person person = listPerson.get(rowIndex);

switch (columnIndex) {
case 1:
person.setName((String) value);
break;
case 2:
person.setPerson((Person) value);
break;
case 3:
person.setJob((String) value);
break;
}
}

@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Object returnValue = null;
Person person = listPerson.get(rowIndex);

switch (columnIndex) {
case 0:
returnValue = rowIndex + 1;
break;
case 1:
returnValue = person.getName();
break;
case 2:
returnValue = person.getPerson();
break;
case 3:
returnValue = person.getJob();
break;
}

return returnValue;
}

public Person getPerson(int row) {
return listPerson.get(row);
}

public boolean isCellEditable(int rowIndex, int columnIndex) {
return columnIndex > 0;
}

}

public class PersonComboBoxRenderer extends DefaultListCellRenderer {

@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if(value instanceof Person) {
Person p = (Person) value;
setText(p.getName());
}
return this;
}

}

public class JComboBoxTableCellEditorExample extends JFrame {

public JComboBoxTableCellEditorExample() {
super("JComboBox Cell Editor for JTable Demo");

List<Person> listPerson = new ArrayList<>();
Person p1 = new Person("John", "Developer");
Person p2 = new Person("Kim", "Designer");
Person p3 = new Person("Peter", "Manager");
p1.setPerson(p2);
p2.setPerson(p3);
p3.setPerson(p1);
listPerson.add(p1);
listPerson.add(p2);
listPerson.add(p3);

PersonTable table = new PersonTable(listPerson);

JScrollPane scrollpane = new JScrollPane(table);
scrollpane.setPreferredSize(new Dimension(400, 200));

add(scrollpane, BorderLayout.CENTER);

JButton buttonSave = new JButton("Save");
buttonSave.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
for (Person p : table.getAllPersons()) {
System.out.println(p.getName() + " --> " + p.getPerson().getName());
}
}
});

add(buttonSave, BorderLayout.PAGE_END);

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setLocationRelativeTo(null);
setVisible(true);
}

public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
ex.printStackTrace();
}

SwingUtilities.invokeLater(new Runnable() {

@Override
public void run() {
new JComboBoxTableCellEditorExample();
}
});
}

}

最佳答案

我已经测试了您的代码并解决了应用 camickr here 解释的解决方案的问题

camickr自己在这个entry中解释了您面临的问题。 。让我引用一段摘录

When editing a cell in a JTable the table doesn’t know when a user isfinished editing the cell. Therefore it is the users responsibility totell the table when to stop editing.

This is normally done by:

  • using the enter key
  • tabbing to the next cell
  • clicking on another cellwith the mouse

如果您编辑第三行 Person [第 2 列] 并立即按“保存”按钮,JTable 不会检测到您已完成对该单元格的编辑。这就是您获得的原因

Kim --> Kim
John --> Kim
Peter --> John

camickr 提供的解决方案之一是当您检测到“保存”按钮已被按下时强制停止编辑。只需更改您的按钮声明

    JButton buttonSave = new JButton("Save");
buttonSave.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
if (table.isEditing()) {
table.getCellEditor().stopCellEditing();
}

for (Person p : table.getAllPersons()) {
System.out.println(p.getName() + " --> " + p.getPerson().getName());
}
}
});

现在您应该获得所需的结果。

请注意,如果您稍微更改一下 PersonTable 类,在方法 getAllPersons 中将 Set 替换为 List,您将获得有序结果,从而提高控制台的可读性。

public class PersonTable extends JTable {

private PersonTableModel tableModel;

public PersonTable(List<Person> listPerson) {
tableModel = new PersonTableModel(listPerson);
setModel(tableModel);
setDefaultRenderer(Person.class, new PersonCellRenderer());
setDefaultEditor(Person.class, new PersonCellEditor(listPerson));
}

public List<Person> getAllPersons() {
List<Person> set = new ArrayList<Person>();

for (int i = 0; i < tableModel.getRowCount(); i++) {
set.add(tableModel.getPerson(i));
}

return set;
}

}

使用列表未进行任何更改的控制台输出

John --> Kim
Kim --> Peter
Peter --> John

关于java - JComboBox 并不总是将值保存到 TableModel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54036283/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com