2

I have read that ActionEvents return the reference of the event object. I want to know how to extract a piece of information out of that reference. I'm sure the answer is out there, I just wasn't sure how to word my question to get it.

I have created a new class that extends JButton. I want each button I create to store an integer value for math operations.

import javax.swing.JButton;
public class NewButton extends JButton {
    int value;
    public NewButton(String writing, int value) {
        this.setText(writing);
        this.value = value;
    }

    public int getValue() {
        return value;
    }
}

I want to use an ActionListener to check for a click then I want to display the int value in the console. Here is my GUI:

import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JPanel;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class MyGui {
    public static void main(String[] args) {

        JFrame frame = new JFrame("GUI");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel panel = new JPanel();
        frame.add(panel);

        NewButton button = new NewButton("ten", 10);
        panel.add(button);

        ActionListener listener = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if(e.getSource() == button) {
                    System.out.println(button.getValue());
                }
            }
        };

        button.addActionListener(listener);

        frame.setVisible(true);
        frame.setSize(100,100);
    }
}

So this works fine for one button.

Now we get to my problem (finally). I want to make another NewButton,button2 . I thought I would change my ActionListener section. I figured I could include one statement for both buttons, since they are of the same class.

        ActionListener listener = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if(e.getSource() == button1 || e.getSource() == button2) {
                    System.out.println(e.getSource().getValue());
                }
            }
        };

But this does not work.

My reasoning was that since I can check:

e.getSource() == button

then the reference e.getSource() should give me access to my getValue().

Does anyone know a way to get the value from e.getSource()? My goal was to see if I could avoid making separate if statements or action listeners for each button.

Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
Krantucket
  • 55
  • 5

2 Answers2

4

You could cast your JButton to a NewButton and then call your method.

public void actionPerformed(ActionEvent e) {
    NewButton newBtn = (NewButton) e.getSource();
    int value = newBtn.getValue();   
}

Having said this, myself, I'd prefer not to extend JButton but rather to extend AbstractAction. For example:

import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JPanel;
import java.awt.event.ActionEvent;

public class MyGui {
   public static void main(String[] args) {
      String[] texts = { "One", "Two", "Three", "Four", "Five" };
      JFrame frame = new JFrame("GUI");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      JPanel panel = new JPanel();

      for (int i = 0; i < texts.length; i++) {
         int value = i + 1;
         panel.add(new JButton(new NewAction(value, texts[i])));
      }

      frame.add(panel);

      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }
}

class NewAction extends AbstractAction {
   private int value;

   public NewAction(int value, String name) {
      super(name);
      this.value = value;
   }

   @Override
   public void actionPerformed(ActionEvent e) {
      System.out.println("Value: " + value);
   }
}
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
3

In addition to @HovercraftFullOfEels great suggestion, if your use case is as simple as set/retrieve an arbitrary value then you can use the very same JButton to "hold" this value by using both putClientProperty(key, value) and getClientProperty(key) methods inherited from JComponent class. Something like this:

JButton button = new JButton("Button 1");
button.putClientProperty("ValueKey", "Actual value");

ActionListener listener = new ActionListener() {        
    @Override
    public void actionPerformed(ActionEvent e) {
        JButton button = (JButton)e.getSource();
        System.out.println(button.getClientProperty("ValueKey"));
    };
}

In this way you don't have to extend neither AbstractAction nor JButton at all. Note this approach can be useful not only for buttons but other components as well. There is a complete example using the very same approach with check boxes in this answer

Community
  • 1
  • 1
dic19
  • 17,821
  • 6
  • 40
  • 69