web-dev-qa-db-ja.com

Java TextFieldで数字とドットのみを受け入れます

キーボードからの数字のみを受け付けるtextFieldを1つ持っていますが、「価格textField」であるため変更する必要があり、ドット「。」も受け入れる必要があります。どんな種類の価格でも。

必要なものを取得するためにどのようにこれを変更できますか?

ptoMinimoField = new JTextField();
        ptoMinimoField.setBounds(348, 177, 167, 20);
        contentPanel.add(ptoMinimoField);
        ptoMinimoField.setColumns(10);
        ptoMinimoField.addKeyListener(new KeyAdapter() {
            public void keyTyped(KeyEvent e) {
                char caracter = e.getKeyChar();
                if (((caracter < '0') || (caracter > '9'))
                        && (caracter != '\b')) {
                    e.consume();
                }
            }
        });
8
Agustín

Oracleが提案したように、 フォーマットされたテキストフィールドを使用

フォーマットされたテキストフィールドは、開発者がテキストフィールドに入力できる有効な文字セットを指定する方法を提供します。

amountFormat = NumberFormat.getNumberInstance();
...
amountField = new JFormattedTextField(amountFormat);
amountField.setValue(new Double(amount));
amountField.setColumns(10);
amountField.addPropertyChangeListener("value", this);
11
Suresh Atta

JTextField txField = new DoubleJTextField();

ファイルDoubleJTextField.Javaを作成し、満足してください

public class DoubleJTextField extends JTextField {
    public DoubleJTextField(){
        addKeyListener(new KeyAdapter() {
            public void keyTyped(KeyEvent e) {
                char ch = e.getKeyChar();

                if (!isNumber(ch) && !isValidSignal(ch) && !validatePoint(ch)  && ch != '\b') {
                    e.consume();
                }
            }
        });

    }

    private boolean isNumber(char ch){
        return ch >= '0' && ch <= '9';
    }

    private boolean isValidSignal(char ch){
        if( (getText() == null || "".equals(getText().trim()) ) && ch == '-'){
            return true;
        }

        return false;
    }

    private boolean validatePoint(char ch){
        if(ch != '.'){
            return false;
        }

        if(getText() == null || "".equals(getText().trim())){
            setText("0.");
            return false;
        }else if("-".equals(getText())){
            setText("-0.");
        }

        return true;
    }
}
6
Wender

私はtry-catchブロックを使用しています:

try {// if is number
    Integer.parseInt(String);
} catch (NumberFormatException e) {
    // else then do blah
}
4
Brayan Byrdsong

これにはKeyListenerを使用しないでください。上記のコードには2つの重大なバグがあり、どちらもKeyListenerの使用が原因です。まず、貼り付けられたテキストを見逃します。数字以外を除外するフィールドを見つけるたびに、楽しみのために常にテキストを貼り付けようとします。 10回のうち9回は、キーリスナを使用したため、テキストが受け入れられます。

第二に、修飾子を除外しませんでした。ユーザーがこのフィールドにいる間にcontrol-sを入力して作業を保存しようとすると、キーリスナーはイベントを消費します。また、アプリケーションが、たとえばcontrol-5またはalt-5ショートカットを何らかのアクションに割り当てる場合、ユーザーが文字を入力しようとしていない場合でも、このKeyListenerはフィールドを入力するときに5をフィールドに追加します。バックスペースキーを渡す必要があることがわかりましたが、渡す必要があるのはそれだけではありません。矢印キーは機能しません。ファンクションキーも同様です。これらの問題はすべて修正できますが、多くの作業が必要になります。

3つ目の欠点がありますが、アプリケーションを外国のアルファベット、特に中国語のように1つの文字を生成するために複数のキーストロークを必要とするアルファベットに適応させる場合にのみ現れます。これらのアルファベットはKeyListenersを役に立たなくします。

