我不确定为什么我为jtable设置的编辑器没有被调用。我使用了另一个SO Question的编辑器示例。
当我编辑我的jtable时,它只是编辑为字符串...我希望它只接受数字值。如果我输入任何其他文本可能会有一些例外...但我不认为编辑我的表时会在这里调用编辑器。
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.text.NumberFormatter;
import java.awt.*;
import java.awt.event.*;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.util.Locale;
public class Grow extends JFrame {
private static final Object[][] rowData = {{"Hello", "World"}};
private static final Object[] columnNames = {"A", "B"};
private JTable table;
private DefaultTableModel model;
public Grow() {
Container c = getContentPane();
c.setLayout(new BorderLayout());
model = new DefaultTableModel(rowData, columnNames);
table = new JTable();
table.setModel(model);
c.add(new JScrollPane(table), BorderLayout.CENTER);
JButton add = new JButton("Add");
JButton delete = new JButton("Delete");
c.add(add, BorderLayout.LINE_START);
add.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
model.addRow(rowData[0]);
}
});
table.setCellEditor(new NumberCellEditor());
c.add(delete, BorderLayout.LINE_END);
delete.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
if(table.getSelectedRow()>-1)
model.removeRow(table.getSelectedRow());
}
});
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
}
class NumberCellEditor extends DefaultCellEditor {
/**
*
*/
private static final long serialVersionUID = 1L;
public NumberCellEditor(){
super(new JFormattedTextField());
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
JFormattedTextField editor = (JFormattedTextField) super.getTableCellEditorComponent(table, value, isSelected, row, column);
if (value!=null){
DecimalFormat numberFormat = new DecimalFormat("#,##0.00;(#,##0.00)");
editor.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.NumberFormatter(numberFormat)));
Number num = (Number) value;
String text = numberFormat.format(num);
editor.setHorizontalAlignment(SwingConstants.RIGHT);
editor.setText(text);
}
System.out.println(value);
return editor;
}
/*@Override
public boolean stopCellEditing() {
try {
// try to get the value
//this.getCellEditorValue();
return super.stopCellEditing();
} catch (Exception ex) {
return false;
}
}
*/
@Override
public Object getCellEditorValue() {
// get content of textField
String str = (String) super.getCellEditorValue();
if (str == null) {
return null;
}
if (str.length() == 0) {
return null;
}
// try to parse a number
try {
ParsePosition pos = new ParsePosition(0);
Number n = NumberFormat.getInstance().parse(str, pos);
if (pos.getIndex() != str.length()) {
throw new ParseException(
"parsing incomplete", pos.getIndex());
}
// return an instance of column class
return new Float(n.floatValue());
} catch (ParseException pex) {
throw new RuntimeException(pex);
}
}
}
public static void main(String[] args) {
Grow g = new Grow();
g.setLocationRelativeTo(null);
g.setVisible(true);
}
}
答案 0 :(得分:2)
使用普通香草JTextField
与DocumentFilter
代替JFormattedTextField
作为编辑Component
。
我无法评论某些内容,为JFormattedTextField
添加XxxFormat
的start_point(重要的详细信息在官方Oracle教程,API How to use FormattedTextField
,NumberFormat
等。)< / p>
您可以添加InternationalFormatter以仅过滤Numbers
e.g。
InternationalFormatter formatter = new InternationalFormatter(format);
formatter.setAllowsInvalid(false);
//formatter.setMinimum(0.0);
//formatter.setMaximum(1000.00);
screen_shot
来自代码
import java.awt.Component;
import java.awt.EventQueue;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import javax.swing.*;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumnModel;
public class EditorAsRendererTableTest {
public EditorAsRendererTableTest() {
JTable table = new JTable(3, 2);
TableColumnModel colModel = table.getColumnModel();
colModel.getColumn(0).setCellEditor(new MyCellEditor());
colModel.getColumn(0).setCellRenderer(new MyCellEditor());
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
frame.add(new JScrollPane(table));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new EditorAsRendererTableTest();
}
});
}
private class MyCellEditor extends AbstractCellEditor implements TableCellEditor, TableCellRenderer {
private static final long serialVersionUID = 1L;
private JFormattedTextField renderer;
private JFormattedTextField editor;
private NumberFormat format = DecimalFormat.getInstance();
public MyCellEditor() {
format.setMinimumFractionDigits(2);
format.setMaximumFractionDigits(4);
format.setRoundingMode(RoundingMode.HALF_UP);
renderer = new JFormattedTextField(format);
renderer.setBorder(null);
editor = new JFormattedTextField(format);
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
renderer.setValue(value);
return renderer;
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
editor.setValue(value);
return editor;
}
@Override
public boolean stopCellEditing() {
try {
editor.commitEdit();
} catch (ParseException e) {
return false;
}
return super.stopCellEditing();
}
@Override
public Object getCellEditorValue() {
return editor.getValue();
}
}
}
答案 1 :(得分:2)
我希望它只接受数字值
通常,无需创建自定义编辑器。只需覆盖TableModel的getColumnClass()方法,即可返回存储在模型中的正确数据类,该表将使用适当的渲染器和编辑器。
但是,如果您希望编辑器限制小数位或对数字进行范围检查,那么您可以使用自定义编辑器。