Search code examples
javaswingjbuttonjradiobutton

are multiple action performed methods needed when using multiple JButtons/JRadioButtons?


My question is basically just the title, but I have a button in my code that makes some JRadiobuttons appear, do I then need to make another action performed method and give it a different name or something? Nothing happens when I use the same action performed method.

so like:

@Override
    public void actionPerformed(ActionEvent a) {

        if( a.getSource() == button1 ) {

      System.out.println("hi");
      }
}
  @Override
  public void ActionPerformed(ActionEvent b){
    if(b.getSource()==firstJRadioButton){
        System.out.println("hi there");
    }
    
  }```

The code above gives me an error and is not my exact code, but I hope it sort of says what I am trying to do if that makes sense.


Solution

  • It's always better to put your real working code in a question.

    The short answer is that you need to make another ActionListener object, with another actionPerformed method, or adapt your single actionPerformed method to handle all your components.

    An ActionListener is an instance of a class which implements the ActionListener interface, so you can only have one action listener per class.

    This means that there are two ways of handling the actions of multiple components:

    Have a single ActionListener instance and then check which component has performed the action:
    public class ListenerEg extends JFrame implements ActionListener {
    
        public ListenerEg() throws HeadlessException {
            this.button1 = new JButton("button 1");
            this.button2 = new JButton("button 2");
            this.setLayout(new FlowLayout());
            this.add(button1);
            button1.addActionListener(this);
            this.add(button2);
            button2.addActionListener(this);
            this.pack();
        }
        JButton button1;
        JButton button2;
        public static void main(String[] args) {
            new ListenerEg().setVisible(true);
        }
        @Override
        public void actionPerformed(ActionEvent e) {
            if (e.getSource() == button1) {
                System.out.println("Button 1");
            } else if (e.getSource() == button2) {
                System.out.println("Button 2");
            }
        }
    }
    
    Have an ActionListener for each component. This is a better approach, as your ActionListener implementation doesn't end up with all your code in it.
    public class ListenerEg extends JFrame {
    
        public ListenerEg() throws HeadlessException {
            this.button1 = new JButton("button 1");
            this.button2 = new JButton("button 2");
            this.setLayout(new FlowLayout());
            this.add(button1);
            button1.addActionListener(e -> {
                System.out.println("Button 1");
            });
            this.add(button2);
            button2.addActionListener(e -> {
                System.out.println("Button 2");
            });
            this.pack();
        }
        JButton button1;
        JButton button2;
        public static void main(String[] args) {
            new ListenerEg().setVisible(true);
        }
    }
    

    You don't have to use a lambda for the ActionListener, you might create your own class hierarchy of ActionListener implementations to reuse common code and improve testability:

    public class ListenerEg extends JFrame {
        private final JButton button1;
        private final JButton button2;
    
        public ListenerEg() throws HeadlessException {
            this.button1 = new JButton("button 1");
            this.button2 = new JButton("button 2");
            this.setLayout(new FlowLayout());
            this.add(button1);
            button1.addActionListener(new ButtonActionListener());
            this.add(button2);
            button2.addActionListener(new ButtonActionListener());
            this.pack();
        }
    
    
        public static void main(String[] args) {
            new ListenerEg().setVisible(true);
        }
    
        private static class ButtonActionListener implements ActionListener {
            @Override
            public void actionPerformed(ActionEvent e) {
                JButton b = (JButton)e.getSource();
                System.out.println(b.getText());
            }
        }
    }
    

    (these are not best practice Swing programs, just the shortest way to illustrate this point)