問題はこれです。文字をフィルタリングする必要がありますが、KeyListenersは文字に関するものではなく、キーストロークに関するものであり、同じことではありません。すべてのキーストロークが文字を生成するわけではなく、すべての文字がキーストロークによって生成されるわけでもありません。文字が生成された後、および変更されたキーストロークが既に除外された後に文字を調べるアプローチが必要です。

最も単純なアプローチはJFormattedTextFieldを使用することですが、入力したときにフォーマットやフィルター処理を行わないため、私はそのアプローチが好きではありませんでした。その代わりに、DocumentFilterを使用します。 DocumentFiltersはキーストロークではなく、JTextFieldのデータモデルに挿入されるテキスト文字列で動作します。したがって、すべてのコントロールキー、矢印、およびファンクションキーなどは、DocumentFilterにも到達しません。貼り付けられたテキストもすべてDocumentFilterを通過します。また、3つのキーストロークを使用して1つの文字を生成する言語の場合、文字が生成されるまでDocumentFilterは呼び出されません。これは次のようなものです。

    ptoMinimoField = new JTextField();
    ptoMinimoField.setBounds(348, 177, 167, 20); // Don't do this! See below.
    contentPanel.add(ptoMinimoField);
    ptoMinimoField.setColumns(10);

    PlainDocument document = (PlainDocument) ptoMinimoField.getDocument();
    document.setDocumentFilter(new DigitFilter());
}

DigitFilterクラスは次のようになります。

public class DigitFilter extends DocumentFilter {
    @Override
    public void insertString(FilterBypass fb, int offset, String text, 
            AttributeSet attr) throws BadLocationException {
        super.insertString(fb, offset, revise(text), attr);
    }

    @Override
    public void replace(FilterBypass fb, int offset, int length, String text,
                        AttributeSet attrs) throws BadLocationException {
        super.replace(fb, offset, length, revise(text), attrs);
    }

    private String revise(String text) {
        StringBuilder builder = new StringBuilder(text);
        int index = 0;
        while (index < builder.length()) {
            if (accept(builder.charAt(index))) {
                index++;
            } else {
                // Don't increment index here, or you'll skip the next character!
                builder.deleteCharAt(index);
            }
        }
        return builder.toString();
    }

    /**
     * Determine if the character should remain in the String. You may
     * override this to get any matching criteria you want. 
     * @param c The character in question
     * @return true if it's valid, false if it should be removed.
     */
    public boolean accept(final char c) {
        return Character.isDigit(c) || c == '.';
    }
}

これを内部クラスとして書くこともできますが、別のクラスを作成して、accept()メソッドをオーバーライドして必要な基準を使用できるようにします。また、次のように書いても数字をテストしないことに気付くかもしれません。

(c < '0') || (c > '9')

代わりに、私はこれを行います:

Character.isDigit()

これはより速く、よりクリーンで、外国の番号システムで動作します。また、バックスペース文字「\ b」のテストも必要ありません。私はあなたの最初のKeyListenerがバックスペースキーをフィルタリングしていると推測しています。これは間違ったアプローチであるという最初の手がかりでした。

また、無関係なことに注意して、コンポーネントの位置をハードコーディングしないでください。 LayoutManagersの使用方法を学びます。これらは使いやすく、コードのメンテナンスがはるかに簡単になります。

3
MiguelMunoz

JFormattedTextFieldを見ましたか?それはあなたが望むことをするようです。

2
arcy

JavaでJTextFieldの二重数を入力します

private boolean dot = false;
private void txtMarkKeyTyped(Java.awt.event.KeyEvent evt) {                                 
    char vChar = evt.getKeyChar();
    if (txtMark.getText().equals(""))
        dot = false;
    if (dot == false){
        if (vChar == '.') dot = true;
        else if (!(Character.isDigit(vChar)
                || (vChar == KeyEvent.VK_BACK_SPACE)
                || (vChar == KeyEvent.VK_DELETE))) {
                evt.consume();
        }
    } else {
        if (!(Character.isDigit(vChar)
                || (vChar == KeyEvent.VK_BACK_SPACE)
                || (vChar == KeyEvent.VK_DELETE))) {
                evt.consume();
        }
    }
}
2
Vũ Trung Sơn

