JFrame not "disposing" on actionperformed method - java

Background: I am creating a login browser page before my main UI(myGUI) page is displayed. I am using a HashMap to store the correct username and password combinations. The key is put in a getter method where I then access it from the LoginBrowser class constructor, where I build the actual UI.
Problem: Currently, the key values are stored correctly and login is successful. It properly loads up the main UI after the correct credentials are entered. I tried to instantiate the class with the key inside and then call the dispose method. However, the login browser UI does not go away afterwards. What is wrong with my instantiation and how would I solve it?
My current code:
Main method:
public static void main(String[] args) {
IdAndPasswords s = new IdAndPasswords();
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
LoginBrowser lb = new LoginBrowser(s.getInfo());
lb.setVisible(true);
//myGUI.requestFocusInWindow(); // makes sure textfield or other components don't auto focus on start-up
lb.setTitle("Chat App");
lb.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
});
}
Login Browser Class Contructor:
HashMap<String,String> loginInfo = new HashMap<String,String>();
/**
* Creates new form LoginBrowser
* #param loginOG
*/
public LoginBrowser(HashMap<String,String> loginOG) {
initComponents();
this.loginInfo = loginOG;
}
Login Browser Action Performed method:
/*
If login button to perform actions
when pressed
*/
private void loginBtnActionPerformed(java.awt.event.ActionEvent evt) {
if(evt.getSource()==loginBtn) {
String userIDNew = usernameText.getText(); // get text of JTextfield
String passwordNew = String.valueOf(passwordText.getPassword()); // get text of JPasswordfield and convert
if(loginInfo.containsKey(userIDNew)) { // key
// if entered characters in strings match up,
// display message and get rid of login browser
if(loginInfo.get(userIDNew).equals(passwordNew)) {
JOptionPane.showMessageDialog(rootPane, "Login successful");
IdAndPasswords s = new IdAndPasswords();
LoginBrowser lb = new LoginBrowser(loginInfo);
lb.dispose(); // dispose login browser
// Once old form is disposed, open main gui form
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
myGUI myGUI = new myGUI(userIDNew);
myGUI.setVisible(true);
//myGUI.requestFocusInWindow(); // makes sure textfield or other components don't auto focus on start-up
myGUI.setTitle("Chat App");
myGUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
});
// tell user if info entered is incorrect
} else {
JOptionPane.showMessageDialog(rootPane, "Incorrect Password");
}
} else {
JOptionPane.showMessageDialog(rootPane, "Incorrect Username");
}
}
}

Instead of instantiating class with key:
LoginBrowser lb = new LoginBrowser(loginInfo);
lb.dispose(); // dispose login browser
Simply use this. to control JFrame from within design feature of netbeans:
this.dispose();

Related

I need help closing a DialogDisplayer window in a Netbeans Platform application

