I am trying to create a simple Input Verifier for a JTable. I ended up with overriding the method: editingStopped(). The problem is that the event does not include informations about the cell that has been updated.
This is my "pseudo code":
If (user finished editing a cell) {
Check if cell`s value is "1" or "0" or "-" (Karnaugh-Veitch)
If (check = false)
setValue (cell, "");
}
The first I tried was this here:
table.getModel().addTableModelListener(new TableModelListener() {
@Override
public void tableChanged(TableModelEvent e) {
inputVerify (e.getColumn(), e.getFirstRow());
}
});
public void inputVerify (int column, int row) {
boolean verified = true;
String field = table.getValueAt(row, column).toString();
if (field != null && field.length() == 1) {
if ( !(field.charAt(0) == '0' || field.charAt(0) == '1' || field.charAt(0) == '-' ))
verified = false;
}
else {
verified = false;
}
if (!verified) {
table.getModel().setValueAt("", row, column);
java.awt.Toolkit.getDefaultToolkit().beep();
}
System.out.println ("Column = " + column + " Row = " + row + " Value = " + table.getValueAt(row, column) +" Verified = "+verified);
}
But this ends up with an : StackOverflow Exception. I guess the problem is that: setValueAt(..) fires another tableChanged() event and an endless loop is being generated.
Now, I tried this here:
table.getDefaultEditor(Object.class).addCellEditorListener(new CellEditorListener() {
// called when editing stops
public void editingStopped(ChangeEvent e) {
// print out the value in the TableCellEditor
System.out.println(((CellEditor) e.getSource()).getCellEditorValue().toString());
}
public void editingCanceled(ChangeEvent e) {
// whatever
}
});
But as you can see I can just retrieve the new value of the cell, not the "coordinates". I need to call: setValueAt( .. ) method, but I dont know how to get the cell`s coordinates.
Or is there a more simple way to create an input verifier??
Best regards Ioannis K.
First: input validation on JTable editing is not well supported. A couple of comments
After all those (incomplete, unfortunately ;-) no-nos, a little hope: best bet is to implement a custom CellEditor which does the validation in stopCellCellEditing: if the new value isn't valid, return false and optionally provide a visual error feedback. Have a look at JTable.GenericEditor to get an idea of how that might be done
What worked for me (tip 'o the hat to kleopatra):
private class CellEditor extends DefaultCellEditor {
InputVerifier verifier = null;
public CellEditor(InputVerifier verifier) {
super(new JTextField());
this.verifier = verifier;
}
@Override
public boolean stopCellEditing() {
return verifier.verify(editorComponent) && super.stopCellEditing();
}
}
// ...
private class PortVerifier extends InputVerifier {
@Override
public boolean verify(JComponent input) {
boolean verified = false;
String text = ((JTextField) input).getText();
try {
int port = Integer.valueOf(text);
if ((0 < port) && (port <= 65535)) {
input.setBackground(Color.WHITE);
verified = true;
} else {
input.setBackground(Color.RED);
}
} catch (NumberFormatException e) {
input.setBackground(Color.RED);
}
return verified;
}
}
// ...
table.getColumn("Port").setCellEditor(new CellEditor(new PortVerifier()));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With