Wbcreators Crea
Wbcreators Crea

Reputation: 87

Adding action to a JButton when using a for loop

I'm trying to dynamically add buttons (JButtons), which changes names everytime. I doing it with a for loop and is not really problematic. but when adding an action listener or identifying which button got pressed, that is when things don't work so good.

MyFrame.java

import javax.swing.*;
import java.awt.event.*;
import java.awt.GridLayout;

public class MyFrame extends JFrame implements ActionListener 
{
    private JPanel panel;
    private static JButton[] buttons  = new JButton[18];
    // set all static calculate JButtons
    private static JButton equalsBtn, addBtn, subBtn, multiBtn, divBtn, clearBtn, plusMinusBtn, decimalBtn;
    // set all static number JBtuttons
    private static JButton zeroBtn, oneBtn, twoBtn, threeBtn, fourBtn, fiveBtn, sixBtn, sevenBtn, eightBtn, nineBtn;
    private static JTextField resultField;
    // numOne is the first row of figures en the second numSecond is the second row
    private static double numOne, numSecond, result;
    private static double plusMinus;
    private static int addClick = 0, subClick = 0, multiClick = 0, divClick = 0;
    private static int clearField;

    public MyFrame() {
        // configure the JFrame
        super("Rekennen maar!");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        setSize(230, 370);
        setLocationRelativeTo(null);

        // confugure the JPanel
        panel = new JPanel();
        panel.setSize(230, 370);
        panel.setLayout(new GridLayout(5, 0));

        // array string whit all the button names
        String a_btnNames[] = {"clearBtn", "plusMinusBtn", "divBtn", "multiBtn", "sevenBtn", "eightBtn", "nineBtn", "subBtn", "fourBtn", "fiveBtn", "sixBtn",                               "addBtn", "oneBtn", "twoBtn", "threeBtn", "equalsBtn", "zeroBtn", "decimalBtn"};
        // array String whit all button characters
        String a_btnCharts[] = {"C", "+/-", "/", "*", "7", "8", "9", "-", "4", "5", "6", "+", "1", "2", "3", "=", "0", "."};

        for(int i = 0; i < buttons.length; i++)
        {
            // make new button name 
            buttons[i]  = new JButton(a_btnNames[i]);
            // add button to panel
            panel.add(new JButton(a_btnCharts[i]));
            //System.out.println(buttons[i]);
        }

        // add panel when he's filled 
        add(panel);
        setVisible(true);
    }

    public void actionPerformed(ActionEvent e) {
        // press the button
        if ( e.getSource() == ...... ) {
            System.out.println("123");  
        }   
    } 
}

Main.java

public class Main {
    public static void main(String[] arg) {
        MyFrame mf = new MyFrame();
    }
}

Upvotes: 4

Views: 14475

Answers (6)

Larois
Larois

Reputation: 1

loop over the JButton array:

for (int i = 0; i < buttons.length; ++i) {
if (e.getSource()==buttons[i]){
    System.out.println("Button name: " + a_btnNames[i] +"<> Char:"+ a_btnCharts[i] + " pressed");
}

}

Upvotes: 0

Sage
Sage

Reputation: 15408

  1. Well i don't see any problem when you know that evt.getSource() return the source Component of the ActionEvent.

  2. To register an action listener to a component like JButton, we usually do this:

    jButton.addActionListener(anActionListener);
    

    For your context you can pass ActionListener using the help of this.

  3. Do not implement ActionListener interface to some class which doesn't listen to such Event or have them. If required declare a new class by implementing it and use instance of that class to register the listener.

     class MyActionListener implements ActionListener
     {
         public void actionPerformed(ActionEvent e) {
             // press the button
          }     
      }
    
      MyActionListener actionListener = new MyActionListener();
      jButton1.addActionListener(actionListener);
      jButton2.addActionListener(actionListener);
      jButton3.addActionListener(actionListener);
    

I'm trying to dynamically add buttons (JButtons), which changes names everytime.

But you are probably having misconception about setting name with new JButton("some text"). This doesn't set name of the Button, rather it's text content. You need to use button.setName("aName") instead.

However, You can always use the either of the getName or getText method to identify your specific button.

public void actionPerformed(ActionEvent e) {
        // press the button

        JButton button = (JButton)e.getSource();
        Syestem.out.println(button.getName()); // get the name
        System.out.println(button.getText()) // get the text content

        if(button.getText().equals("clearBtn"))
            // clear things for me
    } 

Upvotes: 0

Dario
Dario

Reputation: 548

Remember to add the ActionListener to JButtons first. Then, using getSource() this way doesn't help in your case because you are not keeping references to the JButtons you are adding to the panel. You can use getActionCommand() instead - Default behavior is it returns the label of the button but you can override it with setActionCommand(...):

if ( e.getActionCommand().equals(a_btnCharts[0] ) {

Upvotes: 0

vels4j
vels4j

Reputation: 11298

Few changes

for(int i = 0; i < buttons.length; i++)
    {
        // make new button name 
        buttons[i]  = new JButton(a_btnCharts[i]);
        buttons[i].setName(a_btnNames[i]); // assign button name
        buttons[i].addActionListener(this); // assign action listener 
        // add button to panel
        panel.add(buttons[i]);
    }

and

@Override
public void actionPerformed(ActionEvent e) {
    // press the button
      System.out.println(e.getActionCommand()); 
      JButton btn=(JButton)e.getSource();
      System.out.println(btn.getName());  // use name or action command in if statment
} 

Your main method should be

public static void main(String[] arg) {
    SwingUtilities.invokeLater( new Runnable() {
        @Override
        public void run() {
            MyFrame mf = new MyFrame();
        }
    });
}

Read The Event Dispatch Thread

Upvotes: 0

Rayf
Rayf

Reputation: 451

Alter the loop, to something like this.

for(int i = 0; i < buttons.length; i++)
    {
        // make new button name 
        JButton btn = new JButton("" + a_btnNames[i]);
        buttons[i]  = btn;
        btn.addActionListener(this);
        // add button to panel
        panel.add(btn);
        //System.out.println(buttons[i]);
    }

And then have an actionPerformed() like this.

public void actionPerformed(ActionEvent evt) {
   Object src = evt.getSource();
   if (src == buttons[0]) {
     //First button actions
   } else if (src == buttons[1]) {
     //Second button actions
   }
}

Should work.

Upvotes: 5

Mike M
Mike M

Reputation: 752

There is nothing listening for when the buttons are pressed. When you create each button, you must give them action listeners.

Also, you should be adding the same button that you create.

buttons[i] = new JButton("" + a_btnNames[i]);
//buttons[i] should now be added to the panel

New for loop should be...

for(int i = 0; i < buttons.length; i++){
    buttons[i] = new JButton("" + a_btnNames[i]); //create button & add to array
    buttons[i].addActionListener(this); //add an action listener to the current button
    panel.add(buttons[i]); //add that same button to the panel

}

Upvotes: 4

Related Questions