I'm building an ATM simulator and i want the PIN code to be verifyed when the ENTER key is pressed. However, i'm encountering an issue with key events not being detected in the ATM_Interface class after initializing the Authentication class. Here's the relevant part of my code:
public class Main{
public static void main(String[] args){
JFrame frame = new JFrame();
ATM_Interface atm=new ATM_Interface();
frame.setVisible(true);
frame.setDefaultCloseOperation(3);
frame.setLayout(null);
frame.add(atm);
frame.pack();
}
}
public class ATM_Interface extends JPanel {
static String Status="";
public ATM_Interface(){
this.setPreferredSize(new Dimension(200,200));
this.setBackground(Color.blue);
this.setBounds(115,67,340,340);
this.addKeyListener(new keyAdapter());
this.setFocusable(true);
Authentication auth = new Authentication();
this.requestFocusInWindow();
}
class keyAdapter extends KeyAdapter{
@Override
public void keyPressed(KeyEvent e){
switch(Status){
case "authentication":
break;
default:
add(auth);
Status="authentication";
}
System.out.println("test");
}
}
}
public class Authentication extends JPanel {
JTextField input = new JTextField();
public Authentication(){
input.setPreferredSize(new Dimension(100,50));
this.add(input);
}
public boolean getAcces(){
if(input.getText().equals("0234")){
return true;
}
else return false;
}
}
In this code, the ATM_Interface JPanel is supposed to capture key events using a KeyAdapter. However, after initializing the Authentification class and adding it as a child component to ATM_Interface, the key events are not being detected in the ATM_Interface JPanel.
I've already tried setting focus to the ATM_Interface panel using requestFocusInWindow() and setFocusable(), but it doesn't seem to resolve the issue. How can I ensure that key events are detected in the ATM_Interface JPanel? Any help would be appreciated!
I want the PIN code to be verifyed when the ENTER key is pressed
The simple answer is to use a ActionListener
which will be called when the user "actions" the text field (ie, in most cases, presses the Enter key while the field is focused)
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame("Test");
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
protected class TestPane extends JPanel {
private JTextField pinField;
public TestPane() {
setBorder(new EmptyBorder(32, 32, 32, 32));
setLayout(new GridBagLayout());
pinField = new JTextField(4);
add(pinField);
pinField.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String pinText = pinField.getText();
try {
int pinValue = Integer.parseInt(pinText);
if (pinValue != 1234) {
JOptionPane.showMessageDialog(TestPane.this, "Invalid PIN", "Error", JOptionPane.ERROR_MESSAGE);
} else {
// Now I'd use an observer here to notify interested
// parties that the pin was validated
}
} catch (NumberFormatException exp) {
JOptionPane.showMessageDialog(TestPane.this, "Invalid PIN", "Error", JOptionPane.ERROR_MESSAGE);
}
}
});
}
}
}
See:
for more details.
I would also suggest having a look at Implementing a Document Filter if you're interested in limiting what the user can input into the text field (ie real time validation). This would also allow you to "automatically" validate the PIN once it reaches the desired number of digits.
You should also take the time to learn and use the available layout managers, that's just going to save you so much time and head aches.