Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / GUI / June 2006

Tip: Looking for answers? Try searching our database.

Button event

Thread view: 
jaap - 28 Jun 2006 23:58 GMT
Hello

I'm a real noob with java. I worked for 4 years with php but now I have
to use java.
I'm looking for a clean way to get an action behind a button/menuitem. I
 already found the class actionListener. but the method actionpreformed
is not very clean if you want to give 20 buttons an action. The way I
know is 20 times else if. There must be an better method.

I will try to use my GUI like an interface. It does'nt have to include
much code in my opinion. I think it have to be only some field and
button delcarations.

thx for your help

greetz
Jaap
Brandon McCombs - 29 Jun 2006 00:16 GMT
> Hello
>
[quoted text clipped - 13 lines]
> greetz
> Jaap

There are 2 ways (that I know of and can remember from class) for
designing the way your application handles the action events.  You can
have your JFrame or JPanel (some central "authority") manage all the
events which would cause you to need a bunch of "else if" statements or
you can have each button be its own action listener which removes the
need for a large "if" structure but makes the individual button code a
little more messy, IMO.

Brandon
IchBin - 29 Jun 2006 06:05 GMT
> Hello
>
[quoted text clipped - 13 lines]
> greetz
> Jaap

With you program just implement an ActionListener. After this you have
to add the required actionPerformed method. Then just check for which
buttons were selected. Here is an example code for buttons objects.
Naturally this is not a complete program but just info you were asking about

public class MyButtons implements ActionListener
{
    private JButton deleteButton;
    private JButton reloadButton;
    private JButton returnButton;
    private JButton commitButton;

    private final String        TEXT_DETELE           = "Delete";
    private final String        TEXT_RELOAD           = "Reload";
    private final String        TEXT_RETURN           = "Return";
    private final String        TEXT_COMMIT           = "Commit";

    private final String        _Click                = "Click this
button to ";
    private final String        _toolTipDelete        = this._Click +
"Deleteed Se;ected quote from Database";
    private final String        _toolTipReload        = this._Click +
"Reload all remaintng dupicate Quotes from Database";
    private final String        _toolTipReturn        = this._Click +
"Return Insert Quotes";
    private final String        _toolTipCommit        = this._Click +
"Commit all Delete's to Database";

     public MyButtons ()
    {
      deleteButton = buildButton (deleteButton, TEXT_DETELE,
KeyEvent.VK_D, _toolTipDelete));
      reloadButton = buildButton (reloadButton, TEXT_RELOAD,
KeyEvent.VK_R, _toolTipReload));
      returnButton = buildButton (returnButton, TEXT_RETURN,
KeyEvent.VK_X, _toolTipReturn));
      commitButton = buildButton (commitButton, TEXT_COMMIT,
KeyEvent.VK_C, _toolTipCommit));
    }

    private JButton buildButton (JButton jButton, String label, int
keyEvent, String toolTip)
    {
        jButton = new JButton(label);
        jButton.setMnemonic (keyEvent);
        jButton.addActionListener (this);
        jButton.setActionCommand (label);
        jButton.setToolTipText (toolTip);
        return jButton;
    }
    public void actionPerformed (ActionEvent e)
    {
        if (this.TEXT_RETURN.equals (e.getActionCommand ()))
        {
        }
        else if (this.TEXT_DETELE.equals (e.getActionCommand ()))
            {
            }
            else if (this.TEXT_RELOAD.equals (e.getActionCommand ()))
                {
                }
                else if (this.TEXT_COMMIT.equals (e.getActionCommand ()))
                    {
                    }

    }
}

Thanks in Advance...
IchBin, Pocono Lake, Pa, USA              http://weconsultants.phpnet.us
__________________________________________________________________________

'If there is one, Knowledge is the "Fountain of Youth"'
-William E. Taylor,  Regular Guy (1952-)
Ian Wilson - 29 Jun 2006 11:54 GMT
>> I'm a real noob with java. I worked for 4 years with php but now I
>> have to use java.
[quoted text clipped - 72 lines]
>     }
> }

It's a bit rude of me, a mere beginner in Java, to offer comments on
IchBin's contribution, so please accept my apologies for doing so:

In this specific example, you don't need to prefix the constants
"TEXT_RETURN" etc with "this.".

