我在初始创建框架时创建JTable
,但创建一个我扩展的空AbstractTableModel
。然后,用户必须从JComboBox
中选择一些内容,并且用户可以预览处理该指定选择的消息。
单击预览按钮时,我使用新数据创建一个新的AbstractTableModel
,并将该模型设置为新创建的JTable对象。完成后,我致电AbstractTableModel.fireTableDataChanged
,JTable.repaint()
,JTable.validate()
JFrame.repaint()
,JFrame.validate()
。
通过所有这些调用,我仍然无法使用新数据刷新JTable
。
我的JFrame
与JTable
:
public class StudentMessageViewer extends JFrame implements ActionListener {
final String CMD_DELETE = "CMD_DELETE";
final String CMD_DUMP = "CMD_DUMP";
final String CMD_MOVE = "CMD_MOVE";
final String CMD_PREVIEW = "CMD_PREVIEW";
private Students students;
private JComboBox<String> Names;
private TableModel Model;
public Selector(Students students) {
super("Main");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(new Dimension(700, 800));
setContentPane(getMainPanel());
setLocationRelativeTo(null);
setVisible(true);
}
private JPanel getMainPanel() {
JPanel main = new JPanel();
main.add(getSelectorPanel());
main.add(getTablePanel());
main.add(getButtonPanel());
return main;
}
private JPanel getSelectorPanel() {
JPanel main = new JPanel();
main.setLayout(new BoxLayout(main, BoxLayout.PAGE_AXIS));
FlowLayout flowLayout = new FlowLayout(FlowLayout.RIGHT);
main.setMaximumSize(new Dimension(450, 180));
Names = new JComboBox<String>(students.getNames());
JPanel NamesPanel = new JPanel();
NamesPanel.add(new JLabel("Name: "));
NamesPanel.add(Names);
main.add(NamesPanel);
return main;
}
private JPanel getTablePanel() {
JPanel main = new JPanel();
this.Model = new Model(new Object[0][4]);
this.MessagesTable = new JTable(this.Model);
TableColumn column = this.MessagesTable.getColumnModel().getColumn(0);
column.setPreferredWidth(20);
this.MessagesTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
this.MessagesTable.setSelectionBackground(getBackground());
this.MessagesTable.setSelectionForeground(getForeground());
main.add(new JScrollPane(this.MessagesTable));
return main;
}
private JPanel getButtonPanel() {
JPanel main = new JPanel(new FlowLayout(FlowLayout.RIGHT));
JButton btnDelete = new JButton("Delete");
JButton btnDump = new JButton("Dump");
JButton btnMove = new JButton("Move");
JButton btnPreview = new JButton("Preview");
btnDelete.setActionCommand(CMD_DELETE);
btnDump.setActionCommand(CMD_DUMP);
btnMove.setActionCommand(CMD_MOVE);
btnPreview.setActionCommand(CMD_PREVIEW);
btnDelete.addActionListener(this);
btnDump.addActionListener(this);
btnMove.addActionListener(this);
btnPreview.addActionListener(this);
main.add(btnDelete);
main.add(btnDump);
main.add(btnMove);
main.add(btnPreview);
this.getRootPane().setDefaultButton(btnPreview);
return main;
}
private void setTableData() {
Object data[][] = students.Select(Names.getSelectedItem().toString());
this.Model = new Model(data);
this.MessagesTable = new JTable(this.Model);
TableColumn column = this.MessagesTable.getColumnModel().getColumn(0);
column.setPreferredWidth(20);
this.MessagesTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
this.MessagesTable.setSelectionBackground(getBackground());
this.MessagesTable.setSelectionForeground(getForeground());
((AbstractTableModel) this.MessagesTable.getModel()).fireTableDataChanged();
this.MessagesTable.repaint();
this.repaint();
this.validate();
}
@Override
public void actionPerformed(ActionEvent event) {
String actionCmd = event.getActionCommand();
if(actionCmd.equals(CMD_DELETE))
System.out.println("DELETE");
else if(actionCmd.equals(CMD_DUMP))
System.out.println("DUMP");
else if(actionCmd.equals(CMD_MOVE))
System.out.println("MOVE");
else if(actionCmd.equals(CMD_PREVIEW))
setTableData();
}
}
我延长TableModel
的{{1}}课程:
AbstractTableModel
答案 0 :(得分:0)
所以我明白了。在setTableData()
类的StudentMessageViewer
方法中,我创建了一个全新的TableModel
对象和一个全新的JTable
对象,但是将这两个新对象分配给原始变量。所以我可能不得不做repaint()
或validate()
,但我无法理解。
但要修复它,我所做的就是创建一个全新的TableModel
对象,并使用JTable.setModel()
替换旧的TableModel
。
以下是修改过的方法:
private void setTableData() {
Object data[][] = students.Select(Names.getSelectedItem().toString());
this.Model = new Model(data);
TableColumn column = this.MessagesTable.getColumnModel().getColumn(0);
column.setPreferredWidth(20);
this.MessagesTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
this.MessagesTable.setSelectionBackground(getBackground());
this.MessagesTable.setSelectionForeground(getForeground());
this.MessagesTable.setModel(this.MyModel);
}
现在我可以多次更新表格了。
答案 1 :(得分:0)
AbstractTableModel支持表在其上注册自己的侦听器,以响应内容更改。但是AbstractTableModel
它不知道基础数据何时实际上变得不同 - 这已经完全在您的代码中。
当您知道数据现在不同时,尝试从模型中调用fireTableDataChanged
或模型(更糟糕的样式),或者对于有限范围的已知更改,更不愿意像fireTableRowsUpdated
那样。