このコードの一部。

if (((caracter < '0') || (caracter > '9'))
                    && (caracter != '\b')) {

キーイベントを消費するかどうかを決定します。ドット文字を消費しないように条件を更新する必要があります。

1
Qwerky

TextField/events/key/keytypedを右クリックします

if(!Character.isDigit(evt.getKeyChar())){
            evt.consume();}
1
SchneiderJinn

私はこのソリューションを使用してきましたが、シンプルで効率的です:

                jtextfield.addKeyListener(new KeyAdapter() {
                public void keyTyped(KeyEvent e) {
                    char vChar = e.getKeyChar();
                    if (!(Character.isDigit(vChar)
                            || (vChar == KeyEvent.VK_BACK_SPACE)
                            || (vChar == KeyEvent.VK_DELETE))) {
                        e.consume();
                    }
                }
            });
0
JTextField textField = new JTextField();
textField.setColumns(10);

textField.addKeyListener(new KeyAdapter() {
    @Override
    public void KeyTyped(KeyEvent e) {
        if (!(e.getKeyChar() >= '0' && e.getKeyChar() <= '9')) {
            e.consume();
        }
    }
})

これは私がこれまでに見つけた最も簡単な方法であり、エラーなしで動作します

0
Kickass Kicchu

//////////////

    JTextField ptoMinimoField = new JTextField();
    ptoMinimoField.addKeyListener(new KeyAdapter() {
        public void keyTyped(KeyEvent e) {
             boolean ret = true;
                try {

                    Double.parseDouble(ptoMinimoField.getText()+e.getKeyChar());
                }catch (NumberFormatException ee) {
                    ret = false;
                }


            if (!ret) {
                e.consume();
            }
        }
    });
0
Alireza Ravandi
private boolean point = false;
private void txtProductCostPriceAddKeyTyped(Java.awt.event.KeyEvent evt)   
{
    char Char = evt.getKeyChar();
    if (txtProductCostPriceAdd.getText().equals(""))
        point = false;
    if (point == false){
        if (Char == '.') point = true;
        else if (!(Character.isDigit(Char) || (Char == KeyEvent.VK_BACK_SPACE) || (Char == KeyEvent.VK_DELETE))) {
                evt.consume();
        }
    } else {
        if (!(Character.isDigit(Char) || (Char == KeyEvent.VK_BACK_SPACE) || (Char == KeyEvent.VK_DELETE))) {
                evt.consume();
        }
    }
}
0
Noiwong Suwijak

キータイプされた数字とドットだけをフィルタリングするのに役立つかもしれません

public void filterHanyaAngkaDot(Java.awt.event.KeyEvent evt){
      char c = evt.getKeyChar();
      if (! ((Character.isDigit(c) ||
              (c == KeyEvent.VK_BACK_SPACE) ||
              (c == KeyEvent.VK_DELETE))
              )&& c==KeyEvent.VK_COMMA
              )
      {
          evt.consume();
      }
 }
0
irbef
JTextField txtMyTextField = new JTextField();

numOnly(txtMyTextField);

public void numOnly(Object objSource){
    ((Component) objSource).addKeyListener(new KeyListener() {

        @Override
        public void keyTyped(KeyEvent e) {
            String filterStr = "0123456789.";
            char c = (char)e.getKeyChar();
            if(filterStr.indexOf(c)<0){
                e.consume();
            }
        }
        @Override
        public void keyReleased(KeyEvent e) {}

        @Override
        public void keyPressed(KeyEvent e) {}
    });
}

警告:この関数は、適切なJavaドキュメントガイド。

0
kulakesh