Question

I was wondering if there is a way to implement an action listener for a Jbutton without a name. For example, I have the following for loop that creates a button for each letter of the alphabet.

for (int i = 65; i < 91; i++){
     alphabetPanel.add(new JButton("<html><center>" + (char)i));
}

Is there a way that I can add an action listener for each of those buttons without getting rid of my for loop and hard coding each JButton and then creating an action listener for each?

Thanks in advance,

Tomek

Was it helpful?

Solution

Your question is a little vague. it would be trivial to modify the loop to add a listener inside the loop:

ActionListener listener = something;

for (int i = 65; i < 91; i++){
     JButton button = new JButton("<html><center>" + (char)i);
     button.addActionListener( listener );
     alphabetPanel.add(button);
}

if you can't modify the loop you could iterate over all of the panel's children, and add listeners to any of the children that are jbuttons.

also why are you using html to center the text? isn't that overkill? doesn't jbutton already center text?
you could use setHorizontalAlignement(SwingConstants.CENTER) to do it too.

OTHER TIPS

What is the problem of doing this?

for (int i = 65; i < 91; i++){
     JButton button = new JButton("<html><center>" + (char)i));
     button.addActionListener( new ButtonListener());
     alphabetPanel.add(button);
}

...

class ButtonListener implements ActionListener {
     ButtonListener() {
     }
     public void actionPerformed(ActionEvent e) {
         //TODO:
     }
}

Also, if the button's text doesn't identify the button you could set the button's name with the letter of the alphabet.

button.setName((char)i)); // or button.setName(i);

By named, you seem to mean storing the button instance in a local variable of your immediate method. Attempting to avoid that is likely to make your code more difficult to read. But to answer your question:

The most obvious way is to use the old but newly-popular double-brace idiom.

alphabetPanel.add(new JButton("<html><center>" + (char)i) {{
    addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent event) {
            ...
        }
    });
}});

Note, in this case as i is not final it will not be usable from the anonymous inner class. Either assign it to another (final) variable or reformulate the loop.

Another route would be to go via an Action. (Usually I'd suggest avoiding Actions as they are jsut a poor man's Hashtable. ButtonModel is "good" though.)

alphabetPanel.add(new JButton(new AbstractAction("<html><center>" + (char)i) {
    public void actionPerformed(ActionEvent event) {
        ...
    }
}));

Then of course there is the application specific library way:

Form alphabetForm = new Form(alphabetPanel);
for (char c='A'; c <= 'Z'; ++c) {
    alphabetForm.button("<html><center>" + c, new ActionListener() {
        public void actionPerformed(ActionEvent event) {
            ...
        }
    });
}

It is possible to add ActionListener to anonymous components like below:

new JButton().addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent arg0) {
                // TODO your action             
            }           
        });

However, in your case where you try to add the anonymous JButton to your panel, this approach will not work because the return type of addActionListener method (which is void) will be taken instead of JButton's constructor as shown below:

for (int i = 65; i < 91; i++){
             alphabetPanel.add(new JButton("<html><center>" + (char)i).addActionListener(new ActionListener(){
                    @Override
                    public void actionPerformed(ActionEvent arg0) {
                        // TODO your action             
                    }           
                }));
        }

The above code complains about invalid argument for panel.add() method.

So in your case, you will have to create a named instance of the JButton.

Hope this clarifies.

Best Regards, Suresh

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top