return from Jframe by jbutton - java

I have Jframe that has a JTextField and a JButton. It should return text of Jtextfield to anotherClass (MainPage).
but when program starts, It returns null to the class.
public class JframeFoo extends JFrame {
private String username = new String();
public JframeFoo() {
// --------------------------------------------------------------
// Making Frame for login
final JTextField usernameFiled = new JTextField();
this.add(usernameFiled);
JButton signinButton = new JButton();
// ------------------------------------------------------------
signinButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
setVisible(false);
Main.mainpage.setVisible(true);
}
});
// ----------------------------------------------------------------------
username = usernameFiled.getText();
}
public String getuserName() {
return this.username;
}
}
(this Jframe should run at the start of program and when it gets text, it should go to invisible and another class should become visible.)

You need to move the call to username = usernameField.getText() into the actionPerformed method. It only gets set to null the way you currently have it.

The constructor JFrameFoo() is called when that frame is created. Therefore, this line:
username = usernameFiled.getText();
is also called at that moment. What you want to do instead is:
signinButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
username = usernameFiled.getText();
setVisible(false);
Main.mainpage.setVisible(true);
}
});
EDIT
What I expect is also going wrong is that you use userName in your main class before it is initialized. I would recommend two things:
Learn about event-driving programming and callbacks. The simple fact that a line is below another in the source does not mean that it is executed later.
Instead of calling mainPage.setVisible, do something like
signinButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
setVisible(false);
Main.mainpage.open(usernameFiled.getText());
}
});
and add that method in your mainpage, doing something like
public void open(String username) {
this.setVisible(true);
// do whatever you want to do with username
}

In addition to calling the getText() method from within the actionPerformed overridden method, you can also use this.dispose(); rather than setVisible(false);
so your code would look something like:
signinButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
username = usernameFiled.getText();
if ((username != null) || !(username.length() == 0)) {
this.dispose();
Main.mainpage.setVisible(true);
} else {
// Appropriate error here...
}
}
});
Calling getText() from within actionPerformed will also allow you to do some checks on the username variable before you dispose of the frame and proceed (again, see above snippet).
Good luck!

Related

How do I make variables accessible everywhere?

I am using java swing and I have tried using new text as a parameter but I am not sure how, there is also the fact that I have "});" which is completely messed up but it works, and i tried fixing it and it doesn't work
this code is inside my main
public String newText = "";
a.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
JFrame popup = new JFrame("Choose...");
popup.setSize(250,250);
popup.setLayout(null);
popup.setVisible(true);
JButton o=new JButton("o");
o.setBounds(25,75,100,100);
popup.add(o);
o.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae, String newText){
newText = "O";
}
});
JButton x=new JButton("x");
x.setBounds(125,75,100,100);
popup.add(x);
if (!newText.equals(""))
a.setText(newText);
}
});
I have tried using newText as a parameter
Here?
public void actionPerformed(ActionEvent ae, String newText){
This is not valid code. ActionListener is an interface; an interface is a contract that must be followed. You cannot simply add variables to existing method signatures.
Assuming you wanted to modify the button text, you could do this
public class Main {
public String newText;
public static void main(String[] args) {
new Main().run();
}
public void run() {
System.out.printf("before: newText = %s%n", newText);
final JButton o = new JButton("o");
// ...
o.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent ae){
Main.this.newText = "O"; // Sets the field
System.out.printf("action: newText = %s%n", Main.this.newText);
o.setText(Main.this.newText);
}
});
System.out.printf("actionListener set : newText = %s%n", newText);
}
}
However, trying to use newText.equals outside of the action listener happens on a different thread, meaning the code does not run "top to bottom". E.g. the variable isn't "set" in the execution order that the code reads as. Added print statements to show this

Need my GUI to read from a JTextField and show in a JPanel

I have added an action listener to the text field. When the btnReadString (Button Read String) is pressed the program should read what is on the text field and show on the JPanel. but nothing shows on the panel.
stringTextField.addActionListener(new ActionListener() {
public void stringTextField (java.awt.event.ActionEvent e) {
if(e.getSource()==btnReadString) //when the button is pressed
{
String stringParameter = stringTextField.getText(); //gets the text and puts it on this string called "stringParameter"
textPane.setText(stringParameter);//the JPanel is set to what is on the string.
}
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
});
The functionality for the ActionListener should go in the actionPerformed method, as nothings calling the stringTextField method...
stringTextField.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource()==btnReadString) //when the button is pressed
{
String stringParameter = stringTextField.getText(); //gets the text and puts it on this string called "stringParameter"
textPane.setText(stringParameter);//the JPanel is set to what is on the string.
}
}
});
But, based on the code, the ActionListener should be attached to the btnReadString and not the field, as the above logic will never result in anything been executed (as the source of the event will never be btnReadString)
btnReadString.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
String stringParameter = stringTextField.getText(); //gets the text and puts it on this string called "stringParameter"
textPane.setText(stringParameter);//the JPanel is set to what is on the string.
}
});
I would suggest having a closer look at How to Write an Action Listener and How to Use Buttons, Check Boxes, and Radio Buttons for more details
You have added the ActionListener to the text field. So the event source is never going to be the button and hence, the code is never going to execute. What you want is to add the ActionListener to the JButton.
Also, the actionPerformed() is there for a reason. All your 'action' code goes inside this method.
So your code should look like this:
btnReadString.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
String stringParameter = stringTextField.getText();
textPane.setText(stringParameter);
}
});

