Wt Riker
Wt Riker

Reputation: 614

Verifying JTable Input Gets Double Error Message

I am trying to write a TableCellEditor that verifies the input for a JTable cell. I have it working except that the error message is being displayed twice. Here is my tester class:

import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;

public class Tester {
    public static void main(String[] args) {
        JFrame frame=new JFrame();
        frame.setPreferredSize(new Dimension(500,100));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        DefaultTableModel model=new DefaultTableModel(null,new String[] {"Col 1","Col 2"});
        JTable table=new JTable(model);
        table.getColumnModel().getColumn(0).setCellEditor(new decimalCellEditor());
        model.insertRow(0,new Object[] {null,null});
        JScrollPane scroller=new JScrollPane(table);
        frame.add(scroller);
        frame.setVisible(true);
        frame.pack();
     }
}

This is the editor:

 import java.awt.Component;

import javax.swing.AbstractCellEditor;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.TableCellEditor;


public class DecimalCellEditor extends AbstractCellEditor implements TableCellEditor {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private JTextField number=null;

    public DecimalCellEditor() {
        number=new JTextField();
    }

    @Override
    public Object getCellEditorValue() {
        String s=number.getText();
        if (s.equals("")) {
            return(s);
        }
        double x=0.;
        try {
            x=Double.parseDouble(s);
        } catch (NumberFormatException e) {
            JOptionPane.showMessageDialog(null,"Value must be numeric",null, JOptionPane.ERROR_MESSAGE, null);
            return("");
        }
        return(Double.toString(x));
    }

    @Override
    public Component getTableCellEditorComponent(JTable table_, Object value_, boolean isSelected_, int row_, int column_) {
        number.setText(String.valueOf(value_));
        return(number);
    }

    @Override
    public boolean stopCellEditing() {
        String s=(String) getCellEditorValue();
        if (s.equals("")) {
            return(super.stopCellEditing());
        }
        try {
            Double.parseDouble(s);
        } catch (NumberFormatException e) {
            fireEditingCanceled();
            return(false);
        }
        return(super.stopCellEditing());
    }
}

The objective is to assure the user enters a numeric value or no value at all (""). What is causing the error to be displayed and dismissed twice when it is non-numeric and how can I stop it? TIA.

Implementing camickr's suggestion

Assuming I understood the suggestion, I don't need the editor?

import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;

public class Tester {
    public static void main(String[] args) {
        JFrame frame=new JFrame();
        frame.setPreferredSize(new Dimension(500,100));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        MyTableModel model=new MyTableModel(null,new String[] {"Col 1","Col 2"});
        JTable table=new JTable(model);
        model.insertRow(0,new Object[] {"",""});
        JScrollPane scroller=new JScrollPane(table);
        frame.add(scroller);
        frame.setVisible(true);
        frame.pack();
    }
}

Overriding getColumnClass:

import javax.swing.table.DefaultTableModel;

public class MyTableModel extends DefaultTableModel {

/**
 * 
 */
private static final long serialVersionUID = 1L;

    public MyTableModel(Object[][] data_,String[] columnNames_) {
        super(data_,columnNames_);
    }

    @Override
    public Class<?> getColumnClass(int column_) {
        if (column_==0) {
            return(Double.class);
        }
        return(getValueAt(0,column_).getClass());
    }
}

I obviously didn't do this right as I get exceptions from an unknown source saying:

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: Cannot format given Object as a Number

I'm guessing there is a problem with my constructor.

Upvotes: 1

Views: 575

Answers (1)

camickr
camickr

Reputation: 324157

First of all class names should start with an upper case character. You have been given links to the Swing tutorials that provide demo code. I'm sure you have access to the Java API. The API and examples all follow the same convention. Learn by example and follow Java conventions!

The objective is to assure the user enters a numeric value or no value at all ("").

Just override the getColumnClass(...) method of the TableModel to return Double.class for the column and the JTable will use an appropriate editor and renderer.

A red border will be placed around the cell and you won't be able to save the data until you fix the problem.

Cannot format given Object as a Number

Edit:

Take the time to think about the change you just made. Take the time to read the error message. Your change just stated the column should contain Double data. So why are you adding an "empty" String in the first column. How can the renderer convert a String to a Double?

Again, if you read the code in the Java tutorials you will see how numeric data is add to the TableModel. I gave you a link to that tutorial long ago because it contains many basics.

Upvotes: 1

Related Questions