Я пытаюсь написать TableCellEditor, который проверяет ввод для ячейки JTable. У меня он работает, за исключением того, что сообщение об ошибке отображается дважды. Вот мой класс тестера:
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();
}
}
Это редактор:
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());
}
}
Цель состоит в том, чтобы убедиться, что пользователь вводит числовое значение или не вводит никакого значения («»). Что приводит к тому, что ошибка отображается и отклоняется дважды, если она не является числовой, и как ее остановить? TIA.
Реализация предложения camickr
Если я понял предложение, мне не нужен редактор?
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();
}
}
Переопределение 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());
}
}
Очевидно, я сделал это неправильно, поскольку получаю исключения из неизвестного источника, в которых говорится:
Исключение в потоке «AWT-EventQueue-0» java.lang.IllegalArgumentException: невозможно отформатировать данный объект как число
Я предполагаю, что проблема с моим конструктором.
getCellEditorValue
вызывается более одного раза ... как вstopCellEditing()
и, возможно, изJTable
. Я бы постарался не использовать его вstopCellEditing()
, просто получить текст прямо из текстового поля (как это сделано вgetCellEditorValue()
) - person user85421   schedule 22.01.2018getCellEditorValue
не был вызван. - person Wt Riker   schedule 22.01.2018The objective is to assure the user enters a numeric value or no value at all ("").
- просто переопределите методgetColumnClass(...)
TableModel, чтобы вернутьDouble.class
для столбца, и JTable будет использовать соответствующий редактор. Вокруг ячейки появится красная рамка, и вы не сможете сохранить данные, пока не устраните проблему. Кроме того, имена классов должны начинаться с символа верхнего регистра. Соблюдайте соглашения Java! - person camickr   schedule 22.01.2018MCVE's
поправляются. Знайте, можно ли включить код только в один класс, поэтому нам нужно скопировать / вставить только один исходный файл. Вы можете легко встроить настраиваемую TableModel в исходный код тестера с помощью статического класса. Смотрите редактирование моего ответа. - person camickr   schedule 22.01.2018