dev*_*ger 4 java swing jtable tablemodel
嗨,
我创建了我的TableModel,并希望在添加新行后刷新JTable.应该添加什么来监听"刷新"JTable?
public class MyTableModel implements TableModel {
private Set<TableModelListener> listeners = new HashSet<TableModelListener>();
//List<Staff> staffs = Factory.getInstance().getStaffDAO().getAllStaff();
private List<Staff> staffs;
public MyTableModel(List<Staff> staffs){
this.staffs = staffs;
}
@Override
public int getRowCount() {
return staffs.size();
}
@Override
public int getColumnCount() {
return 5;
}
@Override
public String getColumnName(int columnIndex) {
switch (columnIndex){
case 0:
return "First Name";
case 1:
return "Second Name";
case 2:
return "Date";
case 3:
return "Position";
case 4:
return "Salary";
}
return "";
}
@Override
public Class<?> getColumnClass(int columnIndex) {
return Object.class;
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return true;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Staff staff = staffs.get(rowIndex);
switch (columnIndex){
case 0:
return staff.getName();
case 1:
return staff.getSurname();
case 2:
return staff.getDate();
case 3:
return staff.getPosition();
case 4:
return staff.getSalary();
}
return "";
}
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
}
@Override
public void addTableModelListener(TableModelListener l) {
}
@Override
public void removeTableModelListener(TableModelListener l) {
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的添加行按钮的监听器:
@Override
public void actionPerformed(ActionEvent e) {
Staff staff = new Staff();
staff.setName(JOptionPane.showInputDialog("Enter First Name"));
staff.setSurname(JOptionPane.showInputDialog("Enter Second Name"));
staff.setDate(JOptionPane.showInputDialog("Enter Date"));
staff.setPosition(JOptionPane.showInputDialog("Enter Position"));
staff.setSalary(JOptionPane.showInputDialog("Enter Salary"));
try {
Factory.getInstance().getStaffDAO().addStaff(staff);
} catch (SQLException e1) {
e1.printStackTrace();
}
!!!Here should be some code that will be firing my table after adding new row!!!
}
Run Code Online (Sandbox Code Playgroud)
我试图在我的actionPerformed()中使用AbstractTableModel的方法firetabledatachanged(),但是在unluck中,它出现了ClassCastException.
更新1
WorkPlaceGui.java
public class WorkPlaceGui extends JFrame implements ActionListener {
AbstractTableModel model;
JTable jTable;
JScrollPane jScrollPane;
public WorkPlaceGui()throws SQLException{
List<Staff> staffs = Factory.getInstance().getStaffDAO().getAllStaff();
for(int i = 0; i < 0; i++) {
staffs.add(new Staff("First Name " + staffs.get(i).getName(), "Second Name " + staffs.get(i).getSurname(), "Date " + staffs.get(i).getDate(), "Position " + staffs.get(i).getPosition(), "Salary " + staffs.get(i).getSalary()));
}
model = new MyTableModel(staffs);
jTable = new JTable(model);
JButton jBtnAdd = new JButton("????????");
JButton jBtnDel = new JButton("???????");
JButton jBtnUpd = new JButton("????????");
JButton jBtnAdmin = new JButton("???????");
JPanel panelNorth = new JPanel();
JPanel panelCenter = new JPanel();
JPanel panelSouth = new JPanel();
jTable.setPreferredScrollableViewportSize(new Dimension(350, 150));
jScrollPane = new JScrollPane(jTable);
panelNorth.setLayout(new FlowLayout());
panelNorth.add(jBtnAdd);
panelNorth.add(jBtnDel);
panelNorth.add(jBtnUpd);
panelNorth.add(jBtnAdmin);
panelCenter.add(jScrollPane);
setLayout(new BorderLayout());
add(panelNorth, BorderLayout.NORTH);
add(panelCenter, BorderLayout.CENTER);
jBtnAdd.addActionListener(this);
setPreferredSize(new Dimension(550, 300));
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setTitle("Staff data base");
pack();
setVisible(true);
setLocationRelativeTo(null);
}
@Override
public void actionPerformed(ActionEvent e) {
Staff staff = new Staff();
staff.setName(JOptionPane.showInputDialog("Enter First Name"));
staff.setSurname(JOptionPane.showInputDialog("Enter Second Name"));
staff.setDate(JOptionPane.showInputDialog("Enter Date"));
staff.setPosition(JOptionPane.showInputDialog("Enter Position"));
staff.setSalary(JOptionPane.showInputDialog("Enter Salary"));
try {
Factory.getInstance().getStaffDAO().addStaff(staff);
} catch (SQLException e1) {
e1.printStackTrace();
}
model.fireTableDataChanged();
}
}
Run Code Online (Sandbox Code Playgroud)
MyTableModel.java
public class MyTableModel extends AbstractTableModel {
private List<Staff> staffs;
public MyTableModel(List<Staff> staffs){
this.staffs = staffs;
}
@Override
public int getRowCount() {
return staffs.size();
}
@Override
public int getColumnCount() {
return 5;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Staff staff = staffs.get(rowIndex);
switch (columnIndex){
case 0:
return staff.getName();
case 1:
return staff.getSurname();
case 2:
return staff.getDate();
case 3:
return staff.getPosition();
case 4:
return staff.getSalary();
}
return "";
}
}
Run Code Online (Sandbox Code Playgroud)
Mad*_*mer 12
你已经很难完成了.
首先,你已直接实现TableModel,其次你未能实现监听器要求......
相反,尝试从AbstractTableModel替代扩展,其中已经包括监听器注册和通知的实现.
您需要提供一种方法,允许您向表模型添加行.在此方法中,您需要使用fireTableRowsInserted将使用模型通知任何表的方法,即添加了新行...
这是非常非常基本的例子.它的唯一目的是展示其使用fireTableRowsInserted.它使用Swing Timer每125毫秒添加一个新行,直到你杀死它;)
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.AbstractTableModel;
public class DynamicTable {
public static void main(String[] args) {
new DynamicTable();
}
public DynamicTable() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
final MyTableModel model = new MyTableModel();
JTable table = new JTable(model);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new JScrollPane(table));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
Timer timer = new Timer(125, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
model.addRow();
}
});
timer.start();
}
});
}
public class MyTableModel extends AbstractTableModel {
private List<String[]> rows;
public MyTableModel() {
rows = new ArrayList<>(25);
}
@Override
public int getRowCount() {
return rows.size();
}
@Override
public int getColumnCount() {
return 4;
}
@Override
public Class<?> getColumnClass(int columnIndex) {
return String.class;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
String[] row = rows.get(rowIndex);
return row[columnIndex];
}
public void addRow() {
int rowCount = getRowCount();
String[] row = new String[getColumnCount()];
for (int index = 0; index < getColumnCount(); index++) {
row[index] = rowCount + "x" + index;
}
rows.add(row);
fireTableRowsInserted(rowCount, rowCount);
}
}
}
Run Code Online (Sandbox Code Playgroud)
由于您的表模型由其自己支持List,因此它与您的工厂没有任何关联.它不知道何时添加或删除对象.这意味着您有责任更新模型:
public class MyTableModel extends AbstractTableModel {
private List<Staff> staffs;
public MyTableModel(List<Staff> staffs){
this.staffs = staffs;
}
@Override
public int getRowCount() {
return staffs.size();
}
@Override
public int getColumnCount() {
return 5;
}
public void add(Staff staff) {
int size = getSize();
staffs.add(staff);
fireTableRowsInserted(size, size);
}
public void remove(Staff staff) {
if (staffs.contains(staff) {
int index = stafff.indexOf(staff);
staffs.remove(staff);
fireTableRowsDeleted(index, index);
}
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Staff staff = staffs.get(rowIndex);
switch (columnIndex){
case 0:
return staff.getName();
case 1:
return staff.getSurname();
case 2:
return staff.getDate();
case 3:
return staff.getPosition();
case 4:
return staff.getSalary();
}
return "";
}
}
Run Code Online (Sandbox Code Playgroud)
你的actionPerformed:
@Override
public void actionPerformed(ActionEvent e) {
Staff staff = new Staff();
staff.setName(JOptionPane.showInputDialog("Enter First Name"));
staff.setSurname(JOptionPane.showInputDialog("Enter Second Name"));
staff.setDate(JOptionPane.showInputDialog("Enter Date"));
staff.setPosition(JOptionPane.showInputDialog("Enter Position"));
staff.setSalary(JOptionPane.showInputDialog("Enter Salary"));
try {
Factory.getInstance().getStaffDAO().addStaff(staff);
((MyTableModel)model).add(staff);
} catch (SQLException e1) {
e1.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
您的类MyTableModel实现TableModel,但没有事件处理机制将模型连接到视图.而是扩展AbstractTableModel,如此处和此处所示.AbstractTableModel提供了fireTable*所需的方法.
public void setValueAt(Object value, int row, int col) {
data[row][col] = value;
fireTableCellUpdated(row, col);
}
Run Code Online (Sandbox Code Playgroud)