Ron*_*Ron 2 java swing model jtable tablemodel
我有一个JTable被调用的transactionList,每一行代表一个Transaction,其中第一列保存实际Transaction对象,随后的每个列显示有关 的一些数据Transaction。
我不希望该Transaction对象向用户显示,因此我将其从以下位置中删除ColumnModel:
TableColumnModel cm = transactionList.getColumnModel();
cm.removeColumn(cm.getColumn(0));
transactionList.setColumnModel(cm);
Run Code Online (Sandbox Code Playgroud)
这非常有效,然后我可以Transaction使用以下方法检索所选内容:
(Transaction) transactionList.getModel().getValueAt(transactionList.getSelectedRow(), 0))
Run Code Online (Sandbox Code Playgroud)
当用户对表中的列进行排序时,问题就出现了,然后所选的行无法正确匹配。我通过更改上面的行来解决这个问题,以便我们直接从表中而不是从模型中获取所选行:
(Transaction) transactionList.getValueAt(transactionList.getSelectedRow(), 0));
Run Code Online (Sandbox Code Playgroud)
但现在 0 列不是我的隐藏Transaction对象,而只是它的第一个字段。
我也会尝试用另一种方式来解释。
在不允许对 JTable 列进行排序的情况下,这两个示例都有效:
1) 在第一列中显示 Transaction 对象(不要从 ColumnModel 中删除)
可以通过以下方式检索 Transaction 对象:
transactionList.getValueAt(transactionList.getSelectedRow(), 0));
Run Code Online (Sandbox Code Playgroud)
2) 在第一列中显示 Transaction 对象(从 ColumnModel 中删除)
可以通过以下方式检索 Transaction 对象:
transactionList.getModel().getValueAt(transactionList.getSelectedRow(), 0))
Run Code Online (Sandbox Code Playgroud)
如果我现在允许对列进行排序,#1 仍然有效。然而,方法 #2 现在将 JTable.getSelectedRow() 传递给 TableModel.getValueAt()。但这些索引不再相等,问题是 JTable 和 ColumnModel 不包含 Transaction 对象(只有 TableModel 包含)。
transactionList.getColumnCount(); //return 5
transactionList.getColumnModel().getColumnCount(); //return 5
transactionList.getModel().getColumnCount(); //returns 6
Run Code Online (Sandbox Code Playgroud)
我看到的一个可能的解决方案是当用户单击列标题时将 TableModel 与 JTable 一起排序。这可行吗?是否有更好的方法来实现此目标(将“隐藏”对象附加到 JTable 行)?
表模型
public class TransactionTableModel extends AbstractTableModel {
String[] columnNames = { "<Transaction_Object>", "Date", "Name",
"Hours", "Amount", "Notes" };
public TransactionTableModel() {
}
public String getColumnName(int col) {
return columnNames[col].toString();
}
public Class<?> getColumnClass(int col) {
switch (col) {
case 1:
return Calendar.class;
case 2:
return String.class;
}
}
public int getRowCount() {
return DB.getInstance().getTransactions().size();
}
public int getColumnCount() {
return columnNames.length;
}
public Object getValueAt(int row, int col) {
Transaction t = null;
t = DB.getInstance().getTransactionsChronological().get(row);
switch (col) {
case 0:
return t;
case 1:
return t.getDate();
case 2:
return t.getStudent.getName();
}
}
}
Run Code Online (Sandbox Code Playgroud)
MCVE
有一个隐藏的第一列,其值与第二列相匹配。对于未排序的 JTable,按钮会打印正确的值,但通过单击标题对列进行排序后,模型不同步。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
public class SwingTesting {
JFrame frame;
TablePane tablePane;
public SwingTesting() {
tablePane = new TablePane();
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JButton test = new JButton("Print hidden item");
test.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
printHiddenItem();
}
});
frame.add(tablePane);
frame.add(test, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
class TablePane extends JPanel {
private final JTable table;
private final TableModel tableModel;
private final ListSelectionModel listSelectionModel;
public TablePane() {
table = new JTable();
tableModel = createTableModel();
table.setModel(tableModel);
table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
table.setAutoCreateRowSorter(true);
table.add(table.getTableHeader(), BorderLayout.PAGE_START);
table.setFillsViewportHeight(true);
listSelectionModel = table.getSelectionModel();
table.setSelectionModel(listSelectionModel);
this.add(new JScrollPane(table));
testMethod();
}
private TableModel createTableModel() {
DefaultTableModel model = new DefaultTableModel(new Object[] {
"First", "Second", "Third" }, 0) {
};
addTableData(model);
return model;
}
private void addTableData(DefaultTableModel model) {
model.addRow(new Object[] { "ONE", "ONE", "2007" });
model.addRow(new Object[] { "TWO", "TWO", "2012" });
model.addRow(new Object[] { "THREE", "THREE", "2009" });
model.addRow(new Object[] { "FOUR", "FOUR", "2005" });
model.addRow(new Object[] { "FIVE", "FIVE", "2001" });
}
private void testMethod() {
TableColumnModel cm = table.getColumnModel();
cm.removeColumn(cm.getColumn(0));
table.setColumnModel(cm);
}
}
public void printHiddenItem() {
System.out.println(tablePane.table.getModel().getValueAt(tablePane.table.getSelectedRow(), 0));
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new SwingTesting();
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
要记住的一件事是 JTable 和 TableModel 有两个独立的坐标系统,即视图系统与模型系统:
JTable 有方法 ConvertRow/ColumnToView/Model 来回映射,用于访问所选(视图!)行的模型行的具体问题:
model.getValueAt(table.convertRowIndexToModel(table.getSelectedRow()), 0);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2652 次 |
| 最近记录: |