2015-08-19 7 views
0

DocumentFilter работает практически так, как предполагалось, но моя текущая проблема заключается в том, что если пользователь удаляет два числовых символа, а затем вводит один, он отображает displayDoubleErrorMessage() и предотвращает/запрещает пользователю вводить больше символов для завершения двойной до двух знаков после запятой. Будет ли идеальной ситуацией показывать ошибку, когда ячейка теряет фокус или прекращает редактирование, а значение не является двойным? Цель состоит в том, чтобы позволить пользователю вводить числовые символы и всегда показывать два десятичных знака.DocumentFilter для двух десятичных знаков

. Пример: если пользователь входит 3, ячейка будет подстраиваться 3,00

Я попытался кратному, если другое заявление, чтобы проверить StringBuilder, чтобы увидеть, если содержащееся значение, +0,0 и +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

Используйте 'JFormattedTextField' вместо создания пользовательского фильтра. Дополнительную информацию и примеры см. В разделе «Использование форматированных текстовых полей» (http://docs.oracle.com/javase/tutorial/uiswing/components/formattedtextfield.html). – camickr

+0

Я попробую еще раз, чтобы найти способ удалить ведущие нули ... Спасибо Rob – Grim

+0

DecimalFormat решит мою проблему. – Grim

ответ

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); 
        } 
       }); 
     } 
    } 
} 
Смежные вопросы