addActionListenerの著名クラスとラムダ式について
解決したいこと
下記に記載する文の、ラムダ式の箇所について詳細を教えて頂きたいです。
public class Button extends JPanel{
JButton login = new JButton("ログイン");//ログインボタン
JButton clear = new JButton("クリア");//クリアボタン
//コンストラクタ
public Button(UserId uid/*ユーザーIDを表示するクラス*/, PassWord pw/*パスワードを表示するクラス*/) {
this.setLayout(new BoxLayout(this,BoxLayout.X_AXIS));
this.add(login);
this.add(clear);
String id = uid.getText();
String pass = pw.getPass();
//問題の箇所
login.addActionListener(e -> {
if(id.equals("minato") && pass.equals("yusuke")) {
JOptionPane.showMessageDialog
(this,"ログイン成功","ログインに成功しました",JOptionPane.INFORMATION_MESSAGE);
}else {
JOptionPane.showMessageDialog
(this,"ログイン失敗","ログインに失敗しました",JOptionPane.INFORMATION_MESSAGE);
}
});
現在勉強している参考書の問題は下記の通りです。
※該当するところを抜粋して記載致します。
①次のような動作をするようイベントハンドラを追加せよ。
・「ログイン」ボタンを押す際、ユーザー名がminatoかつ、パスワードがyusuke場合、ログイン成功のダイアログ、それ以外はログイン失敗のダイアログが表示される。
完成状態
該当するソースコード①(ユーザーIDの箇所のクラス)
public class UserId extends JPanel {
JLabel userID = new JLabel("ユーザー名");
JTextField idField = new JTextField();
public UserId() {
this.setLayout(new BorderLayout());
this.add(userID,BorderLayout.WEST);
this.add(idField,BorderLayout.CENTER);
}
//getter
public String getText() {
return this.idField.getText();
}
//setter
public void setText(String newValue) {
this.idField.setText(newValue);
}
}
該当するソースコード②(パスワードの箇所のクラス)
public class PassWord extends JPanel {
JLabel passWord = new JLabel("パスワード");
JPasswordField passField = new JPasswordField();
public PassWord() {
this.setLayout(new BorderLayout());
this.hidePass();
this.add(passWord,BorderLayout.WEST);
this.add(passField,BorderLayout.CENTER);
}
//getter
public String getPass() {
return String.valueOf(this.passField.getPassword());
}
//setter
public void setPass(String newValue) {
this.passField.setText(newValue);
}
}
自分で試したこと
現在著名クラス・及びラムダ式の部分に関しては、下記のように認識しております。
・著名クラス
メソッドの呼び出し等の際、クラスの宣言とインスタンス化をするもの。
今回は、addActionListenerクラスを実装した他クラスの作成を省く為に利用している。
login.addActionListener(new ActionListenerをを実装したクラスのインスタンス);
//著名クラス
login.addActionListener(new ActionListener()/* ← クラスの宣言とインスタンス化*/{
public void actionPerformed(ActionEvent e){// ← メンバの宣言と処理
//処理したい内容(if文の箇所)
}
})
・ラムダ式
関数の定義と即時生成。
addActionListenerがactionPerformedメソッド一つしか持たないので、
ラムダ式でクラスとメソッドを省略。
//著名クラス
login.addActionListener(e -> {
//処理したい内容(if文の箇所)
})
そこで、自分が著名クラスにして記載をしようとした内容が下記です。
//宣言はButtonクラスのコンストラクタ内
login.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
if(id.equals("minato") && pass.equals("yusuke")) {
JOptionPane.showMessageDialog
(this,"ログイン成功","ログインに成功しました",JOptionPane.INFORMATION_MESSAGE);
}else {
JOptionPane.showMessageDialog
(this,"ログイン失敗","ログインに失敗しました",JOptionPane.INFORMATION_MESSAGE);
}
}
})
このように記載すると、showMessageDialogの部分でエラーが出ます。
内容は、thisがJPanelを継承しているButtonクラスのインスタンスではなく、著名クラスで宣言しているnew ActionListener()に向いており、引数が対応していないというエラーです。
コードも自分の認識も恐らく間違っているかと思いますが、ラムダ式だとうまくいき、著名クラスの方法ではエラーが起きる理由がわからない状態で、なぜ処理に差があるのかが知りたいです。
正解のラムダ式はクラスを作らず関数の処理を行なっているからthisがしっかり機能しているという事になるのでしょうか。
また、もしthisを生かしたまま著名クラスで記載をする場合はどのようになるのでしょうか。
長文で申し訳ございませんが、ご教示の程宜しくお願い致します。