I am adding to an existing codebase using the Netbeans Platform (14) and its GUI builder to display user selected data to create an output file. The user selects the inputs, then selects to generate the file using a default file name. I want to interrupt the process with a dialog presenting the user with a summary of what they entered, a TextField containing the default file name and the OK - Cancel buttons. I created a DialogDisplayer configured by a DialogDescriptor containing a JPanel which contains the summary info and file name JTextField. This all works, I see the summary data, am able to modify the file name but selecting the OK or Cancel doesn't close the window. Only the X in the upper right will close it.
My actionPerformed() method gets called and exercises the code appropriate to the selected button, but just can't figure out how to close the window from there. I tried setting the closing options to null (dd.setClosingOptions(null);) which the API says causes all action to close the window. No dice.
I don't see a method to call to close the DialogDisplayer window in the API.
I originally thought of using a JDialog but it requires a Frame, which I can't figure out how to get from a org.netbeans.spi.project.ActionProvider, the enclosing class that initiates the request. I have used Swing for more years than I care to admit (since java 1.1) but the Netbeans Platform framework is new to me.
Here is my code:
private class FileNameDialog extends JPanel implements ActionListener
{
private final JTextField fileNameField = new JTextField(50);
private final JLabel fileNameLabel = new JLabel("File Name");
private final JLabel infoLabel = new JLabel();
private final JPanel entryPanel = new JPanel(new FlowLayout());
public FileNameDialog(String fileName, String info)
{
infoLabel.setText(info);
fileNameField.setText(fileName);
setLayout(new BorderLayout());
entryPanel.add(fileNameLabel);
entryPanel.add(fileNameField);
add(BorderLayout.CENTER, infoLabel);
add(BorderLayout.PAGE_END, entryPanel);
}
#Override
public void actionPerformed(ActionEvent e)
{
if (e.getActionCommand().equals(OK_BUTTON))
{
//Replace the file name with what was entered and move on
abort = false; //Global field in enclosing class
logger.log(Level.INFO, "Setting abort to FALSE for {0}",
fileNameField.getText());
}
else if (e.getActionCommand().equals(CANCEL_BUTTON))
{
abort = true; //Global field in enclosing class
logger.log(Level.INFO, "Setting abort to TRUE");
}
//Close the Dialog Window Here (somehow)
}
}
/**
* Request text entry from the user. Currently used for displaying the
* file name and allowing the user to update it. This is the entry point
* for all this code.
* #param info summary text
* #param title window title
* #return the user entered String
*/
private String userRequestDialog(String info, String title, String fileName)
{
FileNameDialog fileNameDialog = new FileNameDialog(fileName, info);
Object [] options = { new JButton ("OK"),
new JButton ("Cancel")};
DialogDescriptor dd = new DialogDescriptor (fileNameDialog,
title,
true,
options,
null,
DialogDescriptor.DEFAULT_ALIGN,
null,
fileNameDialog);
DialogDisplayer.getDefault().notify(dd); //Display the window
dd.setClosingOptions(null); //Doesn't seem to have any effect
return fileNameDialog.fileNameField.getText(); //FileName to use as process continues
}
Just for giggles, I tried Object frame = lookup.lookup(JFrame.class); but that comes back as null.
#jjazzboss - You had the answer that solved my problem and you should get the credit.
Though it technically didn't answer the question, it allowed me to replace the Netbeans DialogDisplayer with a JOptionPane as in below. I also tried a CustomDialog modeled after the one in https://docs.oracle.com/javase/tutorial/uiswing/components/dialog.html, but the OK and Cancel buttons still didn't close it. I suspect that something in Netbeans is stealing those events because a breakpoint in the listener never got hit (or I screwed up the code).
boolean cancelled = false;
Frame frame = WindowManager.getDefault().getMainWindow();
while (!cancelled)
{
String newFileName = JOptionPane.showInputDialog(frame, info, fileName);
if (newFileName == null) //OK was not selected
{
return null;
}
else if (isValidFileName(newFileName))
{
return newFileName;
}
else
{
JOptionPane.showMessageDialog(
frame,
"Sorry, \"" + newFileName + "\" "
+ "isn't a valid file name.\n"
+ "Please Try again",
"Bad File Name",
JOptionPane.ERROR_MESSAGE);
}
}

Forcing a JPanel to repaint after calling the show method of CardLayout

I'm writing a holiday recommendation system for a piece of coursework. The GUI of which uses CardLayout. In the main class a user object is created with default name and access levels defined in it's constructor. this object is passed from main to the UserCard panel which passes it to Login and logged in.
if the user successfully logs in then the cardpanel transitions from Login to logged in and is supposed to display the username of the logged in user by calling the user.getUsername(); method.
my problem is thus. because of the way card layout works the panel with the username display has already been created in the constructor of UserCards with the default values from then the user object was first created. I need to find a way to force this panel to repaint after the show method is called on the cardlayout object. The following is the code of the 3 classes in question. (I've limited the code paste to the relevant methods).
//the usercards panel
public UserCards(User u)
{
CardLayout cl = new CardLayout();
this.setLayout(cl);
UserOptionsPanel options_card = new UserOptionsPanel(cl, this);
RegisterPanel register_card = new RegisterPanel(cl, this);
LoggedInPanel loggedin_card = new LoggedInPanel(cl, this, u);
LoginPanel login_card = new LoginPanel(cl, this, u, loggedin_card);
this.add(options_card, options);
this.add(login_card, login);
this.add(register_card, register);
this.add(loggedin_card, loggedin);
}
//the Loggin action listener user is passed in as a reference to the user object created in //main. the createUser(); method is a badly named method that simply calls setter methods on //the user object's fields
#Override
public void actionPerformed(ActionEvent e)
{
String[] vals = packData();
try
{
DBConnection d = new DBConnection();
Connection conn = d.getConnection();
Validation v = new Validation(vals, user);
v.getActual(conn);
if(v.validate())
{
user = v.createUser();
System.out.println(user.getUserName());
l.revalidate();
cl.show(pane, "loggedin");
}
else
{
lbl_statusmsg.setText("Password Incorrect");
lbl_statusmsg.repaint();
}
}
catch(ClassNotFoundException | SQLException ex)
{
ex.printStackTrace();
}
}
//the loggedin constructor
public class LoggedInPanel extends JPanel
{
private User user;
private JLabel lbl_details;
public LoggedInPanel(CardLayout cl, Container pane, User u)
{
super();
user = u;
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
lbl_details = new JLabel();
lbl_details.setText("Welcome "+user.getUserName());
this.add(lbl_details);
}
}
Apologies if I've not been overly clear I'm not given to asking for help :)
Do you mean something like ?
CardLayout cl = new CardLayout() {
#Override
public void show(java.awt.Container parent, String name) {
super.show(parent, name);
// your code here
}
};

Send a variable from a class to another one

I have a Jframe class that has a login and password fields. When loggin on, i have to display informations of the person that logged in, so i have to retrieve his login from the first Jframe to make a treatment in the other one.
Here is that i made, but the login returns NULL in the second jframe:
First Jframe (login and password fields):
private void button_connectActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
String x= loginField.getText();
String y= passwordField.getText();
AuthentificationDAO authDAO= new AuthentificationDAO();
boolean ok_login= authDAO.verify_login(x);
int pass= Integer.parseInt(y);
System.out.println("password retrieved"+pass);
boolean ok_pass=authDAO.verify_password(pass);
System.out.println("ok pass"+ok_pass);
if (ok_login & ok_pass)
{
System.out.println("Login found!");
Enseignant e= new Enseignant();
edu.app.persistence.Enseignant ens= new edu.app.persistence.Enseignant(x);
//ens.setLogin(x);
System.out.println("login SET:"+ens.getLogin());
e.setVisible(true);
this.setVisible(false);
}
else {
System.out.println("Login NOT found!");
JOptionPane.showMessageDialog(null, "Accourt NOT found. Please check your login or password.", "Check Login/Pass", 1);
}
Second Jframe that will display informations of that login:
private void mauvaisFieldFocusGained(java.awt.event.FocusEvent evt) {
edu.app.persistence.Enseignant ens= new edu.app.persistence.Enseignant();
String login=ens.getLogin();
System.out.println("LOGIN EST:"+login);
StatsDAO stats= new StatsDAO();
int id=stats.get_id_from_login(login);
System.out.println("ID="+id);
}
Any idea please of how solving that problem?
Thank you very much.
Unless ens.login is static, this code won't work.
You can use the MVC pattern or you can just make your second frame class extends JFrame, in order to add a login field to it..
Sonething like :
class1 {
class2 frame2 = new class2();
void login(){
String x = loginField.getText();
edu.app.persist.teach ens= new edu.app.persist.teach(x);
class2.setLogin(x);
}
}
class2 extends JFrame{
String login;
String getLogin(){..}
void setLogin(String s){..}
.
.
}
I've used a sort of pseudocode but it should be clear enough

How to Subscribe to GUI Events in Other JFrames

