-2

I'm rather new to Java so may be going about this completely the wrong way. Is there an interface for objects that implement an addActionLister method, such that I can use a test like this to find out if I can add an ActionListener to it or not.

if (someObject instanceof WhatShouldThisBe){
    someObject.addActionListener(...);
}

I've tried various things, but can't find one that works or work out how to search the documentation (javadoc) for the method.

I'm trying to add action listeners to all components in a form at the same time by iterating over, myForm.getComponents() The problem is, that gives an array of Component objects and the Component class doesn't have an addActionListener method (at least, according to my IDE anyway).

Thanks in advance for your help.

Tinny-D
  • 11
  • 3
  • 1
    `if (someObject.class.getDeclaredMethod("addActionListener", new Class[] { ActionListener.class }) != null)` – Elliott Frisch Jun 29 '17 at 23:04
  • 2
    That sounds like an XY question. What are you trying to achieve? Why are you trying to add an action listener to arbitrary components, without even knowing hat they are? – JB Nizet Jun 29 '17 at 23:04
  • I'm out of up-votes, but I'm with @JBNizet -- your question is an [XY Problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) where the true answer to your question is that you're going about things in a completely wrong way, that you shouldn't let the GUI component structure dictate how the control adds listeners. – Hovercraft Full Of Eels Jun 29 '17 at 23:15
  • Thanks for your comments @JBNizet and `Hovercraft`, your quite right. My aim was to add a hotkey that would work from within all fields on a form, but was being lazy thinking I could iterate through them instead of keeping track of what had been created. – Tinny-D Jun 29 '17 at 23:31

3 Answers3

2

According to the Javadoc for JButton, the addActionListener method is declared in the abstract superclass AbstractButton. It's not an interface, but it will do what you require. If you write

if (someObject instanceof AbstractButton)

then you'll pick up any JButton, JMenuItem or JToggleButton.

Dawood ibn Kareem
  • 77,785
  • 15
  • 98
  • 110
  • 1
    Of course, none of those are *interfaces*, and question said *"Is there an interface ..."* – Andreas Jun 29 '17 at 23:16
  • @Yahya, if OP is looking for `addActionListener`, then he/she is using Swing. – Dawood ibn Kareem Jun 29 '17 at 23:23
  • Thanks, I am working in `Swing`. This seems like a good approach, although I'll have to test whether it's a member of `JList` or `JTextComponent` as well. I was probably just being a bit lazy hoping there was an interface that would pick them all up. – Tinny-D Jun 29 '17 at 23:27
  • 1
    But `JList` and `JTextComponent` don't have `addActionListener` methods (although `JTextField` does). – Dawood ibn Kareem Jun 29 '17 at 23:35
  • Oops, that may be the more relevant issue then; I'll go and have rethink. – Tinny-D Jun 29 '17 at 23:39
  • If you are trying to add a global hotkey, perhaps something like [this](https://stackoverflow.com/questions/5344823/how-can-i-listen-for-key-presses-within-java-swing-across-all-components) will help – Java Devil Jun 29 '17 at 23:41
0

If you have JComponents Objects in your program other than JButton, JMenuItem and JToggleButton that dot not extends AbstractButton -Example JComboBox- you may consider using Reflection.

The idea is to keep two separate sets, one for the approvedClasses and the second for the declinedClasses which contains no such method signature.

In this way you save some time, because the method for searching the given method signature shall search in all classes in the tree of hierarchy of the given Class Component.

And because you have a form that contains a lot of components, the time is critical.

import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JList;
import javax.swing.JMenuItem;


public class SearchForAddActionListener{
    // to save time, instead of searching in already-searched-class
    static Set<Class<?>> approvedClasses = new HashSet<>();
    static Set<Class<?>> declinedClasses = new HashSet<>();

    public static boolean hasAddActionListener(JComponent component, String signature){
        Class<?> componentClazz =  component.getClass();
        Class<?> clazz = componentClazz;

        if(declinedClasses.contains(componentClazz)){return false;}

        while(clazz!=null){
           if(approvedClasses.contains(clazz)){
              approvedClasses.add(componentClazz);// in case clazz is a superclass
              return true;
           }
           for (Method method : clazz.getDeclaredMethods()) {
              if(method.toString().contains(signature)){
                  approvedClasses.add(clazz);
                  approvedClasses.add(componentClazz);
                  return true;
               };
            }
            clazz = clazz.getSuperclass(); // search for superclass as well
        }
        declinedClasses.add(componentClazz);
        return false;
    }


    public static void main(String[] args) {
        JComboBox<?> comboBox = new JComboBox<>();
        JButton button = new JButton();
        JMenuItem menuItem = new JMenuItem();
        JList<?> list = new JList<>();

        System.out.println(hasAddActionListener(comboBox,"addActionListener"));
        System.out.println(hasAddActionListener(button,"removeActionListener"));
        System.out.println(hasAddActionListener(menuItem,"addActionListener"));
        System.out.println(hasAddActionListener(list,"addActionListener"));

        System.out.println(approvedClasses);
        System.out.println(declinedClasses);
    }
}

Output

true
true
true
false
[class javax.swing.JButton, class javax.swing.JComboBox, class javax.swing.AbstractButton, class javax.swing.JMenuItem]
[class javax.swing.JList]
Yahya
  • 13,349
  • 6
  • 30
  • 42
-5

try: if(someObject instanceof ActionListener) ...

Ray Tayek
  • 9,841
  • 8
  • 50
  • 90
  • OP is asking for interface declaring method `addActionListener()`, not whether object is a valid parameter for the method. – Andreas Jun 29 '17 at 23:02