我有一个JTable显示SQL数据库中的行。该表相对较小(仅4列,最多1000行)。
我想让用户有机会编辑表格中的任何单元格,但希望避免限制它,以便他们必须使用编辑对话框(这样可以更容易地进行错误检查和验证,但不太直观)
我尝试了一些使用JTable的valueChanged方法控制编辑选择的不同方法,但是没有多少运气。
我希望在编辑结束时编辑每一行并将其写入数据库。我希望一旦单击一个单元格开始编辑该行,在用户完成编辑行之前不能选择其他行(其他行显示为灰色)。在编辑每个单元格并按Enter后,编辑选择应跳转到同一行中的下一列。
有人可以指点我如何实现这个目标吗?
// Create table with database data
table = new JTable(new DefaultTableModel(data, columnNames)) {
public Class getColumnClass(int column) {
for (int row = 0; row < getRowCount(); row++) {
Object o = getValueAt(row, column);
if (o != null){
return o.getClass();
}
}
return Object.class;
}
@Override
public boolean isCellEditable(int row, int col){
return true;
}
@Override
public boolean editCellAt(int row, int column) {
boolean ans = super.editCellAt(row, column);
if (ans) {
Component editor = table.getEditorComponent();
editor.requestFocusInWindow();
}
return ans;
}
@Override
public void valueChanged(ListSelectionEvent source) {
super.valueChanged(source);
if (table!=null)
table.changeSelection(getSelectedRow(), getSelectedColumn()+1, false, false);
}
};
编辑 - 带表指针的自定义单元格编辑器似乎是一个开始
public class ExchangeTableCellEditor extends AbstractCellEditor implements TableCellEditor {
private JTable table;
JComponent component = new JTextField();
public ExchangeTableCellEditor(JTable table) {
this.table = table;
}
public boolean stopCellEditing() {
boolean ans = super.stopCellEditing();
//now we want to increment the cell count
table.editCellAt(table.getSelectedRow(), table.getSelectedColumn()+1);
return ans;
}
@Override
public void cancelCellEditing() {
//do nothing... must accept cell changes
}
@Override
public Object getCellEditorValue() {
return ((JTextField)component).getText();
}
@Override
public Component getTableCellEditorComponent(JTable arg0, Object value,
boolean arg2, int arg3, int arg4) {
((JTextField)component).setText((String)value);
return component;
}
}
答案 0 :(得分:4)
default renderer and editor通常适用于大多数数据类型,但您可以根据需要定义自定义renderers和editors。
附录:我不熟悉你片段中显示的方法。相反,在您的模型中注册TableModelListener
,如下所示,并以保证的粒度更新数据库。另请参阅How to Use Tables: Listening for Data Changes。
附录:@kleopatra对您的TableCellEditor
是正确的。通知侦听器的一种便捷方式是调用超级实现,如here所示。请注意,delegate
会调用fireEditingStopped()
。
/** @see https://stackoverflow.com/questions/9155596 */
public class NewJavaGUI extends JPanel {
private final JTable table;
public NewJavaGUI() {
String[] colNames = {"C1", "C2", "C3"};
DefaultTableModel model = new DefaultTableModel(colNames, 0) {
@Override
public boolean isCellEditable(int row, int col) {
// return your actual criteria
return true;
}
@Override
public Class getColumnClass(int col) {
// return your actual type tokens
return getValueAt(0, col).getClass();
}
};
// Add data; note auto-boxing
model.addRow(new Object[]{"A1", "A2", 42});
model.addRow(new Object[]{"B1", "B2", 42d});
model.addTableModelListener(new TableModelListener() {
@Override
public void tableChanged(TableModelEvent e) {
// DML as indicated
}
});
table = new JTable(model);
this.add(table);
}
private void display() {
JFrame f = new JFrame("NewJavaGUI");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new NewJavaGUI().display();
}
});
}
}
答案 1 :(得分:-1)
您提到的行为可以通过强制您的表重新开始编辑来实现。
首先确保你现在是yourRow和Column,并且你要添加自己的tablecelleditor,它来自AbstractCellEditor 然后将其添加到您的stopCellEditing方法:
EventQueue.invokeLater(new Runnable()
{
public void run()
{
yourTable.editCellAt( yourRow, yourColumn+1);
}
});