1

I am working in a project where I have to get input from user by using a JTable. Here I had created a JTable which will have only numerical values. I validated it on keyTyped and its working fine until I press F2 or click on the cell. When I am doing so, it put a cursor in cell and other characters are also being typed.

jtblValues.addKeyListener(new KeyListener() {
        public void keyPressed(KeyEvent e) {
            if (e.getKeyCode()==KeyEvent.VK_ENTER && (jtblValues.getRowCount() == (jtblValues.getSelectedRow()+1))) 
                model.addRow(new Object[]{"", "", ""}); 
            else if (e.getKeyCode()==KeyEvent.VK_TAB && (jtblValues.getRowCount() == (jtblValues.getSelectedRow()+1)) && (jtblValues.getColumnCount() == (jtblValues.getSelectedColumn()+1)))
                model.addRow(new Object[]{"", "", ""}); 
        }
        public void keyReleased(KeyEvent e) {}
        public void keyTyped(KeyEvent e) {
            char c = e.getKeyChar();
            if (!((c >= '0') && (c <= '9') || (c == KeyEvent.VK_BACK_SPACE) || (c == KeyEvent.VK_DELETE) || (c == KeyEvent.VK_ENTER) || (c == KeyEvent.VK_TAB))) {
                getToolkit().beep();
                e.consume();
            }
        } 
    } );

So, how to prevent user by typing other characters than numbers?

Thanks.

BK Prajapati
  • 38
  • 2
  • 7
  • 3
    do.not.use.keylisteners.for.input.validation, neither in a table nor anywhere else. Darn, how often do we need to repeat that. Use a custom editor with a formattedTextField as editing component - you might want to look into SwingX for guidance. – kleopatra Jan 16 '14 at 15:14
  • 2
    @kleopatra: keep fighting the good fight! – Hovercraft Full Of Eels Jan 16 '14 at 15:22

3 Answers3

5

You can achieve this by providing an appropriate TableCellEditor as described in Using an Editor to Validate User-Entered Text section of How to Use Tables tutorial.

The key is using a JFormattedTextfield as editor with NumberFormatter and NumberFormat. For instance:

NumberFormat integerFormat = NumberFormat.getIntegerInstance();
NumberFormatter formatter = new NumberFormatter(integerFormat);
formatter.setAllowsInvalid(false);
JFormattedTextField textfield = new JFormattedTextField(formatter);

See How to Use Formatted Text Fields tutorial for further details.

Off-topic

It's preferable use Keybinding over KeyListeners when you're working with Swing for the reasons discussed in this topic: Key bindings vs. key listeners in Java. Refer to the tutorial to start with KeyBinding: How to Use Key Bindings

Community
  • 1
  • 1
dic19
  • 17,821
  • 6
  • 40
  • 69
  • To make my question more clear, I want to add that I have dynamic record entry where user can input as many records as he/she wants so I can't use textfields for that purpose as I am creating new records as per requirements (as shown in my code on keyPressed() event) and JTable is suitable for it. So, if you have any solution where I can generate new rows with validation (either with jtable or anything else) then let me know... thanks. – BK Prajapati Jan 16 '14 at 15:38
  • @BKPrajapati I think you've skipped the [TableCellEditor](http://docs.oracle.com/javase/tutorial/uiswing/components/table.html#validtext) part in my answer. Of course you don't need a JFormattedTextField *out* of the table. But you need to provide one as `TableCellEditor`. Check out the tutorials I've linked. – dic19 Jan 16 '14 at 15:43
  • Thanks for the help. I'll implement it. – BK Prajapati Jan 16 '14 at 15:48
  • You could also use a [DocuemntFilter](http://stackoverflow.com/questions/12793030/jtextfield-limiting-character-amount-input-and-accepting-numeric-only/12793126#12793126), which would provide real time feedback – MadProgrammer Jan 16 '14 at 20:20
0

maybe I have same problem like you. This code worked for me using KeyListener.

//define KeyAdapter variable at header
KeyAdapter key1, key2;

make class TableEditor like this:

final class TableEditor extends DefaultCellEditor{

    public TableEditor(){
        super(new JTextField());
        setClickCountToStart(1);
    }

    @Override
    public Component getTableCellEditorComponent(final JTable table,Object value,boolean isSelected,final int row,final int column){
        final JTextField cellEdit = (JTextField) super.getTableCellEditorComponent(table,value,isSelected,row,column);
        cellEdit.setText((String)value);
        table.setSurrendersFocusOnKeystroke(true);

        //remove previous keyListener that store in memory
        cellEdit.removeKeyListener(key1);
        cellEdit.removeKeyListener(key2);

        // KeyAdapter that accept numeric only (key1)
        key1 = new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent evt){
                // just for check how much times Enter keyEvent store in memory
                if(evt.getKeyCode()==KeyEvent.VK_ENTER) System.out.println("enter 2"); 
            }
            @Override
            public void keyReleased(KeyEvent evt){

            }
            @Override
            public void keyTyped(KeyEvent evt){
                char c = evt.getKeyChar();
                if (!Character.isDigit(c)) evt.consume();
            }
        };

        // KeyAdapter that accept all char (key2)
        key2 = new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent evt){
                // just for check how much times Enter keyEvent store in memory
                if(evt.getKeyCode()==KeyEvent.VK_ENTER) System.out.println("enter 2"); 
            }
            @Override
            public void keyReleased(KeyEvent evt){

            }
            @Override
            public void keyTyped(KeyEvent evt){

            }
        };
        // cell column 3rd accept numeric only > addKeyListener(key1)
        if (column == 3) {
            cellEdit.addKeyListener(key1);
            cellEdit.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
            cellEdit.setCaretPosition(1);
            return cellEdit;
        } 
        // other cell accept all char > addKeyListener(key2)
        else  {
            cellEdit.addKeyListener(key2);
            cellEdit.setHorizontalAlignment(javax.swing.JTextField.LEFT);
            return cellEdit;
        }
    } 
}

Then call the class using:

MyTable.setDefaultEditor(Object.class, new TableEditor());

That's all. I hope this code worked for you.

repot
  • 83
  • 3
  • 9
0

you can do this easy way in netbeans: Step 1:see image 1 here Step 2:see image 2 here Step 3:see image 3 here