How to add action listener that listens to multiple buttons

后端 未结 11 1111
温柔的废话
温柔的废话 2020-11-27 04:25

I\'m trying to figure out what i am doing wrong with action listeners. I\'m following multiple tutorials and yet netbeans and eclipse are giving me errors when im trying to

11条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2020-11-27 04:43

    It's a pretty old question. I suppose nobody cares about it any more. But I'd like to post my approach in case it would be helpful to someone.

    Using my approach, you can write the button click event handler in the 'classical way', just like how you did it in VB or MFC ;)

    Suppose we have a class for a frame window which contains 2 buttons:

    class MainWindow {
        Jbutton searchButton;
        Jbutton filterButton;
    }
    

    You can use my 'router' class to route the event back to your MainWindow class:

    class MainWindow {
        JButton searchButton;
        Jbutton filterButton;
        ButtonClickRouter buttonRouter = new ButtonClickRouter(this);
    
        void initWindowContent() {
            // create your components here...
    
            // setup button listeners
            searchButton.addActionListener(buttonRouter);
            filterButton.addActionListener(buttonRouter);
        }
    
        void on_searchButton() {
            // TODO your handler goes here...
        }
    
        void on_filterButton() {
            // TODO your handler goes here...
        }
    }
    

    Do you like it? :)

    If you like this way and hate the Java's anonymous subclass way, then you are as old as I am. The problem of 'addActionListener(new ActionListener {...})' is that it squeezes all button handlers into one outer method which makes the programme look wired. (in case you have a number of buttons in one window)

    Finally, the router class is at below. You can copy it into your programme without the need for any update.

    Just one thing to mention: the button fields and the event handler methods must be accessible to this router class! To simply put, if you copy this router class in the same package of your programme, your button fields and methods must be package-accessible. Otherwise, they must be public.

    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    public class ButtonClickRouter implements ActionListener {
        private Object target;
    
        ButtonClickRouter(Object target) {
            this.target = target;
        }
    
        @Override
        public void actionPerformed(ActionEvent actionEvent) {
            // get source button
            Object sourceButton = actionEvent.getSource();
    
            // find the corresponding field of the button in the host class
            Field fieldOfSourceButton = null;
            for (Field field : target.getClass().getDeclaredFields()) {
                try {
                    if (field.get(target).equals(sourceButton)) {
                        fieldOfSourceButton = field;
                        break;
                    }
                } catch (IllegalAccessException e) {
                }
            }
    
            if (fieldOfSourceButton == null)
                return;
    
            // make the expected method name for the source button
            // rule: suppose the button field is 'searchButton', then the method
            // is expected to be 'void on_searchButton()'
            String methodName = "on_" + fieldOfSourceButton.getName();
    
            // find such a method
            Method expectedHanderMethod = null;
            for (Method method : target.getClass().getDeclaredMethods()) {
                if (method.getName().equals(methodName)) {
                    expectedHanderMethod = method;
                    break;
                }
            }
    
            if (expectedHanderMethod == null)
                return;
    
            // fire
            try {
                expectedHanderMethod.invoke(target);
            } catch (IllegalAccessException | InvocationTargetException e) { }
        }
    }
    

    I'm a beginner in Java (not in programming), so maybe there are anything inappropriate in the above code. Review it before using it, please.

提交回复
热议问题