Java remove listener from button after 3 clicks

So I want to remove a listener from a button after the button has been pressed 3 times.
So far I have this
class Q5
{
JFrame frame;
JButton button;
int clickCount = 0;
public static void main (String[] args)
{
Q5 example = new Q5();
example.go();
}
public void go()
{
frame = new JFrame();
button = new JButton ("Should I do it");
button.addActionListener(new ButtonPressListener());
button.addActionListener(new AngelListener());
button.addActionListener(new DevilListener());
button.addActionListener(new ConfusedListener());
frame.getContentPane().add(BorderLayout.CENTER, button);
frame.setVisible(true);
frame.setSize(400,150);
// set frame properties here
}
class ButtonPressListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
clickCount++;
}
}
class AngelListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
System.out.println("Don't do it, you might regret it!");
}
}
class DevilListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
System.out.println("Go on, do it!");
}
}
class ConfusedListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
if(clickCount > 3)
{
for(ConfusedListener conf : button.getActionListeners())
{
button.removeActionListener(conf);
}
}
else
System.out.println("I don't know!");
}
}
The way I read online was do a for loop, as I tried above, however I get a type mismatch. Most of the examples I could find were about removing all of the listeners, however I only want to remove the ConfusedListener from the button. Other than the for loop above, I don't have any ideas of how to do it.
The getActionListeners() method returns all the listeners of the button. And they're not all instances of ConfusedListener. The only sure thing we know is that they're instances of ActionListener. That's why your code doesn't compile.
Now, why would you need a loop to remove a given listener? You simply need to remove the ConfusedListener that is being invoked. So you just need
public void actionPerformed(ActionEvent event)
{
if(clickCount > 3)
{
button.removeActionListener(this);
}
else
System.out.println("I don't know!");
}
You could try:
if(clickCount > 3)
{
for(ActionListener listener : button.getActionListeners())
{
if (listener instanceOf ConfusedListener) {
button.removeActionListener(conf);
}
}
}
else
System.out.println("I don't know!");
You could also save the instance of the ConfusedListener when adding it and remove it via
button.removeActionListener(confusedListenerInstance);
Just store an instance of the listener itself and use it to remove the correct listener:
final ConfusedListener confusedListener = new ConfusedListener();
button.addActionListener(confusedListener);
button.removeActionListener(confusedListener);
Of if you are removing the listener from inside a method of ConfusedListener itself just pass this:
button.removeActionListener(this);

Make text in JButton not visible

