Jump to content
  • Advertisement
Sign in to follow this  
ahung89

[java] GUI's

This topic is 3494 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey guys. I've recently started learning about GUI's, action events, and that whole shindig... I've been doing exercises out of my textbook. I recently got an exercise where I have to make a GUI with a text field and two buttons, one called upper case and one called lower case. When I press the upper case one it's supposed to make whatever I type in the text field turn upper case, and vice versa for the lower version. What I'm confused about is how exactly to write these two action listeners. Every example that I've seen in the book embeds the action listener in the client program. However I don't see how I'd have an actionPerformed method for both the upper and lower case buttons inside the client program so I'd probably have to make two separate classes. Now what confuses me about that is that the actionPerformed method, as far as I understand, is supposed to have something like textField.setText(textField.getField().toUpperCase ()) or vice versa for the lower case one. How would I be able to edit the textField from the client program through the separate action listener though?? Also, another question: one of the answer solutions to one of the exercises uses an action listener that is a private class that is INSIDE the public class that creates the GUI. How do these private classes work and what are their strengths/limitations? I never even knew these existed and the book never spoke of them. Thanks a lot - knowing how to do use multiple action listeners to edit the components' fields will make the rest of the exercises a lot easier.

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by ahung89
a private class that is INSIDE the public class


These are known as "inner classes"; I found a short article which explains them a bit more here.

To solve your problem, you could either create a single ActionListener, add it to both buttons and check the source from the ActionEvent too see which button was clicked.


public void actionPerformed(final ActionEvent evt) {
if ( uppercaseButton.equals( (JButton) evt.getSource() ) ) {
// Change text to uppercase.

} else if ( lowercaseButton.equals( (JButton) evt.getSource() ) ) {
// Change text to lowercase.
}
}





Or create 2 inner classes (probably anonymous for a simple task) to handle each button.



uppercaseButton.addActionListener( new ActionListener() {

public void actionPerformed(final ActionEvent evt) {
// Change text to uppercase.
}

});

lowercaseButton.addActionListener( new ActionListener() {

public void actionPerformed(final ActionEvent evt) {
// Change text to lowercase.
}

});






Quote:
Original post by ahung89
How would I be able to edit the textField from the client program through the separate action listener though??


Inner classes can access instance variables of the "parent" class. If the class implementing ActionListener was seperate I guess the client app would be responsible for passing it a reference to the text field. I don't know of any clever way to avoid this.

Share this post


Link to post
Share on other sites
Thanks for taking the time to reply in such detail - truly appreciated.

That makes perfect sense. I'll definitely be able to finish that exercise now. One question though - is it necessary to put a "final" in the parameter for the actionPerformed method? The book doesn't do this... could you explain why you did?

Quote:
Inner classes can access instance variables of the "parent" class. If the class implementing ActionListener was seperate I guess the client app would be responsible for passing it a reference to the text field. I don't know of any clever way to avoid this.


What would be the easiest way to do this? The easiest way I can think of is to send the text as a string to the constructor of the action listener class, and then to have a get string method... I wouldn't be able to do it as easily though because the actionPerformed method only accepts on parameter, right?

Once again thanks for the help.

Share this post


Link to post
Share on other sites
Quote:
Original post by ahung89
is it necessary to put a "final" in the parameter for the actionPerformed method?


No you don't have to use "final", that is just a habbit of mine. Any variable or object reference I don't modify I always use "final".

If you try to re-assign a value the compiler generates an error; it helps to stop mistakes.

e.g. Without "final".

public void actionPerformed(ActionEvent evt) {

// By accident I null the event.
evt = null;

// This would cause a runtime NullPointerException.
System.out.println( evt.getActionCommand() );
}





e.g. With "final"

public void actionPerformed(final ActionEvent evt) {

// By accident I null the event.
//
// This would cause a compile-time error.
evt = null;

System.out.println( evt.getActionCommand() );
}





Without "final" I don't know there is a problem untill runtime; but with "final" I can find the problem at compile-time.
Quote:
Original post by ahung89
What would be the easiest way to do this? The easiest way I can think of is to send the text as a string to the constructor of the action listener class, and then to have a get string method... I wouldn't be able to do it as easily though because the actionPerformed method only accepts on parameter, right?

You're right, one option is to extend the functionality of ActionListner and/or ActionEvent, but we want to avoid duplicating code that already exists.

I also prefer to avoid this situtation by using inner classes; but to do it this way I was thinking of something like:

// ToLowercaseListener.java

public class ToLowercaseListener implements ActionListener {

private JTextField textField;

public ToLowercaseListener(final JTextField textField) {

// Get an object reference to the text field.
this.textField = textField;
}

public void actionPerformed(final ActionEvent evt) {

if (textField != null) {

// Change the text to lowercase.
textField.setText( textField.getText().toLowerCase() );
}
}
}






// ToUppercaseListener.java

public class ToUppercaseListener implements ActionListener {

private JTextField textField;

public ToUppercaseListener(final JTextField textField) {

// Get an object reference to the text field.
this.textField = textField;
}

public void actionPerformed(final ActionEvent evt) {

if (textField != null) {

// Change the text to lowercase.
textField.setText( textField.getText().toUpperCase() );
}
}
}






// SomeMainClass.java

private void initComponents() {

// Create a text field.
JTextField textField = new JTextField("");

// Create buttons.
JButton toUppercaseButton = new JButton("To Uppercase");
JButton toLowercaseButton = new JButton("To Lowercase");

// Add to Jpanel/JFrame etc...


// Create and add a new ToUppercaseListener; with a reference to the text field.
toUppercaseButton.addActionListener( new ToUppercaseListener(textField) );

// Create and add a new ToLowercaseListener; with a reference to the text field.
toLowercaseButton.addActionListener( new ToLowercaseListener(textField) );
}





I'm sure someone else could probably imagine a better way to do this.

Share this post


Link to post
Share on other sites
As far as action listeners go for GUIs, I have always liked an inner class that just calls a function.

For example:


// in a gui class

public JButton getJButton() {
JButton button = new JButton("OK");
button.addActionListener( new ActionListener() {
public void actionPerformed( ActionEvent e ) {
onButtonPressed();
}
});
return button;
}

protected void onButtonPressed() {
// could be a lot of code here that shouldn't get in the
// way of setting up the GUI.
}



I like this because I can find the button in the code and see what happens, but the code isn't in the action listener. Where the code behind the button grows large or does a lot of error checking, it can get ugly.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!