Jump to content

  • Log In with Google      Sign In   
  • Create Account

Interested in a FREE copy of HTML5 game maker Construct 2?

We'll be giving away three Personal Edition licences in next Tuesday's GDNet Direct email newsletter!

Sign up from the right-hand sidebar on our homepage and read Tuesday's newsletter for details!


We're also offering banner ads on our site from just $5! 1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


[java] OO Styles


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
12 replies to this topic

#1 Jim_Ross   Members   -  Reputation: 122

Like
Likes
Like

Posted 10 May 2000 - 12:40 PM

I recently read an article on javaworld about seperating GUI actions from the classes that instatiate them. Instead of making a MenuBar class that implements ActionListener and including tons of if(e.getSource() == such&such MenuItem) {...} you create the buttons with a JFC Action object. These provide basic strings, icons, and event handlers for JFC atomic components, which eliminates lenghty actionPerformed() methods from your classes. This is all fine and I didn''t know aoout the Action class before, but the author put down the method of making individual subclasses for each GUI piece. For example, to make a "new" button and an "ok" button you would make a class OkButton extends JButton, and give component specific listeners and text and what not to that sub-class. Well, I did this a few times... mainly because I didn''t like the long event listeners in my GUI code. My question is, does anyone else use this latter and more frowned-upon style?

Sponsor:

#2 SteveMeister   Members   -  Reputation: 122

Like
Likes
Like

Posted 11 May 2000 - 01:31 AM

For simple things like buttons, I usually use anonymous inner classes:

JButton ok_button = new JButton("OK");
ok_button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
doOK();
}
});

For other things, like menu items in particular, the Action paradigm works great. The nice thing is you completely abstract the functionality from the form, which means that you can change the GUI without affecting the underlying funcionality, and you that you can also provide users with multiple ways to access the functionality. For example, you can have an Action accessible from an item in a menu, a toolbar button, or whatever other sort of input control you want.

This allows for great flexibility in GUI design, and also helps in establishing a customizable GUI. It''ll come in handy if you want to support undo/redo as well.

Ultimately, applications I write use a combination of actions, anonymous inner classes, and "traditional" event listeners.

Actions are used to do things to the "document" the user is working with.
Anonymous inner classes are for dialog buttons, window events, and other very basic things.
And traditional event listeners are used for things like processing mouse and keyboard events (and these may invoke Actions as well).


#3 Jim_Ross   Members   -  Reputation: 122

Like
Likes
Like

Posted 11 May 2000 - 02:55 AM

Hmm.. I fogot about anonymous inner classes. I never understood their syntax well when I was starting out, so i never really used them, except when the examples did. But I always use them with adapters if implementing the listener requires many method definitions. Here's the article for everyone interested, it's pretty good:

http://www.javaworld.com/javaworld/jw-04-2000/jw-0414-action.html

Edited by - Jim_Ross on May 11, 2000 9:56:24 AM

#4 SteveMeister   Members   -  Reputation: 122

Like
Likes
Like

Posted 11 May 2000 - 09:43 AM

Adapters are the way to go for complex listener types. But in those cases, I''ll usually go the "traditional" route and use a class that implements the listener type (or extends the adapter), because I think that overly complex anonymous inner classes can render the code unreadable. I usually just call a single method from within the anonymous inner class method as in the example above, anyway, just to keep the clutter down.

#5 Captain Goatse   Banned   -  Reputation: 100

Like
Likes
Like

Posted 11 May 2000 - 08:48 PM

I don''t know if this is the right way to do it, but I use something like this

class window extends Window implements ActionListener
{
...
...
Button button = new Button();

button.addActionListener(this);
...
public void actionPerformed(ActionEvent e)
{

if (e.getSource()== button)
{
System.exit(0);
}
}

}


Unluckily that getSource() doesn''t work anymore in 1.3 as it Did earliar and I haven''t downloaded it''s documentation so can anyone explain replacer for it?

Time comes, time goes and I only am.

#6 SteveMeister   Members   -  Reputation: 122

Like
Likes
Like

Posted 12 May 2000 - 01:39 AM

