In a Java Swing desktop app. I have a number of smaller classes, all of which are made use of in an overarching App Class. One of such smaller classes is a JPanel that represents my login page. I've added a mouselistener to the login button on this page, that goes thus:
Public class loginPage extends JPanel{
String username;
boolean capturedName=false;
JTextField nameField;
...
loginButton.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
username = nameField.getText();
capturedName=true; //for redundant checking of mouse click event
System.out.println(username); //error checking
System.out.println(capturedName); //error checking
}
});
}
In a separate display class that represents my JFrame, I make the login page an attribute of said class and I instantiate this display class in my app class, after adding the login page to it. I am trying to capture the login page username attr in the App class and pass it to other methods. But when I run the code, and click on the login button, the value in the textbox isn't captured.
To error check, I tried the ff:
//Set login page GUI up
while(display.loginPage.username==null){ //this is initially true
if (display.loginPage.capturedName){ //boolean to check if button has been clicked
display.loginPage.username=display.loginPage.nameField.getText(); //intentional redundancy
String username=display.loginPage.username;
System.out.print(username);
//pass username to other methods
}
}
When I run the code, enter a name on the username textfield, and click login, the typed name and a true value for the capturedName boolean are both printed, but the
if (display.loginPage.capturedName)
condition is never fulfilled. Also when I add in print display.loginPage.username, I get a null value . What could be the reason for this discrepancy between the same values?
What could be the reason for this discrepancy between the same values?
You could have two objects of the same type, one displayed, whose state is being changed, and one not displayed that you're checking in the if block.
But again, for better help, consider creating and posting a Minimal, Complete, and Verifiable Example Program. We don't want to see your whole program, but rather you should condense your code into the smallest bit that still compiles, has no extra code that's not relevant to your problem, but still demonstrates your problem. As an aside, you will never want to use a MouseListener with a JButton as you're doing. Instead use an ActionListener as that is what it was built for.
"I've added a mouselistener to the login button" - Not a good idea, buttons should use ActionListener, see How to Write an Action Listeners and How to Use Buttons, Check Boxes, and Radio Buttons;
while(display.loginPage.username==null){ is a REALLY, REALLY bad idea which could lock up your UI and suggests that you violating the single thread rules of Swing. See Concurrency in Swing for more details.
What it sounds like you need is a modal dialog, which can block the execution of the code at the point the dialog is made visible...
See How to Make Dialogs for more details
Take a look at Java and GUI - Where do ActionListeners belong according to MVC pattern? for an example of a Login dialog/form using the MVC paridigm (Model-View-Controller)
Turns out as #MadProgrammer suggested, that I was creating two different loginPage objects in my display class. It's curious, however, that the mouselistener on the login page GUI that was visible actually listened for, and returned expected results of the better defined login page object (which was invisible).
Related
I have written an application in Java that has a JFrame with options. I now want a certain action to be executed when the user has confirmed the dialog with "Ok". I was recommended to add a return value to JFrame.
Unfortunately, I don't have any experience and need some help. Here are the details.
I want to extend JFrame so that I can have an Enum "DialogResult" when closing a JFrame like in the .Net Framework. Well, the Enum is no problem. My problem is to replicate the ShowDialog method from WinForms of the .Net Framework working in Java for the class JFrame.
Below is an example code in C#:
// DlgOptions : Form
DlgOptions dlg = new DlgOptions();
if(dlg.ShowDialog() == DialogResult.Ok)
{
// do something only when "Ok" was clicked
}
Here's a link from MSDN with the behavior I want to replicate:
https://msdn.microsoft.com/de-de/library/c7ykbedk(v=vs.110).aspx
How can I best implement this? Thanks in advance.
EDIT:
I changed my DlgOptions class so it doesn't extend JFrame but JDialog. I also added an enumeration DialogResult and added a public property of this type in my DlgOptions. But I still have a problem. When I use this code:
// executed when user clicked a JMenuItem in a JMenuBar
DlgOptions dlg = new DlgOptions();
dlg.setModal(true);
dlg.setVisible(true);
if(dlg.DialogResult == DialogResult.OK)
{
// do something
}
the program continues running before the user closed the modal dialog. What can I do?
EDIT 2:
My JDialog contains two JButtons; one to confirm changes that were made and one to abort changing the preferences for the program. I have several JCheckBoxes the user can check or uncheck.
So a JOptionPane would not be what I want / need (as far as I know). That's why I need a modal JDialog. But my Java code above doesn't work as I want it to. I read on a German website of a Java book that a JDialog set to modal with
setModal(true);
would cause the program to wait until the dialog is closed. The problem is, that the code continues too early.
Hey I'm working on a java project, I'll try yo generalize my problem so...
I have a jpanelX that contains jbuttons1 to 5. All these jbuttons connect to the same actionlistener and the same action performed method. I also save the source of the button clicked into a global string variable.
I have another JpanelY. JpanelY contains arrays of strings.
I want to connect the two with this behavior:
user clicks button1 on JpanelX
JpanelY is shown instead of JpanelX. aka the user is taken to JpanelY
the string array in JpanelY will contain different values based on the clicked Jbutton. So if a user clicks Jbutton1, the array will be assigned values {"Value1 ","value 1b","value1c"}
i tried a lot of things and got different errors. please help me, thank you so much
It's a bad idea to save anything in a global string variable. Much better is to call a method in the panel you wish to display that assigns the correct values to your string array.
A user can be 'taken to' a panel in lots of different ways. You could hide the current panel and show the new one (setVisible(true/false)), you could use a layout manager that allows different panels to be displayed in the same space, you could change the contents of the containing panel. You'll need to give more details of what you want.
Depending on what you need, you might end up with code like:
button1.addActionListener(ae-> showValues("val1", "val2");
button2.addActionListener(ae-> showValues("val3", "val4", "val5");
private void showValues(String... values) {
setVisible(false);
arrayPanel.setArray(values);
arrayPanel.setVisible(true);
}
I have a problem about modify button background. I am using netbeans gui builder for build form. I am trying change button background when the second frame is open and turn it back when second frame close.
public void update(boolean x){
if(x==true){
circleButton.setOpaque(true);
circleButton.setBackground(new java.awt.Color(0, 0, 0));
System.out.println("testoutput");
}
}
this is my update method from first class.
I added window listener to second frame.
private void formWindowOpened(java.awt.event.WindowEvent evt) {
isitopen = true;
//this is first class which includes button
homework hwork = new homework();
hwork.update(isitopen);
System.out.println("testoutput2");
}
I got 2 testoutput but color of the button didn't change.
What can i do to fix this issue ?
You're creating a new homework object in your formWindowOpened(...) method, one completely unrelated to the homework object that is displayed, and changing the state of the new object will have no effect on the displayed one.
A simple and WRONG solution is to use static fields or methods.
Instead one simple solution is to give the calss with your formWindowOpened(...) method a valid reference to the displayed homework object, something that can be done with a constructor parameter or a setHomework(...) method.
A much better and even simpler solution:
Make the 2nd window a modal JDialog, not a JFrame
This way homework will know when the window is open and can set its own button colors. When the 2nd window opens, program flow in the calling class is put on hold, and only resumes when the 2nd window closes -- just like using a JOptionPane.
For more on this, please see The Use of Multiple JFrames, Good/Bad Practice?
As an aside, you will want to learn and use Java naming conventions. Variable names should all begin with a lower letter while class names with an upper case letter. Learning this and following this will allow us to better understand your code, and would allow you to better understand the code of others.
Okay so I'm making a Library admin program and I have created a special frame where the user would enter details about a new book. However my method for adding a new book is in a separate class (methods). My question is how can I get the information the user enters in the text fields? Do I have to use something like getters, or is there an easier way. Also keep in mind that I am using the GUI layout (thing) in netbeans, and that I have already actually made the form. (I know it's frowned upon but I'm pressed for time and this is how we were taught.) This is a school project by the way. Thanks.
Okay so I'm making a Library admin program and I have created a special frame where the user would enter details about a new book.
Usually, a detail window should be a dialog, and likely a modal dialog. I suggest that you display this information in a modal JDialog, not a JFrame. Do this and it will make extracting information from the detail window much easier.
However my method for adding a new book is in a separate class (methods). My question is how can I get the information the user enters in the text fields? Do I have to use something like getters, or is there an easier way.
This begs the question -- what's so hard about using getters? And in fact his is exactly what I suggest that you use! Please note that your question essentially boils down to, "how can I get information on the state of one class's object from within another class's object", and for this getter methods are almost mandatory.
Also keep in mind that I am using the GUI layout (thing) in netbeans, and that I have already actually made the form. (I know it's frowned upon but I'm pressed for time and this is how we were taught.) This is a school project by the way.
This is unrelated to your current problem and should have little effect on its solution other than if you've hard-coded your "form" as a JFrame, then scrap it and re-do it as a JPanel.
I suggest:
Create an addEditBook modal JDialog
Give it getter methods to allow outside classes to be able to query its textfields for their contents.
Display the dialog from the main program.
Since it is modal the main program's code flow will pause until the dialog has been dealt with.
In your OK and Cancel button, set the dialog's state (OK_STATE or CANCEL_STATE) and close the dialog. The easiest way to do this actually is to use a JOptionPane as your modal dialog since it has mechanism for just this sort of thing. This is easily accomplished if your addEditBook is geared to create a JPanel, one that you display in the JOptionPane.
Program flow will then resume in your main program from right after where you showed the dialog
query the dialog for the contents of its fields.
For examples of the JOptionPane solutions, including option panes that request information from multiple fields similar to your window above, please see:
How can I make a JFrame modal like a JOptionPane?
Multiple input in JOptionPane.showInputDialog
Edit
You state in comment:
Oh and I was wondering how can I make the field of a normal JOptionpane input dialogue come up with a word already in it like for editing it will show the information stored already?
Please see the example answers that I have listed above as you'll see that they're not examples of a "normal JOptionPane" but rather JOptionPanes that display a GUI that you create. And just the same as it's easy to query the state of this GUI after it is displayed, it's just as easy to set the state of the GUI via setter methods before it is displayed.
My question is how can I get the information the user enters in the
text fields? Do I have to use something like getters, or is there an
easier way
You need to add actionListeners for you buttons, which means you will be overriding a method called actionPerformed. You basically need to associate your actionListeners with your 'Ok' and 'Cancel' buttons. When the 'ok' button is pressed, you should get a callback in the associated actionPerformed method. Then you should try to fetch the values of your textfiled using the getText method. Collect all the fileds and set the bean you have created to store that data. Then you can call your business logic to save/modify the books info.
When writing a graphical interface, using Java, what's the appropriate way of switching between the different windows of the application, when clicking a button for example? I.E. what are the windows supposed to be, JPanels, JFrames...? And how do all the components 'see' the 'domain controller' (the class that links the graphical package to the application logic package)?
Any guide or reference would be appreciated.
You start your application with your Controller. In the constructor of your controller, you are going to initialize the first GUI you want to open, lets say GUI_A:
private GUI_A gui_a = null;
Controller() {
gui_a = new GUI_A(this);
}
As you might notice, I called the constructor of GUI_A with one parameter: this. this is referencing the instance of the current class, so this is type of Controller. The constructor of GUI_A has to look something like this:
private Controller controller = null;
GUI_A(Controller ctrl) {
controller = ctrl;
}
This is a simple way to get the GUI known to the Controller.
The next thing you would do is displaying GUI_A:
gui_a.setVisible(true);
If you now want to handle button-clicks, you would do it like this:
First, you add the action-performed method to your button. And, as it is best practice in MVC, you don't want to do logic in your view/GUI. So you also create a corresponding method in your Controller for the action-performed, and call it from your GUI:
// Controller
GUI_A_button1_actionPerformed(ActionEvent evt) {
// Add your button logic here
}
// GUI_A
button1_actionPerformed(ActionEvent evt) {
controller.GUI_A_button1_actionPerformed(evt);
}
Usually you don't need to pass the ActionEvent-var to the Controller, as you will not need it often. More often you would read a text out of a TextField and pass it on to your Controller:
// Controller
GUI_A_button1_actionPerformed(String text) {
// Add logic for the text here
}
// GUI_A
button1_actionPerformed(ActionEvent evt) {
controller.GUI_A_button1_actionPerformed(textField1.getText());
}
If you now want to access some fields on your GUI_A from the Controller, be sure not to mark the fields as public in your GUI, but to create public methods which handle how to display the values.
The preferable way is using Actions. You can attach action to each control. When user action happens (e.g. click on button) the appropriate Action is called. Actions can delegate calls deeper into the application logic and call graphical components (JFrams, etc).
suggestion: use tabbed-panel should do this, JPanel is just a Java container, while JFrame should be the outside windows, they are different things. there should be several JPanels on top of One JFrame. your app can have multiple JFrames.
When writing a graphical interface, using Java, what's the appropriate way of switching between the different windows of the application, when clicking a button for example?
Add an ActionListener to the button. In the actionPerformed(ActionEvent) method, do what needs to be done.
I.E. what are the windows supposed to be, JPanels, JFrames...?
I would recommend making the main window a JFrame and using either a JDialog or JOptionPane for most of the other elements. Alternately, multiple GUI elements can be added into a single space in a number of ways - CardLayout, JTabbedPane, JSplitPane, JDesktopPane/JInternalFrame, ..
And how do all the components 'see' the 'domain controller' (the class that links the graphical package to the application logic package)?
One way is to pass a reference to the object between the UIs.