Eclipse also lays out (Ctrl-Shift-F) the if statement more like a case
statement, I prefer this layout:
   public void actionPerformed(ActionEvent e) {
        if (TEXT_RETURN.equals(e.getActionCommand())) {
            // do something
        } else if (TEXT_DELETE.equals(e.getActionCommand())) {
            // do something
        } else if (TEXT_RELOAD.equals(e.getActionCommand())) {
            // do something
        } else if (TEXT_COMMIT.equals(e.getActionCommand())) {
            // do something
        }

I would also add some defensive code:
        } else {
            System.out.println("Internal error: command '"
                + e.getActionCOmmand() + "' unknown!";
            // or JOptionPane etc
        }

Lastly: I feel impelled to insert `String command = e.getActionCommand`
at the top of the method and then change all subsequent
'e.getActionCommand()' to 'command'. An old compulsion to avoid
'expensive' subroutine calls from my Fortran IV days. Not that I worry
about microseconds nowadays - its just a habit :-)

Just my GBP 0.02 worth.
jaap - 29 Jun 2006 12:31 GMT
Ian Wilson schreef:

>>> I'm a real noob with java. I worked for 4 years with php but now I
>>> have to use java.
[quoted text clipped - 106 lines]
>
> Just my GBP 0.02 worth.

why I shouldn't use the way like java sun sugests? They create classes
for each action. You will get lots of classes but that won't be a
problem I sugest, am I wrong?
Knute Johnson - 29 Jun 2006 15:58 GMT
> Ian Wilson schreef:
>>>
[quoted text clipped - 113 lines]
> for each action. You will get lots of classes but that won't be a
> problem I sugest, am I wrong?

There is a lot of memory overhead for each internal class.  The single
ActionListener with the if-else tests is the way to go if you have a lot
different events.

For the others:

public void actionPerformed(ActionEvent ae) {
    String ac = ae.getActionCommand();
    if (ac.equals("???")) {
    } else if(ac.equals("????")) {
    }

saves a lot of calls to ActionEvent.getActionCommand() that are not
necessary.

Signature

Knute Johnson
email s/nospam/knute/

Thomas Fritsch - 29 Jun 2006 12:35 GMT
> I'm a real noob with java. I worked for 4 years with php but now I have
> to use java.
[quoted text clipped - 6 lines]
> much code in my opinion. I think it have to be only some field and
> button delcarations.

I personally prefer a design-pattern
roughly alongside the article "How to use Action" at
<http://java.sun.com/docs/books/tutorial/uiswing/misc/action.html>.

My code typically looks like this:

//--begin example-------------------------------------------------
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class MainFrame extends JFrame {
  public static void main(String[] args) {
    JFrame frame = new MainFrame();
    frame.pack();
    frame.setVisible(true);
  }

  // Actions used by menu items and buttons:
  private Action openAction = new OpenAction();
  private Action saveAction = new SaveAction();
  // ...more actions

  public MainFrame() {
    jbInit();
  }

  private void jbInit() {
    getContentPane().setLayout(new BorderLayout());

    JMenuBar menuBar = new JMenuBar();
    JMenu fileMenu = new JMenu("File");
    fileMenu.add(openAction);
    fileMenu.add(saveAction);
    menuBar.add(fileMenu);
    // ... more menus and menu-items
    setJMenuBar(menuBar);

    JToolBar toolBar = new JToolBar();
    toolBar.add(openAction);
    toolBar.add(saveAction);
    // ... more tool-bar buttons
    getContentPane().add(toolBar, BorderLayout.NORTH);

    JPanel panel = new JPanel();
    panel.setLayout(new FlowLayout());
    panel.add(new JButton(openAction));
    panel.add(new JButton(saveAction));
    // ... more buttons
    getContentPane().add(panel, BorderLayout.CENTER);
  }

  class OpenAction extends AbstractAction {
    public OpenAction() {
      putValue(Action.NAME, "Open");
      putValue(Action.SMALL_ICON, new ImageIcon("open16.gif"));
      putValue(Action.MNEMONIC_KEY, new Integer('P'));
      putValue(Action.SHORT_DESCRIPTION, "open file");
      putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(
               KeyEvent.VK_O, InputEvent.CTRL_MASK));
    }
    public void actionPerformed(ActionEvent e) {
      System.out.println(this);
      // ... do something
    }
  }

  class SaveAction extends AbstractAction {
    public SaveAction() {
      putValue(Action.NAME, "Save");
      putValue(Action.SMALL_ICON, new ImageIcon("save16.gif"));
      putValue(Action.MNEMONIC_KEY, new Integer('A'));
      putValue(Action.SHORT_DESCRIPTION, "save file");
      putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(
               KeyEvent.VK_S, InputEvent.CTRL_MASK));
    }
    public void actionPerformed(ActionEvent e) {
      System.out.println(this);
      // ... do something
    }
  }

  // ...more Action classes
}
//--end example------------------------------------------------

