我有一个JTable,其中包含渲染JPanel的单元格。问题是每次我更新模型时,JTable都不会触发。我目前的代码如下。我尝试了不同的东西,如table.validate()和table.repaint(),但仍然不刷新表。
我尝试通过执行table.setModel(newModel)来更改表的模型,但这完全消除了表(包括取消选择)。我希望该表在后台静默更新。
刷新代码在我的其他默认呈现的JTable上运行良好,但这不适用于这个特定的。
public class RoomViewTable2 {
JScrollPane hostPane;
public static JTable table;
public static DefaultTableModel model;
private static Timer refreshTimer;
public RoomViewTable2() {
}
public static JTable getRoomViewTable() {
model = new RoomRowTableModel(getFeeds());
table = new JTable(model);
table.setDefaultRenderer(TablePanelUI.class, new RoomRowCellRenderer());
table.setRowHeight(75);
runRefreshTimer();
return table;
}
public static ArrayList<TablePanelUI> getFeeds() {
ArrayList<TablePanelUI> feeds = new ArrayList<TablePanelUI>();
try {
DB.dbConnect();
String sql = "SELECT id, folio_id from room_view WHERE validity = '1'";
ResultSet rs = DB.con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE
, ResultSet.CONCUR_READ_ONLY)
.executeQuery(sql);
while (rs.next()) {
feeds.add(new TablePanelUI(new RoomInfo(rs.getInt(1))
, new FolioInfo(rs.getInt(2))));
}
rs.close();
DB.con.close();
} catch (Exception e) {
e.printStackTrace();
}
return feeds;
}
public static class RoomRowCellRenderer implements TableCellRenderer{
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
TablePanelUI room = (TablePanelUI) value;
JPanel panel = room.getPanel();
if (isSelected) {
panel.setBackground(table.getSelectionBackground());
}else{
panel.setBackground(table.getBackground());
}
return panel;
}
}
public static void refreshRoomView() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
model = new RoomRowTableModel(getFeeds());
model.fireTableDataChanged();
table.updateUI();
}
});
}
public static void runRefreshTimer() {
refreshTimer = new Timer(10000, new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
refreshRoomView();
System.out.println("UPDATING");
}
});
refreshTimer.start();
}
public static class RoomRowTableModel extends DefaultTableModel {
ArrayList<TablePanelUI> feeds;
public RoomRowTableModel(ArrayList<TablePanelUI> feeds) {
this.feeds = feeds;
}
public Class getColumnClass(int columnIndex) {
return TablePanelUI.class;
}
public int getColumnCount() {
return 1;
}
public String getColumnName(int columnIndex) {
return "Feed";
}
public int getRowCount() {
return (feeds == null) ? 0 : feeds.size();
}
public Object getValueAt(int rowIndex, int columnIndex) {
return (feeds == null) ? null : feeds.get(rowIndex);
}
public boolean isCellEditable(int columnIndex, int rowIndex) {
return true;
}
}
已编辑:上述问题的解决方案
正如@JB Nizet所建议的
1。)将setFeed()添加到DefaultTableModel
public void setFeed(ArrayList<TablePanelUI> feeds) {
this.feeds = feeds;
}
2.)刷新模型的Feed并解除事件
int selectedRow = table.getSelectedRow();
model.setFeed(getFeeds());
model.fireTableDataChanged();
table.updateUI();
if (selectedRow >= 0) {
table.setRowSelectionInterval(0, selectedRow);
}
答案 0 :(得分:2)
首先使用此模型创建模型和表格:
table --uses--> model --contains--> data
但是当你想刷新表时,不是更新这个模型并让模型触发一个事件,以便表重新读取模型并更新其视图,你创建另一个不同的模型,然后你创建这个新模型开火活动:
table --uses--> model --contains--> data
newModel --contains--> newData
但该表仍然使用以前的型号,因此没有收到任何事件。即使它确实如此,它仍然会重新读取它使用的模型的数据,而不是你创建的新模型。
您必须创建单个模型,更新它(即更改其Feed),然后从此模型中激发相应的事件。