質問

ユーザーがテキストフィールドの値を変更した直後にメッセージボックスを表示したいと思います。現在、Enterキーを押して、メッセージボックスを表示してポップアウトする必要があります。私のコードに何か問題がありますか?

textField.addActionListener(new java.awt.event.ActionListener() {
    public void actionPerformed(java.awt.event.ActionEvent e) {

        if (Integer.parseInt(textField.getText())<=0){
            JOptionPane.showMessageDialog(null,
                    "Error: Please enter number bigger than 0", "Error Message",
                    JOptionPane.ERROR_MESSAGE);
        }       
    }
}

どんな助けも感謝します!

役に立ちましたか?

解決

根本的なドキュメントにリスナーを追加します。これは自動的に作成されます。

// Listen for changes in the text
textField.getDocument().addDocumentListener(new DocumentListener() {
  public void changedUpdate(DocumentEvent e) {
    warn();
  }
  public void removeUpdate(DocumentEvent e) {
    warn();
  }
  public void insertUpdate(DocumentEvent e) {
    warn();
  }

  public void warn() {
     if (Integer.parseInt(textField.getText())<=0){
       JOptionPane.showMessageDialog(null,
          "Error: Please enter number bigger than 0", "Error Message",
          JOptionPane.ERROR_MESSAGE);
     }
  }
});

他のヒント

これに対する通常の答えは、「使用してください DocumentListener"。しかし、私は常にインターフェイスが面倒です。正直なところ、インターフェイスは過剰にエンジニアリングされています。テキストの挿入、削除、交換のための3つの方法があります。テキストを何らかのテキストに置き換え、削除をテキストなしでテキストの置き換えと見なすことができます。

通常、あなたが望むのは知っておくことだけです ボックス内のテキストが変更されたとき, 、だから典型的な DocumentListener 実装には、1つのメソッドを呼び出す3つのメソッドがあります。

したがって、次のユーティリティ方法を作成しました。 ChangeListener ではなく DocumentListener. 。 (Java 8のLambda構文を使用しますが、必要に応じて古いJavaに適応できます。)

/**
 * Installs a listener to receive notification when the text of any
 * {@code JTextComponent} is changed. Internally, it installs a
 * {@link DocumentListener} on the text component's {@link Document},
 * and a {@link PropertyChangeListener} on the text component to detect
 * if the {@code Document} itself is replaced.
 * 
 * @param text any text component, such as a {@link JTextField}
 *        or {@link JTextArea}
 * @param changeListener a listener to receieve {@link ChangeEvent}s
 *        when the text is changed; the source object for the events
 *        will be the text component
 * @throws NullPointerException if either parameter is null
 */
public static void addChangeListener(JTextComponent text, ChangeListener changeListener) {
    Objects.requireNonNull(text);
    Objects.requireNonNull(changeListener);
    DocumentListener dl = new DocumentListener() {
        private int lastChange = 0, lastNotifiedChange = 0;

        @Override
        public void insertUpdate(DocumentEvent e) {
            changedUpdate(e);
        }

        @Override
        public void removeUpdate(DocumentEvent e) {
            changedUpdate(e);
        }

        @Override
        public void changedUpdate(DocumentEvent e) {
            lastChange++;
            SwingUtilities.invokeLater(() -> {
                if (lastNotifiedChange != lastChange) {
                    lastNotifiedChange = lastChange;
                    changeListener.stateChanged(new ChangeEvent(text));
                }
            });
        }
    };
    text.addPropertyChangeListener("document", (PropertyChangeEvent e) -> {
        Document d1 = (Document)e.getOldValue();
        Document d2 = (Document)e.getNewValue();
        if (d1 != null) d1.removeDocumentListener(dl);
        if (d2 != null) d2.addDocumentListener(dl);
        dl.changedUpdate(null);
    });
    Document d = text.getDocument();
    if (d != null) d.addDocumentListener(dl);
}

リスナーをドキュメントに直接追加するのとは異なり、これはテキストコンポーネントに新しいドキュメントオブジェクトをインストールする(珍しい)ケースを処理します。さらに、上記の問題を中心に動作します ジャン・マルク・アステサナの答え, 、ドキュメントが必要以上に多くのイベントを発射する場合があります。

とにかく、この方法では、次のように見える迷惑なコードを置き換えることができます。

someTextBox.getDocument().addDocumentListener(new DocumentListener() {
    @Override
    public void insertUpdate(DocumentEvent e) {
        doSomething();
    }

    @Override
    public void removeUpdate(DocumentEvent e) {
        doSomething();
    }

    @Override
    public void changedUpdate(DocumentEvent e) {
        doSomething();
    }
});

と:

addChangeListener(someTextBox, e -> doSomething());

パブリックドメインにリリースされたコード。楽しむ!

ユーザーがフィールドを変更すると、DocumentListenerが2つのイベントを受信できることに注意してください。たとえば、ユーザーがフィールドコンテンツ全体を選択し、キーを押して、removeUpDate(すべてのコンテンツが削除されます)とInsertUpDateを受信します。あなたの場合、私はそれが問題だとは思いませんが、一般的に言えば、そうです。残念ながら、JTextfieldをサブクラス化せずにテキストフィールドのコンテンツを追跡する方法はないようです。 「テキスト」プロパティを提供するクラスのコードは次のとおりです。

package net.yapbam.gui.widget;

import javax.swing.JTextField;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;

/** A JTextField with a property that maps its text.
 * <br>I've found no way to track efficiently the modifications of the text of a JTextField ... so I developed this widget.
 * <br>DocumentListeners are intended to do it, unfortunately, when a text is replace in a field, the listener receive two events:<ol>
 * <li>One when the replaced text is removed.</li>
 * <li>One when the replacing text is inserted</li>
 * </ul>
 * The first event is ... simply absolutely misleading, it corresponds to a value that the text never had.
 * <br>Anoter problem with DocumentListener is that you can't modify the text into it (it throws IllegalStateException).
 * <br><br>Another way was to use KeyListeners ... but some key events are throw a long time (probably the key auto-repeat interval)
 * after the key was released. And others events (for example a click on an OK button) may occurs before the listener is informed of the change.
 * <br><br>This widget guarantees that no "ghost" property change is thrown !
 * @author Jean-Marc Astesana
 * <BR>License : GPL v3
 */

public class CoolJTextField extends JTextField {
    private static final long serialVersionUID = 1L;

    public static final String TEXT_PROPERTY = "text";

    public CoolJTextField() {
        this(0);
    }

    public CoolJTextField(int nbColumns) {
        super("", nbColumns);
        this.setDocument(new MyDocument());
    }

    @SuppressWarnings("serial")
    private class MyDocument extends PlainDocument {
        private boolean ignoreEvents = false;

        @Override
        public void replace(int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
            String oldValue = CoolJTextField.this.getText();
            this.ignoreEvents = true;
            super.replace(offset, length, text, attrs);
            this.ignoreEvents = false;
            String newValue = CoolJTextField.this.getText();
            if (!oldValue.equals(newValue)) CoolJTextField.this.firePropertyChange(TEXT_PROPERTY, oldValue, newValue);
        }

        @Override
        public void remove(int offs, int len) throws BadLocationException {
            String oldValue = CoolJTextField.this.getText();
            super.remove(offs, len);
            String newValue = CoolJTextField.this.getText();
            if (!ignoreEvents && !oldValue.equals(newValue)) CoolJTextField.this.firePropertyChange(TEXT_PROPERTY, oldValue, newValue);
        }
    }

documentlistenerを拡張し、すべてのdocumentlistenerメソッドを実装するインターフェイスを作成するだけです。

@FunctionalInterface
public interface SimpleDocumentListener extends DocumentListener {
    void update(DocumentEvent e);

    @Override
    default void insertUpdate(DocumentEvent e) {
        update(e);
    }
    @Override
    default void removeUpdate(DocumentEvent e) {
        update(e);
    }
    @Override
    default void changedUpdate(DocumentEvent e) {
        update(e);
    }
}

その後:

jTextField.getDocument().addDocumentListener(new SimpleDocumentListener() {
    @Override
    public void update(DocumentEvent e) {
        // Your code here
    }
});

または、ラムダ式を使用することもできます。

jTextField.getDocument().addDocumentListener((SimpleDocumentListener) e -> {
    // Your code here
});

私はこれが本当に古い問題に関連していることを知っていますが、それは私にもいくつかの問題を引き起こしました。として クレオパトラ 上記のコメントで応答し、私は問題を解決しました JFormattedTextField. 。ただし、ソリューションにはもう少し作業が必要ですが、よりきちんとしています。

JFormattedTextField デフォルトでは、フィールドにテキストが変更されるたびにプロパティの変更をトリガーしません。のデフォルトのコンストラクター JFormattedTextField フォーマッタは作成しません。

ただし、OPが提案したことを行うには、フォーマッタを使用する必要があります。 commitEdit() フィールドの有効な各編集後のメソッド。 commitEdit() 方法は、私が見ることができるものからプロパティの変更をトリガーするものであり、フォーマッタなしでは、これはフォーカスの変更またはEnterキーが押されたときにデフォルトでトリガーされます。

見る http://docs.oracle.com/javase/tutorial/uiswing/components/formattedtextfield.html#value 詳細については。

デフォルトのフォーマッタを作成します(DefaultFormatter)に渡されるオブジェクト JFormattedTextField コンストラクターまたはセッターメソッドを介して。デフォルトのフォーマッタの1つの方法は次のとおりです setCommitsOnValidEdit(boolean commit), 、フォーマッタを設定してトリガーします commitEdit() テキストが変更されるたびにメソッド。これは、aを使用してピックアップできます PropertyChangeListener そしてその propertyChange() 方法。

Codemwnciの更新バージョンでした。彼のコードは非常に順調で、エラーメッセージを除いてうまく機能します。エラーを回避するには、条件ステートメントを変更する必要があります。

  // Listen for changes in the text
textField.getDocument().addDocumentListener(new DocumentListener() {
  public void changedUpdate(DocumentEvent e) {
    warn();
  }
  public void removeUpdate(DocumentEvent e) {
    warn();
  }
  public void insertUpdate(DocumentEvent e) {
    warn();
  }

  public void warn() {
     if (textField.getText().length()>0){
       JOptionPane.showMessageDialog(null,
          "Error: Please enter number bigger than 0", "Error Massage",
          JOptionPane.ERROR_MESSAGE);
     }
  }
});
textBoxName.getDocument().addDocumentListener(new DocumentListener() {
   @Override
   public void insertUpdate(DocumentEvent e) {
       onChange();
   }

   @Override
   public void removeUpdate(DocumentEvent e) {
      onChange();
   }

   @Override
   public void changedUpdate(DocumentEvent e) {
      onChange();
   } 
});

しかし、私はユーザーが彼のキーボードに触れているだけではありません。 Integer. 。キャッチする必要があります Exceptionスローして、確認してください JTextField 空ではありません。

「MouseExited」も使用して制御できます。例:

 private void jtSoMauMouseExited(java.awt.event.MouseEvent evt) {                                    
        // TODO add your handling code here:
        try {
            if (Integer.parseInt(jtSoMau.getText()) > 1) {
                //auto update field
                SoMau = Integer.parseInt(jtSoMau.getText());
                int result = SoMau / 5;

                jtSoBlockQuan.setText(String.valueOf(result));
            }
        } catch (Exception e) {

        }

    }   

ActionListener(Enterでトリガーする)ではなく、KeyListener(任意のキーでトリガー)を使用します。

私はWindowbuilderの真新しく、実際には数年後にJavaに戻ってきましたが、「何か」を実装して、それを調べてこのスレッドに出くわしました。

私はこれをテストしている最中にいるので、これらすべてに新しいことに基づいて、私は何かを見逃しているに違いないと確信しています。

これが私がしたことです。「runtxt」はテキストボックスであり、「runname」はクラスのデータメンバーです。

public void focusGained(FocusEvent e)
    {
    if (e.getSource() == runTxt)
        {
        System.out.println("runTxt got focus");
        runTxt.selectAll();
        }
    }
public void focusLost(FocusEvent e)
    {
    if (e.getSource() == runTxt)
        {
        System.out.println("runTxt lost focus");
        if(!runTxt.getText().equals(runName))runName= runTxt.getText();
        System.out.println("runText.getText()= " + runTxt.getText() + "; runName= " + runName);
        }
    }

これまでのところここにあるものよりもはるかに簡単に思えますが、機能しているようですが、私はこれを書いている最中に、見落とされがちなゴッチャを聞いてくれてありがとう。ユーザーが変更を加えてテキストボックスを入力して出て行くことができるのは問題ですか?あなたがしたのは不必要な割り当てだけだと思います。

runnableメソッドを使用する場合、swhingutilities.invokelater()ドキュメントリスナーアプリケーションを使用しているときに、時々立ち往生し、結果を更新するのに時間がかかります(私の実験に従って)。それの代わりに、前述のようにテキストフィールド変更リスナーにキーリリースされたイベントを使用することもできます ここ.

usernameTextField.addKeyListener(new KeyAdapter() {
        public void keyReleased(KeyEvent e) {
            JTextField textField = (JTextField) e.getSource();
            String text = textField.getText();
            textField.setText(text.toUpperCase());
        }
    });

documentfilter ?それはあなたに操作する能力を与えます。

[ http://www.java2s.com/tutorial/java/0240__swing/formatjtextfieldstexttouppercase.htm ]

ごめん。 JはJython(JavaのPython)を使用しています - しかし理解しやすい

# python style
# upper chars [ text.upper() ]

class myComboBoxEditorDocumentFilter( DocumentFilter ):
def __init__(self,jtext):
    self._jtext = jtext

def insertString(self,FilterBypass_fb, offset, text, AttributeSet_attrs):
    txt = self._jtext.getText()
    print('DocumentFilter-insertString:',offset,text,'old:',txt)
    FilterBypass_fb.insertString(offset, text.upper(), AttributeSet_attrs)

def replace(self,FilterBypass_fb, offset, length, text, AttributeSet_attrs):
    txt = self._jtext.getText()
    print('DocumentFilter-replace:',offset, length, text,'old:',txt)
    FilterBypass_fb.replace(offset, length, text.upper(), AttributeSet_attrs)

def remove(self,FilterBypass_fb, offset, length):
    txt = self._jtext.getText()
    print('DocumentFilter-remove:',offset, length, 'old:',txt)
    FilterBypass_fb.remove(offset, length)

// (java style ~example for ComboBox-jTextField)
cb = new ComboBox();
cb.setEditable( true );
cbEditor = cb.getEditor();
cbEditorComp = cbEditor.getEditorComponent();
cbEditorComp.getDocument().setDocumentFilter(new myComboBoxEditorDocumentFilter(cbEditorComp));
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top