javaswingjtabletablemodel

Editing cell restrictions of a column in a JTable / TableModel


I am looking to modify the way cell input is handled in my JTable. Currently I am using a DefaultTableModel as seen below.

 DefaultTableModel model = new DefaultTableModel() {

                @Override
                public boolean isCellEditable(int row, int col) {
                    return col == 1 || col == 2 || col == 6;
                }

                @Override
                public Class getColumnClass(int col) {
                    if (col == 6) {
                        return Integer.class;
                    } else {
                        return String.class;
                    }
                }

            };

With this code column 6 forces the user to input an Integer. I would like to take this further by not allowing the number to be outside of a range (e.g. 1-100) and also for the field to never be empty (The column will have data in it prior to user interaction). I have read the docummentation but cannot seem to find anything that manages the behaviour of column types. Thanks!


Solution

  • You would need to create a custom editor.

    The following example demonstrates and editor that forces the data to be 5 characters:

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.border.*;
    import javax.swing.table.*;
    
    public class TableFiveCharacterEditor extends DefaultCellEditor
    {
        private long lastTime = System.currentTimeMillis();
    
        public TableFiveCharacterEditor()
        {
            super( new JTextField() );
        }
    
        public boolean stopCellEditing()
        {
            JTable table = (JTable)getComponent().getParent();
    
            try
            {
                String editingValue = (String)getCellEditorValue();
    
                if(editingValue.length() != 5)
                {
                    JTextField textField = (JTextField)getComponent();
                    textField.setBorder(new LineBorder(Color.red));
                    textField.selectAll();
                    textField.requestFocusInWindow();
    
                    JOptionPane.showMessageDialog(
                        table,
                        "Please enter string with 5 letters.",
                        "Alert!",JOptionPane.ERROR_MESSAGE);
                    return false;
                }
            }
            catch(ClassCastException exception)
            {
                return false;
            }
    
            return super.stopCellEditing();
        }
    
        public Component getTableCellEditorComponent(
            JTable table, Object value, boolean isSelected, int row, int column)
        {
            Component c = super.getTableCellEditorComponent(
                table, value, isSelected, row, column);
            ((JComponent)c).setBorder(new LineBorder(Color.black));
    
            return c;
        }
    
        private static void createAndShowUI()
        {
            JTable table = new JTable(5, 5);
            table.setPreferredScrollableViewportSize(table.getPreferredSize());
            JScrollPane scrollPane = new JScrollPane(table);
    
            //  Use a custom editor
    
            TableCellEditor fce = new TableFiveCharacterEditor();
            table.setDefaultEditor(Object.class, fce);
    
            JFrame frame = new JFrame("Table Five Character Editor");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add( scrollPane );
            frame.pack();
            frame.setLocationByPlatform( true );
            frame.setVisible( true );
        }
    
        public static void main(String[] args)
        {
            EventQueue.invokeLater(new Runnable()
            {
                public void run()
                {
                    createAndShowUI();
                }
            });
        }
    }
    

    You would need to modify the editor to make sure:

    1. the data is an Integer by using the Integer.parseInt(...) method
    2. that the Integer value is in your desired range

    Edit:

    how can I apply this to influence one column rather than the entire table.

    You can add the editor to the TableColumn:

    table.getColumnModel().getColumn(...).setCellEditor(...);