What is the best practice for subscribing to events from another JFrame? For example, I have a "settings" form, and when the user presses okay on the settings form, I want the main form to know about this so it can retrieve the settings.
Thanks.
Here is my ideal interface:
public void showSettingsButton_Click() {
frmSettings sForm = new sForm(this._currentSettings);
//sForm.btnOkay.Click = okayButtonClicked; // What to do here?
sForm.setVisible(true);
}
public void okayButtonClicked(frmSettings sForm) {
this._currentSettings = sForm.getSettings();
}
Someone publishes an Event, that something has changed, here the settings. A subscriber that registered for this specifig event, gets notified about it and can do his work, here get the settings. This is called publisher/subscriber.
For this you can use Eventbus or implementing something smaller on your own.
One approach is to have only a single JFrame. All the other 'free floating top level containers' could be modal dialogs. Access the the main GUI will be blocked until the current dialog is dismissed, and the code in the main frame can check the settings of the dialog after it is dismissed.
For anyone interested, here is what I ended up going with. I'm not sure if it's the best way, but it is working for my purposes.
// Method called when the "Show Settings" button is pressed from the main JFrame
private void showSettingsButton_Click() {
// Create new settings form and populate with my settings
frmSettings sForm = new frmSettings(this.mySettings);
// Get the "Save" button and register for its click event...
JButton btnSave = sForm.getSaveButton();
btnSave.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent evt) {
SaveSettings(sForm);
}
});
// Show the settings form
sForm.setVisible(true);
}
// Method called whenever the save button is clicked on the settings form
private void SaveSettings(frmSettings sForm) {
// Get the new settings and assign them to the local member
Settings newSettings = sForm.getSettings();
this.mySettings = newSettings;
}
And if, like me, you are coming from a .NET perspective, here is the C# version:
private void showSettingsButton_Click(object sender, EventArgs e)
{
frmSettings sForm = new frmSettings(this.mySettings);
sForm.btnSave += new EventHandler(SaveSettings);
sForm.Show();
}
private void SaveSettings(object sender, EventArgs e)
{
frmSettings sForm = (frmSettings)sender; // This isn't the exact cast you need..
Settings newSettings = sForm.Settings;
this.mySettings = newSettings;
}

Prevent browser form submission when Wicket AjaxFormValidatingBehaviour validation fails

I have a Page with a Wizard component. The user can navigate the panels of the wizard by using the next and previous buttons which I have performing full (non-ajax) form submissions so that the app is back-button friendly.
When the next button is clicked, I would like to attempt ajax form validation (if javascript is enabled). I tried doing:
nextButton.add( new AjaxFormValidatingBehavior( form, "onsubmit") );
to add such validation. The behaviour works - however, when validation errors occur the browser still submits the entire form.
What is the Wicket way to prevent the browser from submitting the form in this case?
Override the onError() method on either the form or the AjaxFormValidatingBehavior. If you do it on the behavior, I am not sure if that will prevent the form from submitting or not.
new AjaxFormValidatingBehavior( form, "onsubmit") {
public void onSubmit() {}
public void onError() {}
}
Maybe a bit to late but here is the answer:
public class SomePage extends WebPage {
private FeedbackPanel feedbackMessageError = new FeedbackPanel("feedbackTabAddEmpMesError", new ExactLevelFeedbackMessageFilter(FeedbackMessage.ERROR));
public SomePage(String id) {
final Form<Void> form = new Form<>("tabFormAddEmp");
add(form);
//Name textfield cannot be empty
final FormComponent<String> tabAddEmpName = new RequiredTextField<>("tabAddEmpName", Model.of(""));
tabAddEmpName.setLabel(Model.of("Name"));
tabAddEmpName.setOutputMarkupId(true);
//Salarynumber has to be minimal 10 char long
final FormComponent<String> tabAddEmpLoon = new RequiredTextField<>("tabAddEmpLoon", Model.of(""));
tabAddEmpLoon.add(new StringValidator(10, null)).setLabel(Model.of("Salarynumber"));
tabAddEmpLoon.setOutputMarkupId(true);
final Button button = new Button("tabFormAddEmpBut");
form.add(tabAddEmpName , tabAddEmpLoon, button);
button.add(new AjaxFormValidatingBehavior(form, "onclick") {
#Override
public void onError(AjaxRequestTarget target) {
//Add feedbackpanel to your html and voila!
target.add(feedbackMessageError);
}
#Override
protected void onSubmit(AjaxRequestTarget target) {
//Do some logic over here
}
}
}
}

Categories

Resources