我有一个JTable
,其创建如下,默认为空模型。
如果我通过文本文件(CSV)的外部处理更改了该数据模型,并使用RosterTable.setModel(...)
重置它,则TAB和Shift + TAB的标准键绑定将丢失。 TableModel
的更改非常标准,并在下面列出。
因此症状:全新的RosterTable
按预期执行,这意味着TAB将一个单元格向右移动,Shift + TAB将一个单元格向左移动并且两者都包裹到表行末尾的下一行/上一行。调用setModel()
后,TAB和Shift + TAB根本不再起作用。
设置InputMap
后,为什么TableModel
会发生变化?
NOTABLY:同一应用程序中的其他表通过使用序列化对象在实例化时加载其表。这些表也可以使用TAB和Shift + TAB键正常运行。更改表中的数据"即时"通过手动编辑似乎也不会影响键绑定。使用setModel
时,它似乎只显示错误。
RosterTable = new javax.swing.JTable();
RosterTable.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
{null, null, null, null, null, null, null, null},
{null, null, null, null, null, null, null, null},
{null, null, null, null, null, null, null, null},
...
},
new String [] {
"Callsign", "Close Time", "Notes", "Precedence", "Dest RI", "List Time", "Status", "Sent Time"
}
) {
Class[] types = new Class [] {
java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class
};
public Class getColumnClass(int columnIndex) {
return types [columnIndex];
}
});
RosterTable.setFillsViewportHeight(true);
RosterTable.setRowSelectionAllowed(false);
RosterTable.getTableHeader().setReorderingAllowed(false);
RosterScrollPane.setViewportView(RosterTable);
RosterTable.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_INTERVAL_SELECTION);
setRosterTableColumWidths(); // to resize columns to preferred widths
RosterTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
RosterTable.setGridColor(java.awt.Color.DARK_GRAY);
RosterTable.setShowGrid (true);
然后,当需要以批发方式更改表数据时,完成此操作的代码如下所示。第一个语句是FileChooser
打开操作的输出的接收者。 EMPTY
是一个静态的空字符串,如果不是很明显的话。
File f = fc.getSelectedFile();
String lineIn = null;
int count = -1;
Vector<Vector> data = new Vector<>();
Vector<String> row = null;
String[] tokens = null;
String delim = ",";
try {
BufferedReader br = new BufferedReader(new FileReader(f));
// skip all data before the roster itself
while ((lineIn = br.readLine()) != null) {
// call is the start of the header text line
if (lineIn.startsWith("NCS:")) {
break;
}
}
// now process all roster lines until we get to BT
while ((lineIn = br.readLine()) != null) {
if (lineIn.startsWith("BT")) {
// we found the end of the data
break;
}
count++;
row = new Vector<>();
tokens = lineIn.split(delim);
if (tokens.length > 0) {
for (String token : tokens) {
row.add(token.equals(EMPTY) ? null : token);
}
} else {
for (int i = 0; i < 8; i++) {
row.add(null);
}
}
data.add(row);
}
br.close();
// now fill the rest of the rows with nulls so
// empty rows may be filled by the user in the UI
while (count < 100) {
row = new Vector<>();
for (int i = 0; i < 8; i++) {
row.add(null);
}
data.add(row);
count++;
}
} catch (FileNotFoundException ex) {
Logger.getLogger(StationManager.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(StationManager.class.getName()).log(Level.SEVERE, null, ex);
}
// reload the column labels from existing
Vector<String> colsV = new Vector<>();
TableModel tcm = RosterTable.getModel();
for (int i = 0; i < 8; i++) {
colsV.add((String) tcm.getColumnName(i));
}
TableModel tm = new DefaultTableModel(data, colsV);
RosterTable.setModel(tm);
setRosterTableColumWidths();
此方法完成后,表模型是正确的,但TAB,Shift + TAB和ENTER不再与首次初始化表模型时相同。 TAB,Shift + TAB和ENTER仅将突出显示的单元格置于编辑模式。箭头键正常工作。文本也可以按正常方式键入任何单元格。
JTable
是否关心我使用Vector
代替String[]
等建立新模型?对我来说听起来不合逻辑。
这是一个SSCCE,如评论中所述,它按预期工作,所以我现在更加困惑。 ;)
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
public class TableModelChange extends JFrame {
private JTable t = null;
public TableModelChange() {
super();
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setBounds(100, 100, 500, 200);
JButton loadModel = new JButton("Load New Model");
loadModel.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
loadModelButtonActionPerformed(evt);
}
});
t = new JTable();
t.setModel(new javax.swing.table.DefaultTableModel(
new Object[][]{
{null, null, null, null, null, null, null, null},
{null, null, null, null, null, null, null, null},
{null, null, null, null, null, null, null, null},
{null, null, null, null, null, null, null, null},
{null, null, null, null, null, null, null, null},
{null, null, null, null, null, null, null, null},
{null, null, null, null, null, null, null, null},
{null, null, null, null, null, null, null, null},
{null, null, null, null, null, null, null, null},
{null, null, null, null, null, null, null, null}
},
new String[]{
"Col1", "Col2", "Col3", "Col4", "Col5", "Col6", "Col7", "Col8"
}
) {
Class[] types = new Class[]{
java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class
};
public Class getColumnClass(int columnIndex) {
return types[columnIndex];
}
});
this.getContentPane().add(t, BorderLayout.CENTER);
this.getContentPane().add(loadModel, BorderLayout.NORTH);
this.pack();
}
private void loadModelButtonActionPerformed(ActionEvent evt) {
Vector<Vector> data = new Vector<>();
Vector<String> row = new Vector<>();
for (int j = 0; j < 6; j++) {
for (int i = 0; i < 8; i++) {
row.add("A");
}
data.add(row);
}
Vector<String> colsV = new Vector<>();
TableModel tcm = t.getModel();
for (int i = 0; i < 8; i++) {
colsV.add((String) tcm.getColumnName(i));
}
t.setModel(new DefaultTableModel(data, colsV));
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
TableModelChange tm = new TableModelChange();
tm.setVisible(true);
}
});
}
}
答案 0 :(得分:0)
如果我在更改JTable模型后添加一个调用来加载现有的L&amp; F,问题就会消失。目前,这是解决方法,但我想深究这个问题。关于如何/在何处追踪的建议将受到欢迎。