I have the following Problem:
I have a function like this:
public void addActionListenerObject(Object object) {
object.addActionListener(this);
}
My problem is the following: I need a solution where I can pass any object with the addActionListener function as a parameter.
The list can be found here: https://docs.oracle.com/javase/tutorial/uiswing/events/eventsandcomponents.html
Is there a way to solve this problem without numerous instances?
Thanks
Keeping Signature
If you cannot change your method signature (i.e., if you must receive an Object, and call addActionListener() if there is such a method definition), a more general/robust solution would be using Java Reflections to check wether the actual object has an addActionListener() method defined, and call it through reflections as well. Sounds a very hacky approach, anyway.
Changing Signature
If you can change your method signature, try using AbstractButton (https://docs.oracle.com/javase/7/docs/api/javax/swing/AbstractButton.html#addActionListener(java.awt.event.ActionListener)), which is the superclass that defines this method for JButton, JToggleButton and JMenuItem, for instance (see "Direct Known Subclasses" and the class definition tree to find out where the methods are actually provided).
This second approach will work only if there is actually a single superclass defining the method. If there is more than one, you'll have to check for the possible classes using if-else structure and instanceof + explicit cast (than you can keep your original Object signature).
If you give more information on your original problem (like, why do you need such a method), we'll probably be able to find better approaches.
Pass a functional interface (>= Java 1.8 only) if you are allowed to change the signature of addActionListenerObject:
public class Just {
private ActionListener actionListener;
public void addActionListener(ActionListener actionListener) {
this.actionListener = actionListener;
}
public void doIt() {
System.out.println("Hello");
actionListener.actionPerformed(new ActionEvent(this, 3, "World"));
}
}
public class MyActionListener implements ActionListener {
public void addActionListenerObject(Consumer<ActionListener> consumer) {
consumer.accept(this);
}
#Override
public void actionPerformed(ActionEvent e) {
System.out.println(e.getActionCommand());
}
}
That way, the classes that add the action listener (in my example this is Just) need not to implement an interface.
Use it:
Just just = new Just();
MyActionListener listener = new MyActionListener();
listener.addActionListenerObject(just::addActionListener); // Aha!
just.doIt();
This prints:
Hello
World
What you're looking for is polymorphism. All instances of type Component have the addActionListener method. Change your method signature to expect a Component, not an Object.
I thought addActioListener was inherited from Component. It is not.
The method is individually added to each component type, with no parent class.
Related
I have a method which adds Objects to an static list like this:
#PostConstruct
protected void registerToTransactionList() {
TransactionValidator.registerTransactionList(this);
}
registerTransactionList method just adds "this" to the static list, this method is in BalanceTransactionValidator class which extends TransactionValidator (owner of static list),the problem is all subclasses of BalanceTransactionValidator class are added to static list either,and if I override registerToTransactionList method in them like this:
#Override
#PostConstruct
protected void registerToTransactionList() {
}
It doesn't add subclasses but doesn't add BalanceTransactionValidator either. Can anybody help me on this? Please notice sublasses are overriding this method by default.
make the method private to block the visibility
private void registerToTransactionList() {
}
or make the method final to block it from been override
protected final void registerToTransactionList() {
}
There are two ways of achieving that:
Keep your method as it is; but then you have to actively check for the type of your objects before externally calling that method
Change your whole logic and make that method private
It won't help to make the method final as suggested in one of the comments - your problem is not that subclasses are overwriting that method; in essence, you have a design problem: you wish that subclasses should not invoke that method at all.
So, the only real option that makes sense here is "2.". You see, by having public method on a class that you want to be extended you are implicitly saying: it is perfectly fine to call that method; on any object that is instance of the base class (or child class!).
And in your case, that is not true: you actually do not want that the code behind this method runs for child classes. Then you shouldn't put that method in the list of public/protected methods of your base class!
Finally: you might want to step back and do some reading about good OO design. Class hierarchies do not fall from the sky: you willfully design them for a certain purpose. In other words: there is more to inheritance than just putting some "A extends B" on your class declaration. You have to understand each and every method on your B class; and how your child classes should deal with them!
EDIT: after some more thinking, I guess you are doing things "the wrong way", like:
class BaseClass {
public final void doRegistration() {
BaseClass toRegister = getObjectForRegistration();
if (toRegister != null) { ... register toRegister ...
}
protected BaseClass getObjectForRegistration() {
return null;
}
With that code, you could then put
protected BaseClass getObjectForRegistration() {
if (this instanceof ClassThatShouldBeRegistered) {
return this;
}
return null;
}
into that one class that wants to be registered. Probably there could be even nicer ways of doing so; but after some thinking I don't see how we could avoid the instanceof. But the above code should work; and it only requires specific code only in your base class and in that one class that wants to register something.
This may be something common and trivial, but I seem to be having trouble finding a concrete answer. In C# there is a concept of delegates, which relates strongly to the idea of function pointers from C++. Is there a similar functionality in Java? Given that pointers are somewhat absent, what is the best way about this? And to be clear, we're talking first class here.
The Java idiom for function-pointer-like functionality is an an anonymous class implementing an interface, e.g.
Collections.sort(list, new Comparator<MyClass>(){
public int compare(MyClass a, MyClass b)
{
// compare objects
}
});
Update: the above is necessary in Java versions prior to Java 8. Now we have much nicer alternatives, namely lambdas:
list.sort((a, b) -> a.isGreaterThan(b));
and method references:
list.sort(MyClass::isGreaterThan);
You can substitue a function pointer with an interface. Lets say you want to run through a collection and do something with each element.
public interface IFunction {
public void execute(Object o);
}
This is the interface we could pass to some say CollectionUtils2.doFunc(Collection c, IFunction f).
public static void doFunc(Collection c, IFunction f) {
for (Object o : c) {
f.execute(o);
}
}
As an example say we have a collection of numbers and you would like to add 1 to every element.
CollectionUtils2.doFunc(List numbers, new IFunction() {
public void execute(Object o) {
Integer anInt = (Integer) o;
anInt++;
}
});
You can use reflection to do it.
Pass as parameter the object and the method name (as a string) and then invoke the method. For example:
Object methodCaller(Object theObject, String methodName) {
return theObject.getClass().getMethod(methodName).invoke(theObject);
// Catch the exceptions
}
And then use it as in:
String theDescription = methodCaller(object1, "toString");
Class theClass = methodCaller(object2, "getClass");
Of course, check all exceptions and add the needed casts.
No, functions are not first class objects in java. You can do the same thing by implementing a handler class - this is how callbacks are implemented in the Swing etc.
There are however proposals for closures (the official name for what you're talking about) in future versions of java - Javaworld has an interesting article.
This brings to mind Steve Yegge's Execution in the Kingdom of Nouns. It basically states that Java needs an object for every action, and therefore does not have "verb-only" entities like function pointers.
To achieve similar functionality you could use anonymous inner classes.
If you were to define a interface Foo:
interface Foo {
Object myFunc(Object arg);
}
Create a method bar which will receive a 'function pointer' as an argument:
public void bar(Foo foo) {
// .....
Object object = foo.myFunc(argValue);
// .....
}
Finally call the method as follows:
bar(new Foo() {
public Object myFunc(Object arg) {
// Function code.
}
}
Java8 has introduced lambdas and method references. So if your function matches a functional interface (you can create your own) you can use a method reference in this case.
Java provides a set of common functional interfaces. whereas you could do the following:
public class Test {
public void test1(Integer i) {}
public void test2(Integer i) {}
public void consumer(Consumer<Integer> a) {
a.accept(10);
}
public void provideConsumer() {
consumer(this::test1); // method reference
consumer(x -> test2(x)); // lambda
}
}
There is no such thing in Java. You will need to wrap your function into some object and pass the reference to that object in order to pass the reference to the method on that object.
Syntactically, this can be eased to a certain extent by using anonymous classes defined in-place or anonymous classes defined as member variables of the class.
Example:
class MyComponent extends JPanel {
private JButton button;
public MyComponent() {
button = new JButton("click me");
button.addActionListener(buttonAction);
add(button);
}
private ActionListener buttonAction = new ActionListener() {
public void actionPerformed(ActionEvent e) {
// handle the event...
// note how the handler instance can access
// members of the surrounding class
button.setText("you clicked me");
}
}
}
I have implemented callback/delegate support in Java using reflection. Details and working source are available on my website.
How It Works
We have a principle class named Callback with a nested class named WithParms. The API which needs the callback will take a Callback object as a parameter and, if neccessary, create a Callback.WithParms as a method variable. Since a great many of the applications of this object will be recursive, this works very cleanly.
With performance still a high priority to me, I didn't want to be required to create a throwaway object array to hold the parameters for every invocation - after all in a large data structure there could be thousands of elements, and in a message processing scenario we could end up processing thousands of data structures a second.
In order to be threadsafe the parameter array needs to exist uniquely for each invocation of the API method, and for efficiency the same one should be used for every invocation of the callback; I needed a second object which would be cheap to create in order to bind the callback with a parameter array for invocation. But, in some scenarios, the invoker would already have a the parameter array for other reasons. For these two reasons, the parameter array did not belong in the Callback object. Also the choice of invocation (passing the parameters as an array or as individual objects) belongs in the hands of the API using the callback enabling it to use whichever invocation is best suited to it's inner workings.
The WithParms nested class, then, is optional and serves two purposes, it contains the parameter object array needed for the callback invocations, and it provides 10 overloaded invoke() methods (with from 1 to 10 parameters) which load the parameter array and then invoke the callback target.
Check the closures how they have been implemented in the lambdaj library. They actually have a behavior very similar to C# delegates:
http://code.google.com/p/lambdaj/wiki/Closures
Relative to most people here I am new to java but since I haven't seen a similar suggestion I have another alternative to suggest. Im not sure if its a good practice or not, or even suggested before and I just didn't get it. I just like it since I think its self descriptive.
/*Just to merge functions in a common name*/
public class CustomFunction{
public CustomFunction(){}
}
/*Actual functions*/
public class Function1 extends CustomFunction{
public Function1(){}
public void execute(){...something here...}
}
public class Function2 extends CustomFunction{
public Function2(){}
public void execute(){...something here...}
}
.....
/*in Main class*/
CustomFunction functionpointer = null;
then depending on the application, assign
functionpointer = new Function1();
functionpointer = new Function2();
etc.
and call by
functionpointer.execute();
I am newbie to java, and developing a real life project. I have many methods and about 2500 lines of code thus far. Many of the methods are slightly different(usually a difference of mere a single identifier) due to which i have to copy the code again and again with slight changes.
What i want is to pass a method as parameter to another method, I've gone through lambda expressions
but i could not find it enough appealing, off-course due to my own conceptual shortcomings. because it tells to define functional interface of each method to be passed. but as per my thoughts it would not give me a generic code so that i would be able to simply add some other Tables in future.
i am putting a piece of code to demonstrate and better explain my problem.
if(houseTabPanel.getComponentCount()==0){
houseTableDb();
}
if(isSelected){
selection(houseTable);
}
else {
houseTable.setColumnSelectionAllowed(false);
houseTable.setRowSelectionAllowed(false);
houseTable.setCellSelectionEnabled(false);
Rselection(houseTable);
}
now i have different methods named houseTableDb() , plotTableDb() , adminTableDb() etc.
i want to make a method of this piece of code and pass plotTableDb() etc as parameter..
something like...
public void genericMethod(JPanel p, JTable t, some method reference to use instead of houseTableDb){}
pardon me if am not descriptive enough.. any response would be truly appreciated by core of the heart.
Provided that all of these methods have the same signature you can define an interface with a single method with that signature (return value, parameter list). Then you write classes implementing the method, one for each method's implementation. For passing the method, you create an object of that class and pass the object. The call to the actual method is replaced by the call to the method defined in the interface.
interface Callee {
void meth();
}
class MethOne implements Callee {
public void meth(){...}
}
void caller( Callee callee ){
callee.meth();
}
Callee ofOne = new MethOne();
caller( ofOne );
But to avoid all this hazzle: that's why lambdas have been added...
You can do like this :
public void genericMethod(JPanel p, JTable t, TableDbCallBack tableDb)
{
if(p.getComponentCount()==0)
{
tableDb.run();
}
if(isSelected)
{
selection(t);
}
else
{
t.setColumnSelectionAllowed(false);
t.setRowSelectionAllowed(false);
t.setCellSelectionEnabled(false);
Rselection(t);
}
}
usage :
genericMethod(p, t, new HouseTableDb());
genericMethod(p, t, new AdminTableDb());
Implementation :
public interface TableDbCallBack extends Runnable {}
public class HouseTableDb implements TableDbCallBack
{
#Override
public void run()
{
// Whatever it should do
}
}
public class AdminTableDb implements TableDbCallBack
{
#Override
public void run()
{
// Whatever it should do
}
}
I have a abstract class to create tools (like illustrator pen, selection etc).
The idea is that users can create easily new tools if they like.
Some tools have a method called, "draggingSelection".
I wonder if there is a way to check if a class has that object, and if so, run it.
(In this case draggingSelection returns a boolean)
So far i can figure out if the method exists or not.
I only can't get it the method to run.
I tried things with invoke but i fail at it. My method doesn't requite any parameters.
Could somone help.
public boolean draggingSelection() {
Method[] meths = activeTool.getClass().getMethods();
for (int i = 0; i < meths.length; i++) {
if (meths[i].getName().equals("draggingSelection")) {
// how can i run it?
//return meths[i].draggingSelection(); // wrong
}
}
return false;
}
Better solution in my opinion is to check if given object's class implements some interface.
However, to call draggingSelection method, do it on an object that you are testing:
activeTool.draggingSelection()
You could do that via reflection, but a far better solution would be to have an interface that has all the relevant methods:
public interface SelectionAware {
public void draggingSelection(SelectionEvent e);
}
Once you have that, you have (at least) two options to use it:
let your tools implement that interface and use myTool instanceof SelectionAware followed by a cast to call that method or
let the tool explicitly register itself as a listener in some appropriate init method.
Option 1 is closer to what you attempted to do, but restricts the use of that interface and is not really clean code (because your code needs to "guess" if some tool implements some interface).
Option 2 is probably slightly more work (where/when to register/unregister the listener? ...), but is definitely the cleaner approach. It also has the advantage that the listeners are not restricted to being tools: anything could register such a listener.
public interface Draggable {
public boolean draggingSelection(int foo, int bar);
}
Then when you have a class with this method just add implements Draggable. Example:
public class Selection implements Draggable {
public boolean draggingSelection(int foo, int bar) {
(insert code here)
return baz;
}
(insert rest of code here)
}
Therefore your example would be:
if (activeTool instanceof Draggable) {
((Draggable)activeTool).draggingSelection(foo, bar);
}
I've come across some code that I can't share here but it declares a method WITHIN the paramter list of another method. I didnt even know that was possible. I dont really understand why its doing that. Can someone please explain to me some possible uses that you as a programmer would have for doing that? (Note: Since I can't show the code I dont expect an in-context explanation just generally)
Related:
What's the nearest substitute for a function pointer in Java?
Did the code look something like this?
obj.someMethod(myVar,3,new FooObject() {
public void bar() {
return "baz";
}
});
If so, then the method is not being passed to the other method as an argument, but rather an anonymous inner class is being created, and an instance of that class is being passed as the argument.
In the example above FooObject is an abstract class which doesn't implement the bar() method. Instead of creating a private class that extends FooObject we create an instance of the abstract class and provide the implementation of the abstract method in line with the rest of the code.
You can't create an instance of an abstract class so we have to provide the missing method to create a complete class defintion. As this new class is created on the fly it has no name, hence anonymous. As it's defined inside another class it's an anonymous inner class.
It can be a very handy shortcut, especially for Listener classes, but it can make your code hard to follow if you get carried away and the in line method definitions get too long.
In Java you can't pass methods as parameters. Could it have been passing not a method, but an anonymnous inner class?
This can be useful for passing behaviours between classes. Google "dependency injection" or "Inversion of control" for more information.
Have you ever seen the Functional Java?
It's a very interesting library that allows you programing like you would do in Scala.
I Wrote about this libs. I confess it is better to use in a more flexible syntax (BGGA closures) like Scala.
Using Functional Java with a high-order function like map on a list we have:
final List<Integer> numbers = list(1, 2, 3, 4, 5);
List<Integer> c = numbers.map(new F<Integer, Integer>() {
public Integer f(Integer arg) {
return arg * arg;
}
});
Another useful lib is lambdaj that offers nice ways to play like in Functional (FP) Programming.
Java has a limited syntax compared to FP languages. But you can still take some advantages of FP style, but you must be creative!
using java.lang.reflect.Method
example
public void callMethod(Method aMethod, int value) throws Exception {
aMethod.invoke(this, value);
}
public void print(Integer value) {
System.out.print(value);
}
public void println(Integer value) {
System.out.println(value);
}
public void demo() throws Exception {
Method println = this.getClass().getMethod("println", Integer.class);
Method print = this.getClass().getMethod("print", Integer.class);
callMethod(println, 10);
callMethod(print, 10);
}
The nearest thing to passing a function pointer in Java is passing an anonymous instance of an abstract class or interface. For example, a generic function type can be encoded in an interface like this:
public interface F<A, B> {
public B f(final A a);
}
You can then expect a method in another method's argument list:
public List<B> map(List<A> as, F<A, B> f) {
...
}
And you can call it with an anonymous instance of that interface:
map(myList, new F<Integer, String>() {
public String f(Integer i) {
return String.valueOf(i);
}
});
There's a library called Functional Java that exploits exactly this idea for great benefit glorious language Java.
It's not, per se, legal syntax in Java. Was it perhaps creating a new instance of an anonymous class?
You can also do something like this:
final Predicate somePredicate = new Predicate<Item>()
{
#Override
public boolean apply(Item item)
{
return item.someProperty().equals(something);
}
}
And use it like this:
List<Item> filteredList = filter(list, somePredicate);
I've done stuff like that before. I've also written methods that use a closure to build and return an anonymous implementation of an interface in a similar way:
Predicate isSomeColor(final Color color)
{
return new Predicate<Shape>()
{
#Override
public boolean apply(Shape shape)
{
return shape.getColor().equals(color);
}
}
}
List<Shape> redShapes = filter(shapes, isSomeColor(Color.RED);
All of this is still anonymous inner classes. Nowhere am I actually naming the class itself, I just have a reference to an instance of the class.
this is called reflection. there is a whole library of objects representing stuff like constructors, methods and such.
you can use it, for instance, in order to call a dynamic method that is determined on runtime.
Yes, declaration of a method within the parameter list of another method can be done. You can check out java.lang.reflect.Method
Using reflection, you retrieve a Method object representing the method you wish to pass as a parameter. Then you can call Method to invoke to make a call to that method.
Moreover, you can refer "Functional programming in the Java language" (http ://www.ibm.com/developerworks/java/library/j-fp.html) which can give you inside-out with examples.
The answers above are varying as to whether or not it is even possible. Is it possible through reflection? Is possible through the use of an anonymous inner class? We need to clarify this.
the closest to a function argument is
an instance of a anonymous class with exactly one method.
Runnable a = new Runnable(){
run(){
System.out.println("hello");
}
}
myMethod(a);
not pointer, but still you can write functions inline with some trick.
check my answer on another thread