Hm. I''d think that would continue to work. I don''t see anything in the docs or release notes that that''s changed... make sure that you''re comparing the same "button" reference in the event handler method that you assigned to begin with.

Otherwise, you might try using an anonymous inner class just for the buttons anyway.

I''ll have to do some messing around & see if I run into the same problems.


#7 Jim_Ross   Members   -  Reputation: 122

Like
Likes
Like

Posted 12 May 2000 - 02:47 AM

I don''t know if this changed since 1.3, but I''ve found that Event.getSource() always return an Object, so you have to cast, I end up doing something like this:

if( ((Button)e.getSource()).getText() == "OK" ) { ... }


#8 SteveMeister   Members   -  Reputation: 122

Like
Likes
Like

Posted 12 May 2000 - 05:32 AM

One word of warning here -- never use == to compare two Strings, always use .equals().

The test (objectA == objectB) will return true if objectA and objectB both reference the same class instance, which is why event.getSource() == button *should* work.

But the equals method''s implementation is dependent on the object you''re comparing, and especially for Strings, when it''s the content of the Strings you want to compare, that''s an important distintion to make. So the test would be:

(button.getText().equals("OK"))

(I excluded the casting for clarity).

You should ALWAYS use this when comparing Strings.

Note, however, that

(objectA == objectB)

may return false, even though

(objectA.equals(objectB))

returns true. It''s the difference once again between comparing object instances and their contents.

#9 Anonymous Poster_Anonymous Poster_*   Guests   -  Reputation:

Likes

Posted 12 May 2000 - 08:07 AM

The code that Arch@on posted should work in jdk1.3. I do those kinds of comparisons all the time and my programs run under jdk1.3.

I would advise against Mr Ross solution where he compares strings instead of button instances. It just makes harder internationalization and as an earlier poster wrote, the equals method is really the way to do it (the equals method for strings perform a == check too so it should not degrade performance much). You don''t need to cast the Object returned from e.getSource() if you just want to perform a == check against an instance of a Button, such as the one Arch@on does.

Henry


#10 Jim_Ross   Members   -  Reputation: 122

Like
Likes
Like

Posted 12 May 2000 - 12:21 PM

Well, how do you check the instance of getSource with the instance of a particular button if you don''t have an instance of that button?
Ex:

JButton jb = new JButton("OK");
jb.addActionListener(this);
panel.add(jb);
...

actionPerformed(ActionEvent e) {
if(e.Source() == jb) { //this won''t work
...
}

That''s why I use the text of the buttons, and I use == because I''m used to php, the compiler doesn''t complain, and the code runs.


#11 SteveMeister   Members   -  Reputation: 122

Like
Likes
Like

Posted 13 May 2000 - 06:17 AM

Try this instead:

public static final String OK_COMMAND = "OK";
...
JButton jb = new JButton(getLocalizedCommand(OK_COMMAND));
jb.addActionListener(this);
jb.setActionCommand(OK_COMMAND);
...
public void actionPerformed(ActionEvent evt)
{
if (evt.getActionCommand().equals(OK_COMMAND))
{
...
}
}

You''d write the "getLocalizedCommand" method would get the localized String for the button label, based on the action command OK_COMMAND. This allows for localization, and you can also add the action command to other controls, if need be. It also allows you to use a button with an icon instead of text, if you wanted to. Basically, the idea is to remove the functionality from the presentation of the functionality. That way you can change the label without changing anything else (which is why Action classes are so cool, but that''s another story).

Still, for simple, one-shot things like dialog buttons, an anonymous inner class is sometimes the better way to go, because that way you don''t have to do ANY testing to see what control generated the event.

#12 Captain Goatse   Banned   -  Reputation: 100

Like
Likes
Like

Posted 14 May 2000 - 05:04 AM

Hey, but doesn''t e.getActionCommand(); do that string comparison thing or am I missing the trick?

#13 Captain Goatse   Banned   -  Reputation: 100

Like
Likes
Like

Posted 15 May 2000 - 04:01 AM

Sorry, but I had error in my code, because the event which makes my custom button click in mouse released section got accidentally deleted when I made some arrangements, but still, doesn''t that e.getActionCommand() thing work with awt buttons when eventing them by label?

Time comes, time goes and I only am.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS