一旦最后一个单元格失去焦点,就向JTable添加一行

时间:2014-05-20 16:43:38

标签: java swing jtable

关于如果在最后一列丢失焦点后如何向JTable添加另一行的任何建议,考虑可移动列?

注意:该表由用户输入填充,但我只想在填写当前行后显示一个新的空行。

2 个答案:

答案 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是完成此任务的最低限度,您可以使用自己的,只需更改我用于您的模型的调用。

看起来像这样:

enter image description here

enter image description here

我建议使用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)

我个人建议您使用TABActionMap而不是使用焦点丢失。

要添加新行,您可以使用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());