Signature

Thomas

Steve W. Jackson - 29 Jun 2006 16:15 GMT
> > I'm a real noob with java. I worked for 4 years with php but now I have
> > to use java.
[quoted text clipped - 92 lines]
> }
> //--end example------------------------------------------------

I hadn't seen that example before, and I like it quite a lot.

I'd like, however, to point out that the API now says that adding an
action directly to a menu, toolbar, etc., is no longer the preferred way
(as of 1.3).  Instead, it suggests creating the component and using
setAction.  Of course, the API also shows that common Swing components
now accept an Action in their constructors (also since 1.3).  So it's
not clear if the preferred way is to use setAction or to instead use
something like "new JMenuItem(openAction)".  In either case, I'm going
to keep this idea in mind for future use.

= Steve =
Signature

Steve W. Jackson
Montgomery, Alabama

Thomas Fritsch - 29 Jun 2006 18:05 GMT
Steve W. Jackson schrieb:

>>My code typically looks like this:
[...]
>>   private Action openAction = new OpenAction();
[...]
>>     JMenu fileMenu = new JMenu("File");
>>     fileMenu.add(openAction);
[...]
>>     JToolBar toolBar = new JToolBar();
>>     toolBar.add(openAction);
[...]
>>   class OpenAction extends AbstractAction {
>>     public OpenAction() {
[quoted text clipped - 18 lines]
> (as of 1.3).  Instead, it suggests creating the component and using
> setAction.  Of course, the API also shows that common Swing components
I read this API note at JMenu#add(Action) and JToolBar#add(Action) and
it irritated me, because Sun didn't say what is the advantage of their
preferred way.

> now accept an Action in their constructors (also since 1.3).  So it's
> not clear if the preferred way is to use setAction or to instead use
> something like "new JMenuItem(openAction)".  In either case, I'm going
> to keep this idea in mind for future use.
With openAction having a NAME and a SMALL_ICON value,
I found no optical or functional difference between
    /*1*/  menu.add(openAction);
and /*2*/  menu.add(new JMenuItem(openAction));

But there is a remarkable optical difference between
    /*1*/  toolbar.add(openAction);
and /*2*/  toolbar.add(new JButton(openAction));
(1) gives a tool-button with icon and without text (--> looking fine).
(2) gives a tool-button with icon and with text (--> looking silly).
Therefore, unlike Sun, I still prefer (1).

Signature

Thomas

nblloyd@gmail.com - 29 Jun 2006 16:13 GMT
You can also write a generic action listener which will invoke a method
on an object:

public class GenericActionListener implements ActionListener {

   protected Method method;
   protected Object object;

   public GenericActionListener(Object object, String methodName) {
       this.object = object;
       try {
           method = object.getClass().getMethod(methodName, null);
       } catch (NoSuchMethodException e) {
           e.printStackTrace();
       }
   }

   // this invokes the method
   public void actionPerformed(ActionEvent e) {
       try {
           method.invoke(object, null);
       } catch (InvocationTargetException e) {
           e.printStackTrace();
       } catch (IllegalAccessException e) {
           e.printStackTrace();
       }
   }
}

So, if you have a controller class (say, GUIController), create methods
like "save", "open", "close", etc. in it:

public class GUIController {
   ...
   public void save() {
       ...
   }
   ...
}

Then, for your buttons, simply do this:

// assuming you have a variable for the GUIController called
"guiController"
// (or you can use "this" if your GUI is itself the controller
JButton saveButton = new JButton(...);
saveButton.addActionListener(new GenericActionListener(guiController,
"save"));

When the button is clicked, the method guiController.save() will be
invoked. It's a nice way to keep your code clean, IMO.

You can also extend GenericActionListener to use methods that have
arguments. I'm just showing the bare bones.

- Natasha -

> Hello
>
[quoted text clipped - 13 lines]
> greetz
> Jaap


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.