2015-10-26 1 views
1

В java, я пытаюсь сделать простой конвертер валют, но для этого мне нужно текстовое поле, которое может ограничивать ввод только номерами и, что более важно, двойными номерами. Я пробовал использовать JFormatedTextField, но он только форматирует ввод после того, как вы сделали свой ввод, и щелкните в другом месте, но мне нужно ограничить TextField до . ( каждый недопустимый символ при выполнении ввода.Ограничить ввод JTextField в двойные числа?

Возможные попытки:

Использование JFormatedTextField:

JFormatedTextField textField = new JFormatedTextField(new DoubleFormat()); 
textField.setBounds(190, 49, 146, 33); 
frame.getContentPane().add(textField); 
textField.setColumns(10); 

Использование KeyTyped Event:

char c = arg0.getKeyChar(); 
if(!(Character.isDigit(c) || c == KeyEvent.VK_BACK_SPACE || c== KeyEvent.VK_DELETE)){ 
    arg0.consume(); 
} 

Использование KeyTyped Event с регулярным выражением:

if(!((textField.getText().toString+arg0.getKeyChar()).matches("[0-9]*(.[0-9]*)?"))){ 
    arg0.consume(); 
} 

Вторая и третья попытка были близки, но затем вторая попытка не удалась по значениям точки, а третья попытка всегда считывала первый символ на textField независимо от того, что это такое, поэтому любые предложения? Я не очень люблю JAVA GUI, любезно проявляю терпение.

+0

1) Java GUI должны работать с различными ОС, размером экрана, разрешением экрана и т. Д., Используя разные PLAF в разных локалях. Таким образом, они не способствуют идеальной компоновке пикселей. Вместо этого используйте диспетчеры макетов или [их комбинации] (http: // stackoverflow.com/a/5630271/418556) вместе с макетом и границами для [пробела] (http://stackoverflow.com/a/17874718/418556). 2) Для этой задачи я хотел бы использовать 'JSpinner' с' SpinnerNumberModel'. –

+0

Это простое текстовое поле редактирования, необходимое для ввода входного номера, если я склонен использовать spinner, как я могу указать число разной длины? означает 34533434445545345345345.3454543534535345345 –

ответ

1

Если вы знаете, сколько места до и после десятичной точки вы хотите, вы можете также использовать MaskFormatter. Например:

JFormattedTextField field = new JFormattedTextField(getMaskFormatter("######.##")); 

(...) 

private MaskFormatter getMaskFormatter(String format) { 
    MaskFormatter mask = null; 
    try { 
     mask = new MaskFormatter(format); 
     mask.setPlaceholderCharacter('0'); 
    }catch (ParseException ex) { 
     ex.printStackTrace(); 
    } 
    return mask; 
} 

Однако это Chenge взгляд JTextField, так что это будет в нем всегда виден 000000.00.

EDIT

Другой способ, не слишком элегантно, но, на мой взгляд, работает. Попробуйте с DecumentListener, может быть, это будет отвечать вашим потребностям:

field = new JFormattedTextField(); 
field.getDocument().addDocumentListener(new DocumentListener() { 
    @Override 
    public void insertUpdate(DocumentEvent e) { 
     Runnable format = new Runnable() { 
      @Override 
      public void run() { 
       String text = field.getText(); 
       if(!text.matches("\\d*(\\.\\d{0,2})?")){ 
        field.setText(text.substring(0,text.length()-1)); 
       } 
      } 
     }; 
     SwingUtilities.invokeLater(format); 
    } 

    @Override 
    public void removeUpdate(DocumentEvent e) { 

    } 

    @Override 
    public void changedUpdate(DocumentEvent e) { 

    } 
}); 

Я использовал регулярное выражение: \\d*(\\.\\d{0,2})? потому, что два знака после запятой достаточно для валюты.

+0

то же самое перешло мне в голову, но насколько хорош вход, если мы не можем полностью использовать программу, ограничив ее размер ввода. –

+0

@BadComputer Я обновил ответ, что с этим? –

+0

он проделал мою работу, извините забыл принять ответ –

1

Вам нужно будет использовать DocumentFilter. Прочтите раздел из учебника Swing на странице Implementing a DocumentFilter для примера, чтобы вы начали.

Ваша реализация будет более сложной, потому что вам нужно будет взять текст уже в документе, а затем вставить новый текст в соответствующее место в String и затем вызвать Double.parseDouble (...) на String to убедитесь, что это действительное двойное значение.

Если проверка прошла успешно, вы продолжаете вставку, иначе вы можете генерировать звуковой сигнал.

+0

Нет ли другого обходного пути без 'DocumentFilter'? , я игнорирую это, потому что я не совсем понял это. –

+1

Как вы могли понять это менее чем за 10 минут? Вы читали учебник? Вы загрузили демо-код и протестировали его? Вы попробовали мое предложение, которое в основном состоит из 3 строк кода? 'Мне нужно ограничить TextField, чтобы потреблять() каждый недопустимый символ, делая ввод' Использование DocumentFilter - правильное решение и делает именно то, что вы хотите – camickr

1

Вы можете добавить прослушиватель клавиш в текстовое поле и реализовать метод keyReleased(), чтобы определить, является ли значение в текстовом поле двойным после каждого нажатия клавиши пользователем.

public class CurrencyJTF extends JFrame { 
JButton jButton = new JButton("Unfocus"); 
final JFormattedTextField textField = new JFormattedTextField(new DecimalFormat()); 
double lastDouble = 0.0; 

public CurrencyJTF() throws HeadlessException { 
    textField.setColumns(20); 
    textField.setText(lastDouble + ""); 

    this.setLayout(new FlowLayout()); 

    this.add(textField); 
    this.add(jButton); 

    textField.addKeyListener(new KeyAdapter() { 
     @Override 
     public void keyReleased(KeyEvent e) { 
      handleKeyReleased(); 
     } 
    }); 
} 

private void handleKeyReleased() { 
    String text = textField.getText(); 
    if (text.isEmpty()) return; 

    try { 
     lastDouble = Double.parseDouble(text); 
    } catch (NumberFormatException ex) { 
     textField.setText(lastDouble + ""); // or set to other values you want 
    } 
} 

public static void main(String[] args) { 
    JFrame frame = new CurrencyJTF(); 
    frame.setVisible(true); 
    frame.pack(); 
} 
} 
+1

Не очень удобный. Если вы вводите недопустимый символ, курсор всегда перемещается в конец текста, а не остается там, где пользователь попытался вставить текст. Также не очень дружелюбный программист, потому что два документа (Add/Remove) будут созданы для недопустимых символов, даже если документ не изменился. – camickr

+0

да показывается неверный символ на мгновение. Неправильный подход. Думаю, –