文字列が等しくなるのを待つ正しい方法
-
22-07-2019 - |
質問
Swingアプリでは、ユーザーが正しい答えを入力した後にのみメソッドを続行する必要があります。正しい答えは文字列に保存され、ユーザーの答えはリスナーによって別の文字列に設定されます。そのため、コードは
while (!correctAnswer.equals(currentAnswer)) {
// wait for user to click the button with the correct answer typed into the textfield
}
// and then continue
このアプローチで問題はありませんか、それとも何らかの形でリファクタリングしますか? CPUに余分なペナルティを課しませんか? 以下はやや同様の質問。
解決
UIプログラミングは初めてですか?私が尋ねる理由は、あなたの答えは手続き型のコーディングに基づいていることです。これはUIの目的ではありません。イベント駆動型である傾向があります。
この場合、ソリューションは非常に簡単です。送信ボタンにイベントリスナー(ActionListener)を追加し、そこで結果を確認します。よければ、続けてください。そうでない場合は、そう言って、もう一度試してみましょう。
他のヒント
他の人が提案したように、ボタンを押すと呼び出されるボタンにリスナーを割り当てる必要があります。
ActionListener
とその actionPerformed
ボタンが押されたときに呼び出されるメソッド:
...
final JTextField textField = new JTextField();
final JButton okButton = new JButton("OK");
okButton.addActionListner(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
if ("some text".equals(textField.getText()))
System.out.println("Yes, text matches.");
else
System.out.println("No, text does not match.");
}
});
...
単に < code> ActionListener をボタンとテキストフィールドが存在するクラスで使用するため、2つのオブジェクトを final
として宣言する必要はありません。 (例を短くするために、匿名の内部クラスを使用しました。)
詳細については、 Javaチュートリアルのアクションリスナーを作成する方法 >。
また、Javaでのイベントの動作に関する一般情報については、レッスン:Javaチュートリアルのイベントリスナーの作成が役立つ場合があります。
編集: if
ステートメント内の式を textField.getText()。equals(&quot; some text&quot;)
からに変更しました>&quot; some text&quot; .equals(textField.getText())
textField
が null
の場合に NullPointerException
を防ぐため、シャイニー氏とニュー氏のコメントからの提案ごと。
私はそこにロジックを得るとは思わないが、それは昔の基本的な時間を思い出させる... :-)アプリケーションがユーザーに既知の何かを入力するように強制する理由がわかりません(パスワードでない限り)または何か)。
入力はリスナーによって監視されます。では、そこでテストをしてみませんか?イベントを待っているループをしないでください、Javaにそれをさせてください(および他のもの)。必要に応じて、ロジックを2つに分け、リスナーに正しい入力が与えられたことを検出したら2番目の部分に進みます。
これが理にかなっていることを望みます...;-)
はい、誰もがここで言ったように。
GUIアプリの場合、ユーザー入力を処理する最良の方法は、イベントが発生するのを待つことです。
次に、メソッドを使用して入力を検証し、成功した場合はフローを続行でき、別のページに移動できます。
これは、ユーザー入力を検証し、成功した場合に何らかのアクションを実行するログイン画面の完全な(ただし単純な)例です。
このコードには、この概念がどのように適用されるかを完全にすぐに実行できるサンプルに示す以外の値はありません。
シンプルなGUI http://img229.imageshack.us/img229/1532/simplenz0 .png
// * used for brevity. Preffer single class per import
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.net.*;
import java.io.*;
public class MatchString{
private final JTextField password;
private final JFrame frame;
public static void main( String [] args ){
MatchString.show();
}
public static void show(){
SwingUtilities.invokeLater( new Runnable(){
public void run(){
new MatchString();
}
});
}
private MatchString(){
password = new JPasswordField( 20 );
frame = new JFrame("Go to www.stackoverflow");
init();
frame.pack();
frame.setVisible( true );
}
private void init(){
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.add( new JPanel(){{
add( new JLabel("Password:"));
add( password );
}});
// This is the key of this question.
// the password textfield is added an
// action listener
// When the user press enter, the method
// validatePassword() is invoked.
password.addActionListener( new ActionListener(){
public void actionPerformed( ActionEvent e ) {
validatePassword();
}
});
}
private void validatePassword(){
// If the two strings match
// then continue with the flow
// in this case, open SO site.
if ( "stackoverflow".equals(password.getText())) try {
Desktop.getDesktop().browse( new URI("http://stackoverflow.com"));
frame.dispose();
} catch ( IOException ioe ){
showError( ioe.getMessage() );
} catch ( URISyntaxException use ){
showError( use.getMessage() );
} else {
// If didn't match.. clear the text.
password.setText("");
}
}
}
文字列がGUIレートで人間のユーザーから来ている場合、パフォーマンスを最適化する意味はほとんどありません。人間は、1秒間に1つから3つ以上の文字列を入力することはできません。これは、マシンにとっては何でもありません。
この特定のケースでは、テストのために入力を取得する必要がある場合、 do-while
ループ。