DocumentFilter几乎按预期工作但我当前的问题是,如果用户删除两个数字字符然后输入一个,则显示displayDoubleErrorMessage()并阻止/拒绝用户输入任何字符以完成双倍达到两位小数地方。当细胞失去焦点或停止编辑并且值不是双倍时,理想的情况是显示错误吗?预期目的是仅允许用户输入数字字符并始终显示两个小数位。
示例:如果用户输入3,则单元格将调整为3.00
我已经尝试了多个if else语句来检查StringBuilder以查看值是否包含。,。0和.00。存在一个问题,因为用户必须删除最后输入的最后一个数字字符并重复此过程直到所需的输入。
我已尝试使用掩码格式化程序####。##的JFormattedTextField但如果用户输入3或任何其他不覆盖输入掩码的数字,我不喜欢前导零。示例:0003.00
public static class DoubleDocumentFilter extends DocumentFilter
{
private JTable table;
public DoubleDocumentFilter(JTable table)
{
this.table = table;
}
@Override
public void insertString(FilterBypass fb, int offset, String value, AttributeSet attr)
throws BadLocationException
{
Document document = fb.getDocument();
String text = document.getText(0, document.getLength());
StringBuilder sb = new StringBuilder();
sb.append(text.substring(0, offset));
sb.append(value);
sb.append(text.substring(offset));
//ValidateDouble is regex that just validates a double to two decimal places
if (new ValidateDouble().validate(sb.toString()))
super.insertString(fb, offset, value, attr);
else
displayDoubleErrorMessage();
}
@Override
public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String value, AttributeSet attr)
throws BadLocationException
{
Document document = fb.getDocument();
String text = document.getText(0, document.getLength());
StringBuilder sb = new StringBuilder();
sb.append(text.substring(0, offset));
sb.append(value);
sb.append(text.substring(offset));
if (new ValidateDouble().validate(sb.toString()))
super.replace(fb, offset, length, value, attr);
else
displayDoubleErrorMessage();
}
public void displayDoubleErrorMessage()
{
ErrorMessageModel errorModel = new ErrorMessageModel();
errorModel.loadProperties();
if (errorModel.isDisplayable("ProductDoubleDisplay")) {
ErrorMessagePane pane = new ErrorMessagePane(table.getParent(),
errorModel.getErrorMessage("ProductDouble"));
if (pane.isCheckBoxSelected()) {
errorModel.saveProperties("ProductDoubleDisplay", "false");
errorModel.storeProperties();
}
}
}
}
答案 0 :(得分:0)
这就是我最终做细胞编辑器的方法.....
public class CurrencyCellEditor
extends DefaultCellEditor
{
private JFormattedTextField textField;
private CSVFileController controller;
private ProductTableModel tableModel;
private int productRow;
public CurrencyCellEditor(
JFormattedTextField textField,
CSVFileController controller,
ProductTableModel tableModel)
{
super(textField);
this.textField = textField;
this.controller = controller;
this.tableModel = tableModel;
productRow = 0;
}
@Override
public Component getTableCellEditorComponent(
JTable table,
Object value,
boolean isSelected,
int row,
int column)
{
BigDecimal decimalValue = new BigDecimal(value.toString());
DecimalFormat formatter = new DecimalFormat("$##,##0.00");
this.productRow = row;
textField.setFont(ApplicationStyles.TABLE_FONT);
textField.addMouseListener(new TextFieldMouseAdapter());
if (value != null)
{
decimalValue = decimalValue.setScale(2, BigDecimal.ROUND_HALF_EVEN);
formatter.setMinimumFractionDigits(2);
formatter.setMinimumFractionDigits(2);
textField.setText(formatter.format(value));
}
return textField;
}
@Override
public Object getCellEditorValue()
{
if (!textField.getText().isEmpty())
{
if (textField.getText().toString().contains(",")
|| textField.getText().toString().contains("$"))
return new BigDecimal(
textField.getText().toString().replaceAll("[,$]", ""));
return new BigDecimal(textField.getText());
}
return new BigDecimal(0.00);
}
@Override
public boolean stopCellEditing()
{
String value = textField.getText();
Product product = tableModel.getProduct(productRow);
if (value.contains(",") || value.contains("$"))
value = value.replaceAll("[,$]", "");
if (new ValidateDouble().validate(value))
{
controller.addProduct(product.getSupplier().getName(), product);
return super.stopCellEditing();
}
ErrorMessageModel errorModel = new ErrorMessageModel();
errorModel.loadProperties();
if (errorModel.isDisplayable("ProductDoubleDisplay"))
{
ErrorMessagePane pane = new ErrorMessagePane(
textField.getParent(),
errorModel.getErrorMessage("ProductDouble"));
if (pane.isCheckBoxSelected())
{
errorModel.saveProperties("ProductDoubleDisplay", "false");
errorModel.storeProperties();
}
}
return false;
}
private class TextFieldMouseAdapter
extends MouseAdapter
{
@Override
public void mousePressed(MouseEvent evt)
{
if ((evt.getButton() == MouseEvent.BUTTON1)
&& evt.getClickCount() == 2)
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run()
{
int offset = textField.viewToModel(evt.getPoint());
textField.setCaretPosition(offset);
}
});
}
}
}