If one has no intention of using a parameter in C++, one simply omits the name of the variable but keeps the type in the function declaration. Doing so is a light-weight method to signal to the compiler that one intends not to use a given parameter.
Is this possible to replicate in Java?
The scenario is this: I would like not to flood my code with #SuppressWarnings("unused") for every single button listener (because button listeners most often ignore the View v they receive), and yet I would like to be warned in general about the silly mistake of, say, not initializing a member variable by a parameter.
I can't think of anything like the C++ option but you could extend/implement your button listener and add a new method without the parameter and have that method called in the original event method. This way you will only have to suppress warnings once.
public void someEvent(Parameter p) {
someEvent();
}
public void someEvent() {
}
In addition to creating an adapter like #Farzad suggested, you might want to also check your compiler settings in your IDE. For example, I use Eclipse and there are error/warning compiler settings under Window->Preferences->Java Compiler->Errors/Warnings. Within that dialog you can set UnnecessaryCode->Value of parameter is not used->Ignore in overriding and implementing methods.
Having that option checked automatically ignores those unused params when they are from a method that you are implementing/overriding such as in your listener case. I generally find that to be sufficient without needing to create an adapter.
Related
I have an Eclipse plugin which has the purpose of indexing and searching XML files for custom frameworks used by the application my team develops.
There is a toolbar with several buttons on it. Each button has its own command and each command is linked to a separate handler which brings up a search dialog.
The handlers differ only by which file type they search. Currently there are ten concrete handlers and one abstract. All of the functionality is handled in the abstract class, and the concrete classes only implement an abstract "get file type" method.
Ideally I would only have one handler. This means there would need to be a way to inject the enum into the base class directly.
I looked at command parameters, but this appears to be user-facing. I need something hard-coded where the command tells the handler "use this value." I don't care if this is a constructor argument or some hard-coded parameter in plugin.xml.
Thus far I have not been able to find a way to do this. Perhaps my Google-fu is weak, perhaps I am just not seeing it.
Is there a way to specify a hard-coded parameter to a handler constructor or to call a method to set a parameter after it is constructed but before it is invoked?
Command parameters are the right way to achieve that. What are the problems you face with that? Here is an example to use the parameters
Please allow me to explain what I am trying to do - I think that the title explains it roughly, but I am none too sure that I am going about things the right way, so please correct me if I am wrong!
I have created a custom dialog using a LayeredPane. Essentially a jPanel is shown on the POPUP_LAYER, thus appearing over the top of the main content. This panel contains a simple 'label-textbox-okay-cancel' group of controls. I will call this the 'Dialog Panel'.
What am I trying to do:
When a button is clicked on the main window (contained within the LayeredPane), the Dialog Panel will appear and allow the user to enter some text, then click okay or cancel. This is all easy enough, but I would like this code to be re-usable, which means that other buttons on the main window will invoke the same Dialog Panel, but with different text in the label.
This of course requires me to include some kind of callback function so that the okay button on the Dialog Panel will run the correct code, according to the button which invoked it.
My current attempt is to store a string which will contain the name of the function that should be run when the user clicks the okay button on the Dialog Panel. I am attempting to retrieve this string and convert it into the function name and so far I have found many references to 'Reflection', many of them suggesting that it is not a good idea.
In any case I have been unable to get any example code to work because I do not understand what the 'obj' is in the code below and am unable to invoke the method:
method = obj.getClass().getMethod(myCallbackString);
My questions are:
Firstly, am I even going about this the right way? I am more than open to suggestions, but please try to keep it as simple as possible because I really am just getting started!
Secondly, what is the 'obj' in the code shown above? I would really like to know, even if this is not the way that I should be doing things!
My other thoughts include: Should my Dialog Panel be in its own class, and if so, again, how to pass the callback function?
Any help or advice would be gratefully received.
BTW: In answer to the question "why not use a normal dialog?" I can only say that I am currently experimenting, and I simply want to see if I can do this!
MVK
The usual way the callback functions are passed in by Java programs is by passing instances of interfaces that implement a specific callback function. It is typical, though not required, to implement the interface anonymously.
For example, here is an interface:
interface MyCallback {
void performCallback();
}
Here is the way you define your dialog's method that takes a callback:
void openWithCallback(MyCallback cb) {
// Do something useful...
...
// Perform the callback
cb.performCallback();
}
Here is the way that you invoke that method:
public void OpenDialog() {
myDialog.openWithCallback(new MyCallback() {
public void performCallback() {
System.out.println("Inside callback...");
}
});
}
obj names the object whose method you want to call, in your case you can probably replace it with this (or drop it out entirely, since this is implied):
private void callByName(String name) {
try { getClass().getMethod(name).invoke(this); }
catch (RuntimeException e) { throw e; }
catch (Exception e) { throw new RuntimeException(e); }
}
For this to work you need to declare a public no-arg method with the appropriate name.
I think your idea is valid, although it has a major drawback: you store the method names as simple strings in your code, so the compiler can't check them for validity. Therefore, if you change the name of a method, you manually have to make sure you have updated all the strings referencing it.
This is what's usually meant with 'reflection is a bad idea'.
obj in your code is the object on which you want to call a method. As a simple example, the equivalent of someInteger.toString(); with reflection would be someInteger.getClass().getMethod("toString").invoke();.
On a more generic note, once you're comfortable with Java, you might also check out a functional language like Scala, where functions are regular objects, and the scenario you intend could be implemented with full compiler checking.
I think that you're making this way more complicated than it has to be. You said you want this:
This is all easy enough, but I would like this code to be re-usable, which means
that other buttons on the main window will invoke the same Dialog Panel, but with
different text in the label.
A DialogBox is, by definition, reusable. Why don't you just have the button click listener pass the appropriate text to the dialog box when clicked, so it shows the correct information?
If you need specific actions to happen after a button click on the dialog depending on the invoker, you may want to consider:
Created a custom DialogBox extension that includes logic that knows what to do based on who called it. Then when a button invokes the custom dialog, it would pass it a parameter to let it know what it wants to do after the dialog box is dismissed.
Look into using something like the abstract factory pattern.
Yes, you could do this via reflection. Yes, it would be a very bad idea, for many reasons that other people have discussed in other answers, especially if this is production code (though you seem to indicate it's an experiment.)
If you really just want to see how to work it with reflection, you'll probably want to read up on that topic. I found this to be one of the better tutorials out there.
I haven't worked with JPanel, but what I understand form your query, answer seems rather simple. Instead of passing method name, why dont you work on interface and pass the different implementation of that interface?
It seems in an Activity, for example, the onCreate() method, it does not make much difference if I have the #Override annotation or not. They both work. (As long as I call super.onCreate() inside the callback , it will call the parent class' method.)
Can someone tell me why we need to have the #Override annotation for life-cycle callbacks in Activity ?
I ask this because I tested without #Override annotation, my app still running successfully.
This is more like a good development practice.
If by mistake you want to override a method that doesn't exist in the super class (or interfaces implemented) you'll get an error.
Think that you want to override "onCreate" but you misspell it and write "onCreatee". With that annotation, you'll get an error. Without it, you'd end up spend a lot time trying to understand why your initialization method was not working properly.
The #Override annotation is used just to tell the compiler that we are overriding a method in our code. This is used for safety purposes to let the compiler know the aim of our function (i.e. to override) and if we are overloading a function by any chance, the compiler will return an error. Hence with this annotation, we can detect overloading mistakes easily.
Some already mentioned that it is very useful to catch potential bugs with wrongly spelled names.
I would like to add that it
also shows which methods are new methods specific to your class and which are inherited from the parent class (or interface). It might not sound like much, but I personally find it very useful.
So you should always use #Override and configure your IDE to flag an error if you forget it.
In Eclipse, I would like to set a breakpoint on a Java default constructor. I can't simply double click to the left of any line of code since default constructors have no source code - they are implicitly generated by the Java compiler.
I'd like to be able to set such a breakpoint without modifying the existing code.
If the code where you want to set a breakpoint in, is on the build path and not in your project itself, then if you open the Outline view, you'll see that the default constructor is present there, and you can right-click on it and choose Toggle Method Breakpoint.
Note that sometimes the default constructor is filtered out of the Outline view. In that case it can be included by changing the filter settings. This is done by going to Outline view menu → Filters... → and unchecking Synthetic members.
This is in Eclipse Indigo, I don't know how long this functionality has been around.
If you really need it, set a method breakpoint in one of the other methods of the class, select the breakpoint (Breakpoints view) and export it. Edit this file so the breakpoint points to the standard constructor. At least the following attrib's must be changed (Galileo):
org.eclipse.jdt.debug.ui.JAVA_ELEMENT_HANDLE_ID
org.eclipse.jdt.debug.core.methodName - value="<init>"
org.eclipse.jdt.debug.core.methodSignature - value="()V"
message - no idea if that is really needed
probably easier to also export a constructor breakpoint from an other class to see the correct values. Now import the changed file and you should have your constructor breakpoint.
It's a hack, but worked for me...
I'd like to make a small improvement to the answer given by rsp, making it a bit easier, but I can't post comments yet.
If you create the default constructor (e.g. by pressing ctrl+alt+s and then c), place the breakPoint in the call to this constructor and then press ctrl+z to undo the creation of the default constructor you'll still have the breakpoint with no changes in the code.
Hope it helps
Solution 1: member initializers
If you have any member variables with initializers, then you can put a breakpoint on them. For example:
class MyClass {
private int i = 0; // this line can have a breakpoint in Eclipse
}
Solution 2: class load breakpoints
If you can get by with only hitting this breakpoint once, then you can use a class load breakpoint:
You can set a Class Load Breakpoint,
which will stop when the class is
being lodaed [sic]. Right-click on a class
in the Package Explorer, Project
Explorer, or Types view and choose
"Toggle class load breakpoint"
As the name implies, this breakpoint will be hit when the class is first loaded, so it will only fire once (assuming you only have a single classloader). But depending on your needs, it might be good enough.
you can do the following:
public class MyClass {
public MyClass() {
super();
}
}
And then put the break point on that. However, what are you hoping to accomplish by this?
How about creating a public no-argument constructor and setting a breakpoint on that? If that won't help, could you elaborate why not?
You can always create your own no-argument constructor and put the breakpoint there. More to the point, though, why do you want a breakpoint there? It will simply chain to the no-argument super(). If that has code you care about, put the breakpoint inside that constructor.
Your best bet is probably using an aspect based framework to inject the functionality you need in the classes.
I thought Eclipse provided a default constructor breakpoint, but alas only the class loaded breakpoint in the outline.
What problem do you need to actually solve?
You could consider the YouDebug framework, in order to script your debug session, including a breakpoint on any specific method of any class.
Breakpoints are event callback handlers that are invoked when a certain event occurs in the target JVM. You can create breakpoints by calling breakpoint methods on the 'vm' object. These methods takes a closure that gets invoked when the event occurs, and they often takes additional arguments to control the nature of the breakpoint.
The following code defines a breakpoint on line 7 of the org.acme.SubStringTest.java (or whichever source file this class is defined in:)
vm.breakpoint("org.acme.SubStringTest",7) {
println "I'm at SubStringTest.java line 7";
}
I am (supposed to be) creating a simple menu display. My Menu class creates a List of MenuOption objects and these can be displayed and selected, etc. A programmer can add options to the List in the Menu class, optionList, using the addOption method.
What I want to be able to do is make it so the programmer can associate any arbitrary method from one of his or her other classes with a specific option.
For example, I want it so if the programmer typed something like:
menu.addOption("Print a roster", roster.print());
then the addOption method would do something like this:
optionList.add(new MenuOption("Print a roster", roster.print()));
and then, henceforth, the method roster.print() would be associated with the menu option text "Print a roster" so if a user chose "Print a roster," roster.print() would be called.
===============================================
By the way, I have started looking into the new Lambda Expressions from Java 8, but I'm not quite sure how they work or if they provide the necessary approach I would need to achieve my desired effect.
Any help is appreciated, thank you!
The second parameter to the MenuOption constructor would have to be a Runnable, and you would be able to supply
roster::print
as a value. This is called a Method Reference, and is just syntactic sugar for creating an object that implements a Functional Interface (in this case Runnable). It could also be written as
() -> roster.print()
On button click you would need to call the run() method.