I'm new to programming and am trying my hand at swing. I have a JFrame that serves as as the default menu, and I have a JPanel that appears in it to handle logins. After a successful login the JPanel is supposed to send the login information to JFrame so it knows who is currently logged in.
The problem is that the JButton, when clicked, is activating the send portion(whose code is the JFrame) before the JPanel has the chance to check the credentials. They are both using the same actionlistener so I don't know how to control the order.
public class GUIFrame extends JFrame {
private DetailsPanel detailsPanel;
private String curUsername;
public GUIFrame(String title){
super(title);
detailsPanel = new DetailsPanel();
setLayout(new BorderLayout());
Container c = getContentPane();
c.add(detailsPanel, BorderLayout.EAST);
detailsPanel.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (!(detailsPanel.getCurUsername() == "")){
randomToBeImplementedFunctionThatWillLogIn();
//TODO:
// The check here happens BEFORE the detailsPanel processes everything
// so the first time they create an account it won't log them in
// and every subsequent time the PREVIOUS login creds will be used.
}
}
});
public class DetailsPanel extends JPanel {
private HashMap<String, String> logInMap = new HashMap<String, String>();
private String curUsername = "";//the current logged in username
public String getCurUsername(){
return curUsername;
}
JTextField nameField;
JTextField passField;
public DetailsPanel(){
nameField = new JTextField(0);
passField = new JTextField(0);
logIn.addActionListener( (e) -> {//login attempted
if (logInMap.containsKey(nameField.getText())){
if (passField.getText().equals(logInMap.get(nameField.getText()))){
//logged in
curUsername = nameField.getText();
}
else{
//wrong password, logged out
curUsername = "";
}
}
else {
logInMap.put(nameField.getText(), passField.getText());
curUsername = nameField.getText();
//create new account
}
} );
GridBagConstraints gCons = new GridBagConstraints();
gCons.gridy = 0;
gCons.gridx = 0;
add(nameField, gCons);
gCons.gridy = 1;
add(passField, gCons);
}
public void addActionListener(ActionListener al)
{
logIn.addActionListener(al);
}
}
on a successful login, DetailsPanel is supposed to send information to GUIFrame, and then GUIFrame logs in.
Instead, when actionlistener occurs, the GUIFrame attemps to login before DetailsPanel gets to check the credentials and send it to GUIFrame.
Is there a way to get the DetailsPanel.addActionListener() to come AFTER the logIn.addActionListener()?
The order of events is generally not guaranteed. Observationally, they tend to be trigged in FILO (first in, last out) order.
A better solution would be to decouple the process, so any interested parties are not reliant on the button action, but instead on the component telling them when the validation has occurred.
A "simple" solution is to use the existing API functionality
public class DetailsPanel extends JPanel {
private HashMap<String, String> logInMap = new HashMap<String, String>();
private String curUsername = "";//the current logged in username
public String getCurUsername() {
return curUsername;
}
JTextField nameField;
JTextField passField;
JButton logIn;
public DetailsPanel() {
nameField = new JTextField(0);
passField = new JTextField(0);
logIn.addActionListener((e) -> {//login attempted
if (logInMap.containsKey(nameField.getText())) {
if (passField.getText().equals(logInMap.get(nameField.getText()))) {
//logged in
curUsername = nameField.getText();
fireActionPerformed();
} else {
//wrong password, logged out
curUsername = "";
}
} else {
logInMap.put(nameField.getText(), passField.getText());
curUsername = nameField.getText();
//create new account
}
});
GridBagConstraints gCons = new GridBagConstraints();
gCons.gridy = 0;
gCons.gridx = 0;
add(nameField, gCons);
gCons.gridy = 1;
add(passField, gCons);
}
public void addActionListener(ActionListener al) {
listenerList.add(ActionListener.class, al);
}
protected void fireActionPerformed() {
ActionListener[] listeners = listenerList.getListeners(ActionListener.class);
if (listeners.length == 0) {
return;
}
ActionEvent evt = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "validated");
for (ActionListener listener : listeners) {
listener.actionPerformed(evt);
}
}
}
So, basically, or this does, is stores the "registered" ActionListener
s in the available listenerList
. This is API provided by Swing available to all Swing components.
When the button is clicked and the identity verified, all registered parties are notified, via the fireActionPerformed
method.
A more complete solution would probably involve your own event listener interface
which could include validationSuccess
and validationUnsuccessful
and could pass back the user credentials as part of the event object
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.