I made a button and did a .setText() on it because I have to compare the value of the .setText() with something else.
I applied the .setText() to a JButton, but I don't want the text to be visible in my button.
If I do setVisible(false) then it hides the whole button, but I only want it to hide the text.
Is there an option for this? I've considered making a custom font and apply it on the text in the .setText() but I'm wondering if there's a more efficient option to my problem.
Thanks in advance guys.
EDIT: I can't use .setText(" ") because I have to compare the value within it.
You state:
EDIT: I can't use .setText(" ") because I have to compare the value within it.
Nonsense. As I've mentioned in a comment, set the JButton's text to " ", and don't use the JButton's text for comparison. Instead use its actionCommand easily obtained via getActionCommand(). Or use a HashMap<JButton, SomethingElse>.
You may consider changing the JButton's Action when you need to change its behavior and state which is easily done by calling setAction(...)
For example,
import java.awt.event.ActionEvent;
import javax.swing.*;
public class ButtonActions {
private static void createAndShowGui() {
JPanel mainPanel = new JPanel();
JButton myButton = new JButton();
StartAction startAction = new StartAction();
PauseAction pauseAction = new PauseAction();
BlankAction blankAction = new BlankAction();
startAction.setNextAction(pauseAction);
pauseAction.setNextAction(blankAction);
blankAction.setNextAction(startAction);
myButton.setAction(startAction);
mainPanel.add(myButton);
JFrame frame = new JFrame("ButtonActions");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class SwappingAction extends AbstractAction {
private Action nextAction;
public SwappingAction(String text) {
super(text);
}
public void setNextAction(Action nextAction) {
this.nextAction = nextAction;
}
public Action getNextAction() {
return nextAction;
}
#Override
/**
* super method needs to be called in child for swap to work
*/
public void actionPerformed(ActionEvent e) {
System.out.println("ActionCommand: " + e.getActionCommand());
((AbstractButton)e.getSource()).setAction(nextAction);
}
}
class StartAction extends SwappingAction {
public static final String START = "Start";
public StartAction() {
super(START);
}
#Override
public void actionPerformed(ActionEvent e) {
super.actionPerformed(e);
// start-specific code goes here
}
}
class PauseAction extends SwappingAction {
public static final String PAUSE = "Pause";
public PauseAction() {
super(PAUSE);
}
#Override
public void actionPerformed(ActionEvent e) {
super.actionPerformed(e);
// pause-specific code goes here
}
}
class BlankAction extends SwappingAction {
public static final String BLANK = " ";
public BlankAction() {
super(BLANK);
}
#Override
public void actionPerformed(ActionEvent e) {
super.actionPerformed(e);
}
}
Write buttonName.setText(" ") this will not display any name to the button. And whenever you feel like displaying the name (on any event) then set it again buttonName.setText("some text")
If you insist not to use setText(""), try setting same colour as a background colour and text colour. Check the below links
setBackground(java.awt.Color)
setForeground(java.awt.Color)
Why don't you name the first button " " (1 space).
the second: " " (2 spaces)
the third: " "(3 spaces) and so on ..
Now, compare:
if((event.getActionCommand()).equals(" "))
{ //1st button }
if((event.getActionCommand()).equals(" "))
{ //2nd button }
..and so on
where event is an object of ActionEvent
This way the buttons will have a unique names and be invisible.
Horrible coding, I know. But it does the trick ;)
Instead of .setText(), use .setTag() and .getTag() to attach some value to a View - including a Button - for later retrieval.
These methods are there directly for that kind of purpose.

Simple memory game with replay button

I want to build a simple memory game. I want to put a replay button, which is play again the memory game.
I have built a class named MemoryGame and a main class.
Here is the part of the ButtonListener code.
public void actionPerformed(ActionEvent e) {
if (exitButton == e.getSource()) {
System.exit(0);
}
else if (replayButton == e.getSource()) {
//How can I declare it?
}
}
If I declare the replay button as :
new MemoryGame();
It's work fine, but it pops up another windows.
I want to clear the current display and return to the beginning, without a new windows. How can I do that?
EDIT :
I think I need to rewrite the code of my program, because my program does not have the init() method as suggested which is the initial state of the program.
My Java knowledge is very limited and usually I create less method and dump most into a method.
I will try to redo my program.
Thanks for the suggestions.
Show us what is inside the MemoryGame how you create its initial state. Effectively what folks are suggesting here is for you is to have an initial method which will set-up the game state which the MemeoryGame constructor will call. Then on replay-button of the game you call this method.
Something along these lines:
void init(){
this.x = 10;
this.y = 10;
}
public MemoryGame(){
init();
}
public void actionPerformed(ActionEvent e) {
if (exitButton == e.getSource()) {
System.exit(0);
}
else if (replayButton == e.getSource()) {
init();
}
}
one way you can do it although it might be dirty, is to grab your MemoryGame constructor, and put the stuff inside it inside another method, and call that method in your constructor and inside the button event.
as an example i have made the following class and it resets itself with the use of the previous technique:
public class App extends JFrame{
public static void main(String[] args){
new App();
}
public App(){
init();
}
private JButton changeColorButton;
private JButton resetAppButton;
private JPanel panel;
private void init() {
changeColorButton=null;
resetAppButton=null;
panel=null;
this.setSize(200,400);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new JPanel();
panel.setBackground(Color.white);
panel.setPreferredSize(new Dimension(200,400));
changeColorButton = new JButton("Change");
changeColorButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
panel.setBackground(Color.black);
panel.repaint();
}
});
changeColorButton.setPreferredSize(new Dimension(100,100));
resetAppButton = new JButton("Reset");
resetAppButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
init();
}
});
resetAppButton.setPreferredSize(new Dimension(100,100));
panel.add(changeColorButton);
panel.add(resetAppButton);
this.add(panel);
this.validate();
}
}
what this app does is it has two buttons. one changes the color and the other resets the app itself.
You should think about re-factoring your code so that the MemoryGame class does not create the GUI, then you wont be recreating it whenever you initialise a new Game.
It's a good idea to keep program logic separate to UI code.
What you could do is you could call dispose() on your JFrame. This will get rid of it and go to your title screen like this:
Here's the button code
public void actionPerformed(ActionEvent event)
{
if (closeButton = event.getSource())
{
System.exit(0);
}
if (playAgainButton = event.getSource())
{
Game.frame.dispose(); // Your class name, then the JFrame variable and call dispose
}
}
This will work but you may have a few problems reseting your program. If so then create a reset method where you can reset all your variables and call when playAgainButton is clicked. For example:
public void reset()
{
// Right here you'd reset all your variables
// Perhaps you have a gameOver variable to see if it's game over or not reset it
gameOver = false;
}

Categories

Resources