Instead of allowing the client to pass in an ActionListener
, have the client pass in a different callback, create your own listener, then have your listener invoke the callback:
public class MyComponent extends JPanel {
private final JButton jButton;
public MyComponent(){
jButton = new JButton();
}
public void addActionListener(SomeCallback callback){
jButton.addActionListener(event -> { //create listener
callback.execute(); //invoke callback
});
}
}
interface SomeCallback {
void execute();
}
If you want to pass the client the ActionEvent
without the ability to access ActionEvent#getSource()
, create a wrapper:
class ActionEventWrapper {
private ActionEvent event;
public MyActionEvent(ActionEvent event) {
this.event = event;
}
//expose methods that aren't getSource()
public String getActionCommand() {
return event.getActionCommand();
}
}
Simply add this type to the callback's method parameter:
interface SomeCallback {
void execute(ActionEventWrapper event);
}
You could then create a new ActionEventWrapper
anytime an event is triggered:
public void addActionListener(SomeCallback callback){
jButton.addActionListener(event -> {
callback.execute(new ActionEventWrapper(event));
});
}
If you really want to adjust the source of the component's listener's events, simply create a new ActionEvent
, specifying whichever source you want via the constructor:
public void addActionListener(ActionListener listener) {
jButton.addActionListener(event -> {
listener.actionPerformed(new ActionEvent(..., event.getID(), event.getActionCommand()));
});
}
The ...
is where you specify which component you want to act as the source.