删除行后 JTable 未更新
JTable Not Updated After Deleting Row
I'm trying to update the rows of a JTable (or data?) after I perform a delete on a row, so when another row is selected the selected row can be edited.当前删除该行会将已删除行下方的行向上移动,但如果选择了该行号并尝试对其进行编辑 returns (JOptionPane),就好像没有选择任何内容一样。似乎没有“刷新”数据(?)。
这是一个 SCCE,希望有人可以 运行 它并指出问题。我试图尽可能地缩小它以便于 copy/paste:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.plaf.nimbus.NimbusLookAndFeel;
import javax.swing.table.*;
import java.util.*;
public class JTableTest4 extends JFrame implements ActionListener {
private JPanel dbOutputPanel = new JPanel();
private JTable dbOutputTable;
private JScrollPane dbOutputTableSP = new JScrollPane(dbOutputTable);
private JButton deleteButton = new JButton("Delete");
private JButton editButton = new JButton("Edit");
private JButton searchButton = new JButton("Search");
private JPanel south = new JPanel();
protected HashMap<Integer, Student> studentMap;
protected int studentIndex;
public JTableTest4() {
super("Student Database");
populateMap();
south.add(deleteButton);
south.add(editButton);
south.add(searchButton);
dbOutputTable = new JTable();
dbOutputTable.setFillsViewportHeight(true);
dbOutputTable.setPreferredScrollableViewportSize(new Dimension(450, 250));
dbOutputTableSP = new JScrollPane(dbOutputTable);
dbOutputPanel.add(dbOutputTableSP);
searchButton.addActionListener(this);
editButton.addActionListener(this);
deleteButton.addActionListener(this);
this.add(new JLabel("Welcome to " + getTitle(), JLabel.CENTER), BorderLayout.NORTH);
this.add(dbOutputPanel, BorderLayout.CENTER);
this.add(south, BorderLayout.SOUTH);
this.setSize(600, 500);
this.setResizable(false);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent event) {
Object source = event.getSource();
int selectedRow = dbOutputTable.getSelectedRow();
if (source == searchButton) {
displayTable();
} else if (source == editButton) {
Student student = studentMap.get(selectedRow);
displayTable();
if (student != null) {
System.out.println("\n" + student.toString() + "\n");
} else {
JOptionPane.showMessageDialog(this, "Please select a student to edit",
getTitle(), JOptionPane.INFORMATION_MESSAGE);
}
}
else if (source == deleteButton) {
System.out.println("Row count: " + ((DefaultTableModel) dbOutputTable.getModel()).getRowCount());
System.out.println("Selected Row: " + (selectedRow));
String[] options = {"Yes", "No"};
int result = JOptionPane.showOptionDialog(null, "Delete student from database?",
"Delete Student", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE,
null, options, options[1]);
if (result == JOptionPane.YES_OPTION) {
studentMap.remove(selectedRow);
((DefaultTableModel) dbOutputTable.getModel()).fireTableRowsDeleted(selectedRow, selectedRow);//not the issue
displayTable();
} else if (result == JOptionPane.NO_OPTION) {
}
}
displayTable();
}
public void populateMap() {
studentMap = new HashMap<>();
Student s1 = new Student("232", "john", "thomas", 22);
Student s2 = new Student("56", "bob", "doe", 23);
Student s3 = new Student("678", "sally", "smith", 24);
Student s4 = new Student("32", "chris", "johnson", 21);
Student s5 = new Student("12", "dsfg", "sgfsdg", 22);
studentMap.put(0, s1);
studentMap.put(1, s2);
studentMap.put(2, s3);
studentMap.put(3, s4);
studentMap.put(4, s5);
}
public TableModel toTableModel() {
System.out.println("Using toTableModel");
ArrayList<Student> studentList = new ArrayList<>();
for (Integer key : studentMap.keySet()) {
Student newStudent = (Student) studentMap.get(key);
studentList.add(newStudent);
}
DefaultTableModel tmodel = new DefaultTableModel(
new Object[]{"Id", "First", "Last", "Age"}, 0);
for (int i = 0; i < studentList.size(); i++) {
Student newStudent = studentList.get(i);
tmodel.addRow(new Object[] {newStudent.getStudentId(),
newStudent.getStudentFirstName(),
newStudent.getStudentLastName(),
newStudent.getStudentAge()});
}
return tmodel;
}
public void displayTable() {
dbOutputTable.setModel(toTableModel());
// dbOutputTable.revalidate();
}
public static void main(String[] args) throws Exception {
JTableTest4 test = new JTableTest4();
UIManager.setLookAndFeel(new NimbusLookAndFeel());
}
}
class Student {
private String studentId;
private String studentFirstName;
private String studentLastName;
private int studentAge;
public Student(String id, String first, String last, int age) {
this.studentId = id;
this.studentFirstName = first;
this.studentLastName = last;
this.studentAge = age;
}
public String getStudentId() {return studentId;}
public void setStudentId(String studentId) {this.studentId = studentId;}
public String getStudentFirstName() {return studentFirstName;}
public void setStudentFirstName(String studentFirstName) {this.studentFirstName = studentFirstName;}
public String getStudentLastName() {return studentLastName;}
public void setStudentLastName(String studentLastName) {this.studentLastName = studentLastName;}
public int getStudentAge() {return studentAge;}
public void setStudentAge(int studentAge) {this.studentAge = studentAge;}
@Override
public String toString() {
String st = "_id : " + this.studentId + "\n";
st += "First Name : " + this.studentFirstName + "\n";
st += "Last Name : " + this.studentLastName + "\n";
st += "Age : " + this.studentAge + "\n";
return st;
}
}
我在这里以各种形式看到了这个问题,它们都有点不同,通常都是相同的建议,我已经尝试了一些。您可以提供的任何帮助将不胜感激。谢谢!
您的“数据模型”和 TableModel
需要保持同步。您的 displayTable
方法令人担忧,并且表明对模型、视图和数据应如何管理的基本误解。
就我个人而言,我会使用 AbstractTable
将现有的 studentList
与 TableModel
更好地结合起来,而不是使用两种不同的模型,但这可能超出了问题。
下面是您的代码的略微修改版本,它使用 DefaultTableModel#removeRow
来更新 JTable
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.HashMap;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.plaf.nimbus.NimbusLookAndFeel;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
public class JTableTest4 extends JFrame implements ActionListener {
private JPanel dbOutputPanel = new JPanel();
private JTable dbOutputTable;
private JScrollPane dbOutputTableSP = new JScrollPane(dbOutputTable);
private JButton deleteButton = new JButton("Delete");
private JButton editButton = new JButton("Edit");
private JButton searchButton = new JButton("Search");
private JPanel south = new JPanel();
protected HashMap<Integer, Student> studentMap;
protected int studentIndex;
public JTableTest4() {
super("Student Database");
populateMap();
south.add(deleteButton);
south.add(editButton);
south.add(searchButton);
dbOutputTable = new JTable();
dbOutputTable.setModel(toTableModel());
dbOutputTable.setFillsViewportHeight(true);
dbOutputTable.setPreferredScrollableViewportSize(new Dimension(450, 250));
dbOutputTableSP = new JScrollPane(dbOutputTable);
dbOutputPanel.add(dbOutputTableSP);
searchButton.addActionListener(this);
editButton.addActionListener(this);
deleteButton.addActionListener(this);
this.add(new JLabel("Welcome to " + getTitle(), JLabel.CENTER), BorderLayout.NORTH);
this.add(dbOutputPanel, BorderLayout.CENTER);
this.add(south, BorderLayout.SOUTH);
this.setSize(600, 500);
this.setResizable(false);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent event) {
Object source = event.getSource();
int selectedRow = dbOutputTable.getSelectedRow();
if (source == searchButton) {
//displayTable();
} else if (source == editButton) {
Student student = studentMap.get(selectedRow);
//displayTable();
if (student != null) {
System.out.println("\n" + student.toString() + "\n");
} else {
JOptionPane.showMessageDialog(this, "Please select a student to edit",
getTitle(), JOptionPane.INFORMATION_MESSAGE);
}
} else if (source == deleteButton) {
System.out.println("Row count: " + ((DefaultTableModel) dbOutputTable.getModel()).getRowCount());
System.out.println("Selected Row: " + (selectedRow));
String[] options = {"Yes", "No"};
int result = JOptionPane.showOptionDialog(null, "Delete student from database?",
"Delete Student", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE,
null, options, options[1]);
if (result == JOptionPane.YES_OPTION) {
studentMap.remove(selectedRow);
((DefaultTableModel)dbOutputTable.getModel()).removeRow(selectedRow);
// ((DefaultTableModel) dbOutputTable.getModel()).fireTableRowsDeleted(selectedRow, selectedRow);//not the issue
// displayTable();
} else if (result == JOptionPane.NO_OPTION) {
}
}
//displayTable();
}
public void populateMap() {
studentMap = new HashMap<>();
Student s1 = new Student("232", "john", "thomas", 22);
Student s2 = new Student("56", "bob", "doe", 23);
Student s3 = new Student("678", "sally", "smith", 24);
Student s4 = new Student("32", "chris", "johnson", 21);
Student s5 = new Student("12", "dsfg", "sgfsdg", 22);
studentMap.put(0, s1);
studentMap.put(1, s2);
studentMap.put(2, s3);
studentMap.put(3, s4);
studentMap.put(4, s5);
}
public TableModel toTableModel() {
System.out.println("Using toTableModel");
ArrayList<Student> studentList = new ArrayList<>();
for (Integer key : studentMap.keySet()) {
Student newStudent = (Student) studentMap.get(key);
studentList.add(newStudent);
}
DefaultTableModel tmodel = new DefaultTableModel(
new Object[]{"Id", "First", "Last", "Age"}, 0);
for (int i = 0; i < studentList.size(); i++) {
Student newStudent = studentList.get(i);
tmodel.addRow(new Object[]{newStudent.getStudentId(),
newStudent.getStudentFirstName(),
newStudent.getStudentLastName(),
newStudent.getStudentAge()});
}
return tmodel;
}
public void displayTable() {
dbOutputTable.setModel(toTableModel());
// dbOutputTable.revalidate();
}
public static void main(String[] args) throws Exception {
JTableTest4 test = new JTableTest4();
UIManager.setLookAndFeel(new NimbusLookAndFeel());
}
}
class Student {
private String studentId;
private String studentFirstName;
private String studentLastName;
private int studentAge;
public Student(String id, String first, String last, int age) {
this.studentId = id;
this.studentFirstName = first;
this.studentLastName = last;
this.studentAge = age;
}
public String getStudentId() {
return studentId;
}
public void setStudentId(String studentId) {
this.studentId = studentId;
}
public String getStudentFirstName() {
return studentFirstName;
}
public void setStudentFirstName(String studentFirstName) {
this.studentFirstName = studentFirstName;
}
public String getStudentLastName() {
return studentLastName;
}
public void setStudentLastName(String studentLastName) {
this.studentLastName = studentLastName;
}
public int getStudentAge() {
return studentAge;
}
public void setStudentAge(int studentAge) {
this.studentAge = studentAge;
}
@Override
public String toString() {
String st = "_id : " + this.studentId + "\n";
st += "First Name : " + this.studentFirstName + "\n";
st += "Last Name : " + this.studentLastName + "\n";
st += "Age : " + this.studentAge + "\n";
return st;
}
}
更“高级”的实现
此示例使用自定义 TableModel
(名为 StudentTableModel
),它将 TableModel
包裹在基础数据模型周围并协调更新。
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.plaf.nimbus.NimbusLookAndFeel;
import javax.swing.table.AbstractTableModel;
public class JTableTest4 extends JFrame implements ActionListener {
private JPanel dbOutputPanel = new JPanel();
private JTable dbOutputTable;
private JScrollPane dbOutputTableSP = new JScrollPane(dbOutputTable);
private JButton deleteButton = new JButton("Delete");
private JButton editButton = new JButton("Edit");
private JButton searchButton = new JButton("Search");
private JPanel south = new JPanel();
public JTableTest4() {
super("Student Database");
south.add(deleteButton);
south.add(editButton);
south.add(searchButton);
dbOutputTable = new JTable();
dbOutputTable.setModel(makeModel());
dbOutputTable.setFillsViewportHeight(true);
dbOutputTable.setPreferredScrollableViewportSize(new Dimension(450, 250));
dbOutputTableSP = new JScrollPane(dbOutputTable);
dbOutputPanel.add(dbOutputTableSP);
searchButton.addActionListener(this);
editButton.addActionListener(this);
deleteButton.addActionListener(this);
this.add(new JLabel("Welcome to " + getTitle(), JLabel.CENTER), BorderLayout.NORTH);
this.add(dbOutputPanel, BorderLayout.CENTER);
this.add(south, BorderLayout.SOUTH);
this.setSize(600, 500);
this.setResizable(false);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent event) {
Object source = event.getSource();
int selectedRow = dbOutputTable.convertRowIndexToModel(dbOutputTable.getSelectedRow());
if (selectedRow < 0) {
return;
}
if (source == searchButton) {
//displayTable();
} else if (source == editButton) {
// Student student = studentMap.get(selectedRow);
// //displayTable();
// if (student != null) {
// System.out.println("\n" + student.toString() + "\n");
// } else {
// JOptionPane.showMessageDialog(this, "Please select a student to edit",
// getTitle(), JOptionPane.INFORMATION_MESSAGE);
// }
} else if (source == deleteButton) {
StudentTableModel model = (StudentTableModel)dbOutputTable.getModel();
model.removeRow(selectedRow);
// System.out.println("Row count: " + ((DefaultTableModel) dbOutputTable.getModel()).getRowCount());
// System.out.println("Selected Row: " + (selectedRow));
// String[] options = {"Yes", "No"};
// int result = JOptionPane.showOptionDialog(null, "Delete student from database?",
// "Delete Student", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE,
// null, options, options[1]);
// if (result == JOptionPane.YES_OPTION) {
// studentMap.remove(selectedRow);
// ((DefaultTableModel) dbOutputTable.getModel()).removeRow(selectedRow);
// // ((DefaultTableModel) dbOutputTable.getModel()).fireTableRowsDeleted(selectedRow, selectedRow);//not the issue
// // displayTable();
// } else if (result == JOptionPane.NO_OPTION) {
// }
}
//displayTable();
}
public StudentTableModel makeModel() {
System.out.println("Using toTableModel");
ArrayList<Student> studentList = new ArrayList<>();
studentList.add(new Student("232", "john", "thomas", 22));
studentList.add(new Student("56", "bob", "doe", 23));
studentList.add(new Student("678", "sally", "smith", 24));
studentList.add(new Student("32", "chris", "johnson", 21));
studentList.add(new Student("12", "dsfg", "sgfsdg", 22));
return new StudentTableModel(studentList);
}
public static void main(String[] args) throws Exception {
JTableTest4 test = new JTableTest4();
UIManager.setLookAndFeel(new NimbusLookAndFeel());
}
class Student {
private String studentId;
private String studentFirstName;
private String studentLastName;
private int studentAge;
public Student(String id, String first, String last, int age) {
this.studentId = id;
this.studentFirstName = first;
this.studentLastName = last;
this.studentAge = age;
}
public String getStudentId() {
return studentId;
}
public void setStudentId(String studentId) {
this.studentId = studentId;
}
public String getStudentFirstName() {
return studentFirstName;
}
public void setStudentFirstName(String studentFirstName) {
this.studentFirstName = studentFirstName;
}
public String getStudentLastName() {
return studentLastName;
}
public void setStudentLastName(String studentLastName) {
this.studentLastName = studentLastName;
}
public int getStudentAge() {
return studentAge;
}
public void setStudentAge(int studentAge) {
this.studentAge = studentAge;
}
@Override
public String toString() {
String st = "_id : " + this.studentId + "\n";
st += "First Name : " + this.studentFirstName + "\n";
st += "Last Name : " + this.studentLastName + "\n";
st += "Age : " + this.studentAge + "\n";
return st;
}
}
class StudentTableModel extends AbstractTableModel {
List<Student> studentList;
public StudentTableModel(List<Student> studentList) {
this.studentList = studentList;
}
@Override
public int getRowCount() {
return studentList.size();
}
@Override
public int getColumnCount() {
return 4;
}
@Override
public String getColumnName(int column) {
switch (column) {
case 0: return "ID";
case 1: return "First Name";
case 2: return "Last Name";
case 3: return "Age";
}
return "??";
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Student student = studentList.get(rowIndex);
switch (columnIndex) {
case 0: return student.studentId;
case 1: return student.studentFirstName;
case 2: return student.studentLastName;
case 3: return student.studentAge;
}
return null;
}
// This is a more advance topic then I want to get into here
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return false;
}
public Student studentAt(int row) {
return studentList.get(row);
}
public void removeRow(int index) {
studentList.remove(index);
fireTableRowsDeleted(index, index);
}
}
}
仔细查看 How to Use Tables 了解更多详情
I'm trying to update the rows of a JTable (or data?) after I perform a delete on a row, so when another row is selected the selected row can be edited.当前删除该行会将已删除行下方的行向上移动,但如果选择了该行号并尝试对其进行编辑 returns (JOptionPane),就好像没有选择任何内容一样。似乎没有“刷新”数据(?)。
这是一个 SCCE,希望有人可以 运行 它并指出问题。我试图尽可能地缩小它以便于 copy/paste:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.plaf.nimbus.NimbusLookAndFeel;
import javax.swing.table.*;
import java.util.*;
public class JTableTest4 extends JFrame implements ActionListener {
private JPanel dbOutputPanel = new JPanel();
private JTable dbOutputTable;
private JScrollPane dbOutputTableSP = new JScrollPane(dbOutputTable);
private JButton deleteButton = new JButton("Delete");
private JButton editButton = new JButton("Edit");
private JButton searchButton = new JButton("Search");
private JPanel south = new JPanel();
protected HashMap<Integer, Student> studentMap;
protected int studentIndex;
public JTableTest4() {
super("Student Database");
populateMap();
south.add(deleteButton);
south.add(editButton);
south.add(searchButton);
dbOutputTable = new JTable();
dbOutputTable.setFillsViewportHeight(true);
dbOutputTable.setPreferredScrollableViewportSize(new Dimension(450, 250));
dbOutputTableSP = new JScrollPane(dbOutputTable);
dbOutputPanel.add(dbOutputTableSP);
searchButton.addActionListener(this);
editButton.addActionListener(this);
deleteButton.addActionListener(this);
this.add(new JLabel("Welcome to " + getTitle(), JLabel.CENTER), BorderLayout.NORTH);
this.add(dbOutputPanel, BorderLayout.CENTER);
this.add(south, BorderLayout.SOUTH);
this.setSize(600, 500);
this.setResizable(false);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent event) {
Object source = event.getSource();
int selectedRow = dbOutputTable.getSelectedRow();
if (source == searchButton) {
displayTable();
} else if (source == editButton) {
Student student = studentMap.get(selectedRow);
displayTable();
if (student != null) {
System.out.println("\n" + student.toString() + "\n");
} else {
JOptionPane.showMessageDialog(this, "Please select a student to edit",
getTitle(), JOptionPane.INFORMATION_MESSAGE);
}
}
else if (source == deleteButton) {
System.out.println("Row count: " + ((DefaultTableModel) dbOutputTable.getModel()).getRowCount());
System.out.println("Selected Row: " + (selectedRow));
String[] options = {"Yes", "No"};
int result = JOptionPane.showOptionDialog(null, "Delete student from database?",
"Delete Student", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE,
null, options, options[1]);
if (result == JOptionPane.YES_OPTION) {
studentMap.remove(selectedRow);
((DefaultTableModel) dbOutputTable.getModel()).fireTableRowsDeleted(selectedRow, selectedRow);//not the issue
displayTable();
} else if (result == JOptionPane.NO_OPTION) {
}
}
displayTable();
}
public void populateMap() {
studentMap = new HashMap<>();
Student s1 = new Student("232", "john", "thomas", 22);
Student s2 = new Student("56", "bob", "doe", 23);
Student s3 = new Student("678", "sally", "smith", 24);
Student s4 = new Student("32", "chris", "johnson", 21);
Student s5 = new Student("12", "dsfg", "sgfsdg", 22);
studentMap.put(0, s1);
studentMap.put(1, s2);
studentMap.put(2, s3);
studentMap.put(3, s4);
studentMap.put(4, s5);
}
public TableModel toTableModel() {
System.out.println("Using toTableModel");
ArrayList<Student> studentList = new ArrayList<>();
for (Integer key : studentMap.keySet()) {
Student newStudent = (Student) studentMap.get(key);
studentList.add(newStudent);
}
DefaultTableModel tmodel = new DefaultTableModel(
new Object[]{"Id", "First", "Last", "Age"}, 0);
for (int i = 0; i < studentList.size(); i++) {
Student newStudent = studentList.get(i);
tmodel.addRow(new Object[] {newStudent.getStudentId(),
newStudent.getStudentFirstName(),
newStudent.getStudentLastName(),
newStudent.getStudentAge()});
}
return tmodel;
}
public void displayTable() {
dbOutputTable.setModel(toTableModel());
// dbOutputTable.revalidate();
}
public static void main(String[] args) throws Exception {
JTableTest4 test = new JTableTest4();
UIManager.setLookAndFeel(new NimbusLookAndFeel());
}
}
class Student {
private String studentId;
private String studentFirstName;
private String studentLastName;
private int studentAge;
public Student(String id, String first, String last, int age) {
this.studentId = id;
this.studentFirstName = first;
this.studentLastName = last;
this.studentAge = age;
}
public String getStudentId() {return studentId;}
public void setStudentId(String studentId) {this.studentId = studentId;}
public String getStudentFirstName() {return studentFirstName;}
public void setStudentFirstName(String studentFirstName) {this.studentFirstName = studentFirstName;}
public String getStudentLastName() {return studentLastName;}
public void setStudentLastName(String studentLastName) {this.studentLastName = studentLastName;}
public int getStudentAge() {return studentAge;}
public void setStudentAge(int studentAge) {this.studentAge = studentAge;}
@Override
public String toString() {
String st = "_id : " + this.studentId + "\n";
st += "First Name : " + this.studentFirstName + "\n";
st += "Last Name : " + this.studentLastName + "\n";
st += "Age : " + this.studentAge + "\n";
return st;
}
}
我在这里以各种形式看到了这个问题,它们都有点不同,通常都是相同的建议,我已经尝试了一些。您可以提供的任何帮助将不胜感激。谢谢!
您的“数据模型”和 TableModel
需要保持同步。您的 displayTable
方法令人担忧,并且表明对模型、视图和数据应如何管理的基本误解。
就我个人而言,我会使用 AbstractTable
将现有的 studentList
与 TableModel
更好地结合起来,而不是使用两种不同的模型,但这可能超出了问题。
下面是您的代码的略微修改版本,它使用 DefaultTableModel#removeRow
来更新 JTable
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.HashMap;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.plaf.nimbus.NimbusLookAndFeel;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
public class JTableTest4 extends JFrame implements ActionListener {
private JPanel dbOutputPanel = new JPanel();
private JTable dbOutputTable;
private JScrollPane dbOutputTableSP = new JScrollPane(dbOutputTable);
private JButton deleteButton = new JButton("Delete");
private JButton editButton = new JButton("Edit");
private JButton searchButton = new JButton("Search");
private JPanel south = new JPanel();
protected HashMap<Integer, Student> studentMap;
protected int studentIndex;
public JTableTest4() {
super("Student Database");
populateMap();
south.add(deleteButton);
south.add(editButton);
south.add(searchButton);
dbOutputTable = new JTable();
dbOutputTable.setModel(toTableModel());
dbOutputTable.setFillsViewportHeight(true);
dbOutputTable.setPreferredScrollableViewportSize(new Dimension(450, 250));
dbOutputTableSP = new JScrollPane(dbOutputTable);
dbOutputPanel.add(dbOutputTableSP);
searchButton.addActionListener(this);
editButton.addActionListener(this);
deleteButton.addActionListener(this);
this.add(new JLabel("Welcome to " + getTitle(), JLabel.CENTER), BorderLayout.NORTH);
this.add(dbOutputPanel, BorderLayout.CENTER);
this.add(south, BorderLayout.SOUTH);
this.setSize(600, 500);
this.setResizable(false);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent event) {
Object source = event.getSource();
int selectedRow = dbOutputTable.getSelectedRow();
if (source == searchButton) {
//displayTable();
} else if (source == editButton) {
Student student = studentMap.get(selectedRow);
//displayTable();
if (student != null) {
System.out.println("\n" + student.toString() + "\n");
} else {
JOptionPane.showMessageDialog(this, "Please select a student to edit",
getTitle(), JOptionPane.INFORMATION_MESSAGE);
}
} else if (source == deleteButton) {
System.out.println("Row count: " + ((DefaultTableModel) dbOutputTable.getModel()).getRowCount());
System.out.println("Selected Row: " + (selectedRow));
String[] options = {"Yes", "No"};
int result = JOptionPane.showOptionDialog(null, "Delete student from database?",
"Delete Student", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE,
null, options, options[1]);
if (result == JOptionPane.YES_OPTION) {
studentMap.remove(selectedRow);
((DefaultTableModel)dbOutputTable.getModel()).removeRow(selectedRow);
// ((DefaultTableModel) dbOutputTable.getModel()).fireTableRowsDeleted(selectedRow, selectedRow);//not the issue
// displayTable();
} else if (result == JOptionPane.NO_OPTION) {
}
}
//displayTable();
}
public void populateMap() {
studentMap = new HashMap<>();
Student s1 = new Student("232", "john", "thomas", 22);
Student s2 = new Student("56", "bob", "doe", 23);
Student s3 = new Student("678", "sally", "smith", 24);
Student s4 = new Student("32", "chris", "johnson", 21);
Student s5 = new Student("12", "dsfg", "sgfsdg", 22);
studentMap.put(0, s1);
studentMap.put(1, s2);
studentMap.put(2, s3);
studentMap.put(3, s4);
studentMap.put(4, s5);
}
public TableModel toTableModel() {
System.out.println("Using toTableModel");
ArrayList<Student> studentList = new ArrayList<>();
for (Integer key : studentMap.keySet()) {
Student newStudent = (Student) studentMap.get(key);
studentList.add(newStudent);
}
DefaultTableModel tmodel = new DefaultTableModel(
new Object[]{"Id", "First", "Last", "Age"}, 0);
for (int i = 0; i < studentList.size(); i++) {
Student newStudent = studentList.get(i);
tmodel.addRow(new Object[]{newStudent.getStudentId(),
newStudent.getStudentFirstName(),
newStudent.getStudentLastName(),
newStudent.getStudentAge()});
}
return tmodel;
}
public void displayTable() {
dbOutputTable.setModel(toTableModel());
// dbOutputTable.revalidate();
}
public static void main(String[] args) throws Exception {
JTableTest4 test = new JTableTest4();
UIManager.setLookAndFeel(new NimbusLookAndFeel());
}
}
class Student {
private String studentId;
private String studentFirstName;
private String studentLastName;
private int studentAge;
public Student(String id, String first, String last, int age) {
this.studentId = id;
this.studentFirstName = first;
this.studentLastName = last;
this.studentAge = age;
}
public String getStudentId() {
return studentId;
}
public void setStudentId(String studentId) {
this.studentId = studentId;
}
public String getStudentFirstName() {
return studentFirstName;
}
public void setStudentFirstName(String studentFirstName) {
this.studentFirstName = studentFirstName;
}
public String getStudentLastName() {
return studentLastName;
}
public void setStudentLastName(String studentLastName) {
this.studentLastName = studentLastName;
}
public int getStudentAge() {
return studentAge;
}
public void setStudentAge(int studentAge) {
this.studentAge = studentAge;
}
@Override
public String toString() {
String st = "_id : " + this.studentId + "\n";
st += "First Name : " + this.studentFirstName + "\n";
st += "Last Name : " + this.studentLastName + "\n";
st += "Age : " + this.studentAge + "\n";
return st;
}
}
更“高级”的实现
此示例使用自定义 TableModel
(名为 StudentTableModel
),它将 TableModel
包裹在基础数据模型周围并协调更新。
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.plaf.nimbus.NimbusLookAndFeel;
import javax.swing.table.AbstractTableModel;
public class JTableTest4 extends JFrame implements ActionListener {
private JPanel dbOutputPanel = new JPanel();
private JTable dbOutputTable;
private JScrollPane dbOutputTableSP = new JScrollPane(dbOutputTable);
private JButton deleteButton = new JButton("Delete");
private JButton editButton = new JButton("Edit");
private JButton searchButton = new JButton("Search");
private JPanel south = new JPanel();
public JTableTest4() {
super("Student Database");
south.add(deleteButton);
south.add(editButton);
south.add(searchButton);
dbOutputTable = new JTable();
dbOutputTable.setModel(makeModel());
dbOutputTable.setFillsViewportHeight(true);
dbOutputTable.setPreferredScrollableViewportSize(new Dimension(450, 250));
dbOutputTableSP = new JScrollPane(dbOutputTable);
dbOutputPanel.add(dbOutputTableSP);
searchButton.addActionListener(this);
editButton.addActionListener(this);
deleteButton.addActionListener(this);
this.add(new JLabel("Welcome to " + getTitle(), JLabel.CENTER), BorderLayout.NORTH);
this.add(dbOutputPanel, BorderLayout.CENTER);
this.add(south, BorderLayout.SOUTH);
this.setSize(600, 500);
this.setResizable(false);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent event) {
Object source = event.getSource();
int selectedRow = dbOutputTable.convertRowIndexToModel(dbOutputTable.getSelectedRow());
if (selectedRow < 0) {
return;
}
if (source == searchButton) {
//displayTable();
} else if (source == editButton) {
// Student student = studentMap.get(selectedRow);
// //displayTable();
// if (student != null) {
// System.out.println("\n" + student.toString() + "\n");
// } else {
// JOptionPane.showMessageDialog(this, "Please select a student to edit",
// getTitle(), JOptionPane.INFORMATION_MESSAGE);
// }
} else if (source == deleteButton) {
StudentTableModel model = (StudentTableModel)dbOutputTable.getModel();
model.removeRow(selectedRow);
// System.out.println("Row count: " + ((DefaultTableModel) dbOutputTable.getModel()).getRowCount());
// System.out.println("Selected Row: " + (selectedRow));
// String[] options = {"Yes", "No"};
// int result = JOptionPane.showOptionDialog(null, "Delete student from database?",
// "Delete Student", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE,
// null, options, options[1]);
// if (result == JOptionPane.YES_OPTION) {
// studentMap.remove(selectedRow);
// ((DefaultTableModel) dbOutputTable.getModel()).removeRow(selectedRow);
// // ((DefaultTableModel) dbOutputTable.getModel()).fireTableRowsDeleted(selectedRow, selectedRow);//not the issue
// // displayTable();
// } else if (result == JOptionPane.NO_OPTION) {
// }
}
//displayTable();
}
public StudentTableModel makeModel() {
System.out.println("Using toTableModel");
ArrayList<Student> studentList = new ArrayList<>();
studentList.add(new Student("232", "john", "thomas", 22));
studentList.add(new Student("56", "bob", "doe", 23));
studentList.add(new Student("678", "sally", "smith", 24));
studentList.add(new Student("32", "chris", "johnson", 21));
studentList.add(new Student("12", "dsfg", "sgfsdg", 22));
return new StudentTableModel(studentList);
}
public static void main(String[] args) throws Exception {
JTableTest4 test = new JTableTest4();
UIManager.setLookAndFeel(new NimbusLookAndFeel());
}
class Student {
private String studentId;
private String studentFirstName;
private String studentLastName;
private int studentAge;
public Student(String id, String first, String last, int age) {
this.studentId = id;
this.studentFirstName = first;
this.studentLastName = last;
this.studentAge = age;
}
public String getStudentId() {
return studentId;
}
public void setStudentId(String studentId) {
this.studentId = studentId;
}
public String getStudentFirstName() {
return studentFirstName;
}
public void setStudentFirstName(String studentFirstName) {
this.studentFirstName = studentFirstName;
}
public String getStudentLastName() {
return studentLastName;
}
public void setStudentLastName(String studentLastName) {
this.studentLastName = studentLastName;
}
public int getStudentAge() {
return studentAge;
}
public void setStudentAge(int studentAge) {
this.studentAge = studentAge;
}
@Override
public String toString() {
String st = "_id : " + this.studentId + "\n";
st += "First Name : " + this.studentFirstName + "\n";
st += "Last Name : " + this.studentLastName + "\n";
st += "Age : " + this.studentAge + "\n";
return st;
}
}
class StudentTableModel extends AbstractTableModel {
List<Student> studentList;
public StudentTableModel(List<Student> studentList) {
this.studentList = studentList;
}
@Override
public int getRowCount() {
return studentList.size();
}
@Override
public int getColumnCount() {
return 4;
}
@Override
public String getColumnName(int column) {
switch (column) {
case 0: return "ID";
case 1: return "First Name";
case 2: return "Last Name";
case 3: return "Age";
}
return "??";
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Student student = studentList.get(rowIndex);
switch (columnIndex) {
case 0: return student.studentId;
case 1: return student.studentFirstName;
case 2: return student.studentLastName;
case 3: return student.studentAge;
}
return null;
}
// This is a more advance topic then I want to get into here
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return false;
}
public Student studentAt(int row) {
return studentList.get(row);
}
public void removeRow(int index) {
studentList.remove(index);
fireTableRowsDeleted(index, index);
}
}
}
仔细查看 How to Use Tables 了解更多详情