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.