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);
}
Related
I'm newish to programming so there might be something obvious I don't know of that's a solution to this.
I'm currently writing a program that tests the user on words that they've entered before. When the user is entering words, the screen shows a jtextfield and jtextarea among other things for adding a word and it's definition and a variable is set to the constant NOT_TESTING to remember that that's the screen being displayed. My question is, when I want to switch screens to show the testing screen which has a jlabel displaying the word and a different jtextfield to write the definition of a word, what's the best way to not show the jtextfield and jtextarea from the screen where the user submits a word? (I'm not sure screen is the proper term, but I'm using it anyway.) If I don't make the components instnace variables, then I can't remove them when making a different screen, but it seems ridiculous to make them instance variables and then remove them whenever I switch screens, create new objects when going back to the old screen, and have so many instance variables.
Sorry for the long explanation, basically my question is: what's the best way to not show objects from previous screens when drawing a new screen?
Take a look at CardLayout, which allows multiple JPanels to be shown without the other one showing (basically, it makes the entire window that panel and you can switch between them).
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).
I will do my best to explain-- I am trying to make a choose-your-own-adventure type game while using a TextField and a TextArea, where what is written in the TextField is appended into the TextArea (this I know how to do via ActionListener).
However, I need to have the TextArea start with a pre-written 'intro', which asks the user at the end if they want to continue or not. Therefore, I need it to be able to scan the user's response ('yes' or 'no') and choose the appropriate selection of pre-written text to follow.
I don't want to overwrite what is already in the TextArea, I want to add to it. I suppose what I'm confused about it how I'm supposed to lay out the entire file so that it functions properly, because the different choices for the adventure span different methods. Having
"String text = textField.getText();" only within the actionPerformed method means I can't use 'text' elsewhere, but moving that line up with my other variables tells me it can't reference the field before it's defined.
I am fairly new to Java and am working on this as a project for a non-programming school course. I've been through many iterations thus far and this is what seems to be my final attempt, as I've remade it repeatedly and don't have much time left. :(
Your questions/comments and my attempts to answer:
I am trying to make a choose-your-own-adventure type game while using a TextField and a TextArea, where what is written in the TextField is appended into the TextArea (this I know how to do via ActionListener).
As per my comment, be sure to create a Swing GUI which would use a JTextField and a JTextArea. You would then add your java.awt.event.ActionListener to the JTextArea, and the ActionListener would respond whenever the user pressed <ENTER> within the JTextField.
However, I need to have the TextArea start with a pre-written 'intro', which asks the user at the end if they want to continue or not. Therefore, I need it to be able to scan the user's response ('yes' or 'no') and choose the appropriate selection of pre-written text to follow.
This can be done easily, but sounds as if you may be trying to shoe-horn a linear console type program into a GUI. If so, consider reconsidering your program design since what works best for one often doesn't work well for another. If you do re-write, then you should consider redoing most including your program flow, but excepting perhaps the "model" portion of your previous program, the "business logic" that underlies everything.
I don't want to overwrite what is already in the TextArea, I want to add to it. I suppose what I'm confused about it how I'm supposed to lay out the entire file so that it functions properly, because the different choices for the adventure span different methods. Having "String text = textField.getText();" only within the actionPerformed method means I can't use 'text' elsewhere, but moving that line up with my other variables tells me it can't reference the field before it's defined.
Again as per comments a JTextArea has an append(String text) method that will add new text to existing text that is already displayed in your JText Area. So on that note, your ActionListener's actionPerformed method could be very simple and look something like:
public void actionPerformed(ActionEvent e) {
String text = textField.getText();
textArea.append(text):
}
Although you may need to add line feeds, "\n" either before and/or after the text you are going to append.
I created a simple app in Netbeans, it contains a few textfields for user input and a button, I've associated an action with the button through the Netbeans interface but I decided to define the action in the App and not the View so as to follow some notion of MVC.
The action works fine, I can print out the console every time the button is clicked.
But in order to do what I want, I need the values included in the jTextFields!
How to do this? This is the code in TestApp.java:
#Action
public void ClickedOnButton() {
System.out.println("Clicked ok");
System.out.println("Will now attempt to read notes.ini");
ReadNotesFile();
}
And this is the code in TestView.java:
javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(tpa_fixer.TPA_FixerApp.class).getContext().getActionMap(TPA_FixerView.class, this);
jButton1.setAction(actionMap.get("ClickedOnButton")); // NOI18N
What have you tried, and how doesn't it work? The standard way to get a JTextField to display text is to call setText() on it. Have you tried doing this?
Also,
Have you gone through the Swing tutorial about these concepts including using text components, JButtons, and ActionListeners?
Are you seeing any errors in these attempts? If so, post them here.
Is your "control" class, the one with the listener code, separate from your "view" or GUI class? If so, does control have a valid reference to view?
Edit
You state:
I don't want to set the text in the jTextFields, I want to get the values out of them and use it in the method that gets run when I click on the button. I can't see how to do this unless I can pass arguments somehow within the body of the action definition in the View class.
What I've done in this situation, where I need to extract information out of gui fields for manipulation in other classes:
You can give each field an associated public getText() method and then call these methods using the control's reference to the view object. For instance say view has a nameField JTextField, then I'd give it a getNameFieldText() method that returns nameField.getText();.
If you had many such fields, then it may be more efficient to use just one getText method but allow it a parameter to let you choose which field to extract text from. To make this work efficiently, I've sometimes given my GUI a HashMap and then have control pass in the String key that allows the getText method to obtain the correct JTextfield, get its text and return it. I often use the same Strings used as JLabels associated with the JTextField as my key Strings.
I am trying the save the state of a previous frame and then carry it over to the other frame. More like saving the data of the textfields and areas so that when i press next button some text fields,and variables will be initialized in the next forms Labels and when you press back your previous data will still remain in your form inteface.Pls help
More like data binding but across different forms
You can use any varible for that, and pass it as parameter to every JFrame you create.
But it sounds more like you want to use a CardLayout for your JFrame and use different cards that can be shown for the user. See How to use CardLayout.
If you are trying to create a wizard like UI, you should look up Sun(oracle)tutorial here.
Use something like Java's XMLEncoder.