Я создал JTable
со списком лиц.Человек всегда может содержать другого человека (или, возможно, самого себя).Таким образом, пользователь может щелкнуть столбец, и появится JComboBox
.Этот JComboBox содержит все лица JTable.
После того, как пользователь закончил редактирование JTable, он может нажать JButton
«Сохранить».В этом примере он просто выведет значения TableModel на консоль.
Проблема: последнее изменение не «передано» TableModel.Например, пользователь выбирает для каждой строки человека Кима.Для него это выглядит правильно, но если вы нажмете кнопку, вы увидите, что в последнем ряду значение столбца «Персона» по-прежнему равно Джону.Когда пользователь нажимает на другой столбец, после изменения лиц в третьем столбце, а затем нажимает кнопку, вывод выводится правильно.
Я думаю, что что-то упустил, но не могу понять, в чем проблема.
Для 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();
}
});
}
}