Home > front end >  How to use my own method for event listening in javax.swing
How to use my own method for event listening in javax.swing

Time:10-08

I'm actually started learning about javax.swing for graphics. For event listening like KeyListener, MouseListener etc., I have to implement all their methods with their own headers.

I previously worked in JS, and there event listening is very simple.

So I decided to create my own class myButton which extends JButton and also implements all the listeners required. But the statements for what has to be done when the button is clicked should be placed in mouseClicked normally, but using that externally I'm not getting how to use that. Another thing is that I want to create a method onClick inside myButton class which has the parameter of the function name same as JS. But I don't know how to create that function. Moreover function passing is not there in Java. And another problem is that how can I tell the program the onClick method is the method that should be implement when the button is clicked.

So these are the two things I wanted to clarify and know how to achieve them.

  1. Use my own method (onClick) instead of the default (mouseClicked).
  2. How to pass a function name or an anonymous function (which should actually be implemented) as an argument to the onClick method as it is in Javascript.

Thanks in advance

CodePudding user response:

Seriously, I think you need to go and read How to Use Buttons, Check Boxes, and Radio Buttons and How to Write an Action Listener which will ultimately do what you want

So something like...

JButton btn = new JButton("Click me");
btn.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("I was clicked");
    }
});

will do exactly what you've just described. The fact is, most components already have some mouse and/or keyboard controls built in, so you don't "have" to reinvent the whole wheel over again.

So I decided to create my own class myButton which extends JButton and also implements all the listeners required. But the statements for what has to be done when the button is clicked should be placed in mouseClicked normally, but using that externally I'm not getting how to use that.

Yes this is what a custom interface would be used for - but the question is, is it important for the button to generate events when a "mouse" action occurs as to apposed to a "key board" action or some other action?

This is why the ActionListener is generally used, as it provides an agnostic event handler for when the button is "actioned", generally, regardless of how it was triggered

Another thing is that I want to create a method onClick inside myButton class which has the parameter of the function name same as JS. But I don't know how to create that function. Moreover function passing is not there in Java. And another problem is that how can I tell the program the onClick method is the method that should be implement when the button is clicked.

There are no functions in Java, just objects. This is where an interface would be useful, it's a contract which describes what functionality an implementation is expected to provide.

You've already used them, you just need to define what your expected "trigger"/method/callback will be for your "onClick" action.

Ok but I want the button to listener for more events like hover, drag etc.

Well drag'n'drop is handled by the Drag and Drop and Data Transfer API and is, again, designed to provide an agnostic and re-usable workflow for what is, honestly, a very complicated feature.

And using actionListener might be useless for that moreover I'm keeping different responses for different kinds of events .

No, but you could use the ButtonModel instead, for example...

btn.getModel().addChangeListener(new ChangeListener() {
    @Override
    public void stateChanged(ChangeEvent e) {
        if (btn.getModel().isRollover()) {
            System.out.println("You have entered the spiders web");
        } else {
         System.out.println("You have escaped");   
        }
    }
});
btn.setRolloverEnabled(true);

(note - the JButton can also support "roll over" images automatically)

Or if you just wanted to display a tooltip you could just use...

btn.setToolTipText("What are you waiting for");

And if you wanted some custom keyboard action, you could make use of the Key Bindings API, for example...

InputMap im = btn.getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = btn.getActionMap();

im.put(KeyStroke.getKeyStroke(KeyEvent.VK_M, InputEvent.ALT_DOWN_MASK), "pressed");
am.put("pressed", new AbstractAction() {
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("Activiated via the keyboard");
        JButton btn = (JButton) e.getSource();
        btn.doClick();
    }
});

I would also recommend having a look at Introduction to Event Listeners.

Now, if you're really hell bent on making your own button, then JButton really isn't the place to get started. You'd want to look at ButtonUI and look and feel APIs, but this is a really advance level of Swing and to be honest, not many seasoned developers get down to this level.

But what about MouseWheel?

Why would need to do anything other than add a MouseWheelListener to an existing instance of JButton? What "extra" functionality do you intend to provide which wouldn't need to be delegated to another listener?

Sure, maybe you could use it as means to increase or decrease a counter I guess, but then, I'd probably only be using it a seperate MouseWheelListener any, it's not a feature that I'd consider useful on a regular bases ... in fact, I can't say I've ever used these two together.

Theres a general concept in OO, "prefer composition over inheritance", you might want to become familiar study up on it.

Runnable example...

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class Main {

    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            JButton btn = new JButton("Click me");
            btn.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    System.out.println("I was clicked");
                }
            });
            btn.getModel().addChangeListener(new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {
                    if (btn.getModel().isRollover()) {
                        System.out.println("You have entered the spiders web");
                    } else {
                        System.out.println("You have escaped");
                    }
                }
            });
            btn.setRolloverEnabled(true);
            btn.setMnemonic('m');

            InputMap im = btn.getInputMap(WHEN_IN_FOCUSED_WINDOW);
            ActionMap am = btn.getActionMap();

            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_M, InputEvent.ALT_DOWN_MASK), "pressed");
            am.put("pressed", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    System.out.println("Activiated via the keyboard");
                    JButton btn = (JButton) e.getSource();
                    btn.doClick();
                }
            });

            btn.setToolTipText("What are you waiting for");

            btn.addMouseWheelListener(new MouseWheelListener() {
                @Override
                public void mouseWheelMoved(MouseWheelEvent e) {
                    System.out.println("I've been wheeled");
                }
            });

            add(btn);
        }

    }
}

Please, understand, I'm not suggesting that you "can't" do all the things you're trying to do, what I'm trying to suggest is, first figure out "how" those things might be done already, then explore which ones do and don't work for you. From there you can start exploring alternative workflows.

  • Related