关于如果在最后一列丢失焦点后如何向JTable添加另一行的任何建议,考虑可移动列?
注意:该表由用户输入填充,但我只想在填写当前行后显示一个新的空行。
答案 0 :(得分:0)
我制作了一个符合要求的简单应用程序:
您可以编辑任何单元格,一旦最后一行编辑的最后一个单元格结束,就会添加一个空行。
它支持列重新排序(不需要额外的工作)。
这种方法实际上非常简单,JTable
实现CellEditorListener
,因此我们可以覆盖方法editingStopped(ChangeEvent)
并检查我们是否在表的最后一个单元格中,如果是,则添加一个新行。
所以你应该这样做:
//In the JTable class
@Override
public void editingStopped(ChangeEvent e)
{
//getting these values before calling super.editingStopped(e); because they get erased.
int row = getEditingRow();
int col = getEditingColumn();
super.editingStopped(e); //must call the super code to have a working edition
if (row == getRowCount() - 1 && col == getColumnCount() - 1)
{
getModel().createNewRow();
}
};
显然我实现的TableModel和TableCellEditor以及JTable是完成此任务的最低限度,您可以使用自己的,只需更改我用于您的模型的调用。
看起来像这样:
我建议使用TAB完成编辑,使焦点转到下一个,当你在最后一个时,它跳转到新行的第一个。
完整代码:
import java.awt.Component;
import java.util.ArrayList;
import javax.swing.AbstractCellEditor;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellEditor;
public class TableEditingTest
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
new TableEditingTest().createAndShowGUI();
}
});
}
private void createAndShowGUI()
{
JFrame frame = new JFrame("Table editing test");
MyTableModel model = new MyTableModel();
model.addRow(new String[]{"Some values", "so we have", "an actual table."});
model.addRow(new String[]{"This table", "is inititalized", "with an empty row:"});
model.createNewRow();
MyTable table = new MyTable(model);
table.setDefaultEditor(String.class, new MyStringTableCellEditor());
frame.add(new JScrollPane(table));
frame.setSize(600, 400); //use frame.pack() in a real application
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
private class MyTable extends JTable
{
public MyTable(MyTableModel model)
{
super(model);
}
@Override
public MyTableModel getModel()
{
return (MyTableModel) super.getModel();
}
@Override
public void editingStopped(ChangeEvent e)
{
int row = getEditingRow();
int col = getEditingColumn();
super.editingStopped(e);
if (row == getRowCount() - 1 && col == getColumnCount() - 1)
{
getModel().createNewRow();
}
};
}
private class MyTableModel extends AbstractTableModel
{
private static final int NUMBER_OF_COLUMNS = 3;
private ArrayList<String[]> values;
public MyTableModel()
{
values = new ArrayList<String[]>();
}
@Override
public String getColumnName(int col)
{
return "Column " + col;
}
@Override
public int getColumnCount()
{
return NUMBER_OF_COLUMNS;
}
@Override
public int getRowCount()
{
return values.size();
}
@Override
public Class<?> getColumnClass(int col)
{
return String.class;
}
@Override
public boolean isCellEditable(int row, int col)
{
return true;
};
@Override
public Object getValueAt(int row, int col)
{
return values.get(row)[col];
}
public void createNewRow()
{
addRow(null);
}
public void addRow(String[] rowValues)
{
if (rowValues == null)
{
values.add(new String[3]);
fireTableDataChanged();
}
else if (rowValues.length == 3)
{
values.add(rowValues);
fireTableDataChanged();
}
else throw new IllegalArgumentException("Expected an array of " + NUMBER_OF_COLUMNS + " strings, got " + rowValues.length + ".");
}
@Override
public void setValueAt(Object value, int row, int col)
{
values.get(row)[col] = value.toString();
}
}
private class MyStringTableCellEditor extends AbstractCellEditor implements TableCellEditor
{
private JTextField editorField = new JTextField();
@Override
public Object getCellEditorValue()
{
return editorField.getText();
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column)
{
editorField.setText((String) value);
return editorField;
}
}
}
答案 1 :(得分:0)
我个人建议您使用TAB
键ActionMap
而不是使用焦点丢失。
要添加新行,您可以使用DeafultTableModel
public void addNewRow(){
DefaultTableModel model = (DefaultTableModel) jTable1.getModel();
Vector row = new Vector();
row.add(null);
row.add(null);
row.add(null);
model.addRow(row);
}
对于可执行上述方法的触发器,您可以使用InputMap
&amp; ActionMap
private class NextCellActioin extends AbstractAction{
public NextCellActioin() {
}
@Override
public void actionPerformed(ActionEvent e) {
int col = jTable1.getSelectedColumn();
int row =jTable1.getSelectedRow();
int colCount = jTable1.getColumnCount();
int rowCount = jTable1.getRowCount();
col++;
if (col >= colCount) {
col = 0;
row++;
}
if (row >= rowCount) {
row = 0;
}
jTable1.getSelectionModel().setSelectionInterval(row, row);
jTable1.getColumnModel().getSelectionModel().setSelectionInterval(col, col);
jTable1.editCellAt(row, col);
if(col==3 && row==rowCount-1) {
addNewRow();
jTable1.scrollRectToVisible(jTable1.getCellRect(rowCount,0, true));
}
}
}
初始化InputMap
&amp; ActionMap
jTable1.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0), "Action.NextCell");
jTable1.getActionMap().put("Action.NextCell", new NextCellActioin());