What does that Java construct do? - java

I new to java so bear with me if this is a ridiculously simple question but I am curious about this method call which has {code} being taken in - see code below for an example in the method addSelectionListener. What is the purpose of this? I have been looking through docs for an explaination but cant seem to find what this practice is called never mind any useful information.
setStatusLine.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
String message = "I would like to say hello to you.";
if (pressed) {
message = "Thank you for using me";
}
setStatusLine(message);
pressed = !pressed;
}
});
Thanks for any help or insights that can be offered

this is an Anonymous Class, or Anonymous inner class. If you google for that you will find some tutorials/examples. Sun has some docs too.

As the other contributors already said: It is an Anonymous Class
You could have created a new class named MyClass in a new file called McClass.java looking like that:
class MyClass extends SelectionAdapter {
public void widgetSelected(SelectionEvent e) {
<your code that's being executed whenever the widget is being selected>
}
}
Then you could have changed the first line like that:
setStatusLine.addSelectionListener(new MyClass());
See? Now you have an "explicit" class with just one function. Often that is too much overhead and would clutter your design.
Does that help?

The method addSelectionListener receives a SelectionListener instance. It doesn't receive "code". The confusing thing is the use of new <class/interface name>(){...}. This construct is used for anonymous inner classes. In fact what the code above does is extending the SelectionAdapter class, overriding its widgetSelected method, creating an instance of the new class and passing it to addSelectionListener().
Usage of anonymous inner classes is common with listeners, where we create a new class, to be used in one specific place. Therefore we don't give it a name, and we prefer implementing it directly in the context where it is being used.

There is not a method call in fact...
This code set a selection listener on the setStatusLine component.
An equivalent of this code could be
public class X implements SelectionListener{
//In the constructor or an other method.
setStatusLine.addSelectionListener(this);
public void widgetSelected(SelectionEvent e) {
String message = "I would like to say hello to you.";
if (pressed) {
message = "Thank you for using me";
}
setStatusLine(message);
pressed = !pressed;
}
}

It took me some time to understand Anonymous Inner classes. The basic things to remember are:
They are just like parameters, except instead of passing in an primitive or Object you pass in a class that implements an Interface/extends a class (yes they also work with interfaces) depending on method parameter.
They are anonymous, so "disappear" right after the method has popped off the stack.
}); is a dead give-away for an anonymous inner class.
They often pop-up in user interfaces for listener events
They save clutter in your code, but also make it harder to read.
For full punishment read the JLS: http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.9.5
If you are interested in knowing the nitty gritty about such things, reading the SCJP book and doing the exam is good or you can study the JLS. It won't learn you how to code, but it will help you understand how Java, and in some way, many other OO languages work.

Related

How can I make an Interface Private but used between two classes?

I want to create a private Interface in Class A and have it implemented by Class B. My intention is to have a way for Class A to call a method set on class B that NO ONE else can call. They are in separate file in separate packages. Anyone have any ideas?
The best you can achieve is to give the interface package level visibility and move Class A and B into the same package.
This doesn't stop someone adding another class into the same package in the future, thus giving it access to the interface.
short answer is redesign your class structure.
But if you really need to, consider to use reflex feature in java. and you can inject the method although not recommended.
Disclaimer: not a Java programmer.
But if you want to leverage a type system to get compile-time errors... there are often tricks by introducing a new data type as a sort of "access token" or "dummy parameter". Make it hard to get ahold of a value of that type, but require a value of that type as a parameter in the interface.
Yet introducing a hoop like that winds up being about as contrived as renaming your methods alarming things like DoFooActionOnClassB_ButDontCallUnlessYouAreClassA. I think one usually finds that in a good design, this "dummy type" isn't a dummy type at all... but a capture of the context and state that you should have had in the first place.
I understand that you want to have methods on class B which can only be called from class A. One way would be deferring the real check until runtime but let the compiler make it hard to do the wrong thing. So you could try using a secret which only class A can have in order to protect the method in class B.
public class A {
private static final PrivateA PROOF = new PrivateA();
public static class PrivateA {
private PrivateA() { }
// only A can extend PrivateA
}
public static void main(String[] args) {
new B().methodForAOnly(PROOF, "A");
}
}
Here A's PrivateA is a type which only A can instantiate or extend, and B knows about that...
public class B {
public void methodForAOnly(PrivateA proof, String param) {
if (proof == null) throw new NullPointerException();
// do something
System.out.println(param);
}
}

Understanding callbacks in Java

I have been trying to wrap my head around callbacks and have been struggling to grasp the concept. The following code is an example that I found here
starting from first to last I understand the flow to be such:
CallMe is instantiated, thus calling the constructor of said class
The variable en is set, subsequently instantiating the EventNotifier class and calling it's constructor which is passed a reference to the object CallMe
The variable ie is set to the object CallMe which was passed into the constructor
The variable somethinghappened is set to false (I would assume some conditional statement would be used to determine whether or not to set the value otherwise)
Ummm... done?
I do not understand this code. How does doWork get called? How does this signify an event? Why would one not simply call interestingevent from the constructor of callme .... For that matter why not just call dowork in place of whatever would change the value of somethinghappened?
Try as I might I cannot seem to grasp the idea. I understand that callbacks are used primarily to signify an event has occurred such as a mouse or button click but how does it make the connection between the event occurring and the methods being called? Should there not be a loop that checks for changes, and thus triggers the event?
Can someone please provide a (not over-simplified) explanation of callbacks in java and help clarify how something like this could be useful?
public interface InterestingEvent
{
public void interestingEvent ();
}
public class EventNotifier
{
private InterestingEvent ie;
private boolean somethingHappened;
public EventNotifier (InterestingEvent event)
{
ie = event;
somethingHappened = false;
}
public void doWork ()
{
if (somethingHappened)
{
ie.interestingEvent ();
}
}
}
public class CallMe implements InterestingEvent
{
private EventNotifier en;
public CallMe ()
{
en = new EventNotifier (this);
}
public void interestingEvent ()
{
// Wow! Something really interesting must have occurred!
// Do something...
}
}
EDIT: please see the comments in the approved answer... ---this--- link was very helpful for me =)
There is no main method or static blocks. Nothing is actually run from the code you posted; hence, doWork() is never called. I read the article and looked at the code, and it appears to be incomplete, or perhaps some code is left out because the author felt that it didn't need to be explained.
Here's the gist:
We have an interface InterestingEvent, a class EventNotifier, and another class CallMe, which implements InterestingEvent.
EventNotifier takes an InterestingEvent in its constructor, and sets somethingHappened to false.
The constructor for CallMe initializes its EventNotifier instance member by passing the EventNotifier constructor a reference to the CallMe object, itself.
The following is not in the code, but if we detect that some particular action takes place, we set somethingHappened = true. So after that, if doWork() is called for an EventNotifier, interestingEvent() will be called on that EventNotifier's InterestingEvent ie. We can do this, since CallMe implements InterestingEvent.
NB: This article was from 1996 and much has changed since then. You mentioned how to detect mouse click events, but this is different. The point of the article, I assume, was to show how you can use objects in conjunction with interfaces and booleans to see if something occurred.
To actually detect a mouse click, take a look at this tutorial. Here's another tutorial on Writing Event Listeners. Finally, since you asked about threading in a comment, here's a great book: Java Concurrency in Practice.
The way that I typically use callbacks is with PropertyChangeListeners/PropertyChangeSupport classes. There is probably of lot of different explanations about those classes that you might find helpful.
Anyway, to the point of your question.
First, you need to understand that the two classes you have are normally running on different threads. What the callback does is allow you to get an asynchronous notification that something has happened on the other thread. This allows the notified thread to do its part when it regains control. For example, you have a serial line that is receiving data. The InterestingEvent would be something like 10 characters have arrived on this line. Now, instead of having just one EventNotifier, you'd have one for each serial line coming in. The CallMe instance would be running doing something, periodically checking to see if interestingEvent had been called. interestingEvent would set some sort of flag so that CallMe would know that it had new data to process. When CallMe sees that, it takes care of whatever the interestingEvent was and then goes back to its normal activity.
The whole point of the interface is to have a well-defined way to access an instance of CallMe. If you develop this more, you are probably going to want to manage the other instances that are accessing your instance of CallMe. That's where reading up on the PropertyChange stuff that I mentioned earlier would be really helpful.

How do I call to a void method to incorporate it in a method in a different class?

My assignment is to create a program that simulates a simple online shopping program.
we have to:
create a main menu with 3 options and then a submenu when selecting the 2nd option on the main menu.
I'm unsure how call a method from another class for example:
I have been given a method:
public void start() {
which is in the file "GroceryStore.java"
I am supposed to create a topMenu method which when the user inputs "1" calls to the method:
public void displayItems(){
^in file called "Stock.java"
which then prints out an array of items that online store has in stock. The array in the
Stock.java is
private SalesItem[] items;
Can anyone tell me how to do this? I have to do this for several things and I'm hoping I can apply the skeleton of this to the rest of the cases.
For now, I'm going to assume that Stock is an instance type(it sounds like an instance type), and It would make sense that your GroceryStore would have a reference to 1 or more Stock items.
Your Stocks will have to be instantiated with the new keyword. so
Stock myStock = new Stock(/*parameters for constructor*/);
after you do that, you can call the displayItems method of myStock like so
myStock.displayItems();
so start() is in the GroceryStore class.
So in a public static void main class you would go :
GroceryStore gs = new GroceryStore();
gs.start();
In your GroceryStore class you would have a new method which looks like (You may want to have the Stock stock = new Stock() line in the constructor of the GroceryStore object-- would make more sense:
Stock stock = new Stock();
public void topMenu(int parm){
if(parm==1)then{
stock.displayItems();
}
}
And then finally in the Stock class you have the displayItems method which may look like :
public void displayItems(){
for(int i=0;i<items.length;i++){
SalesItem temp = items[i];
System.out.prinlnt(temp.toString());//or this may be temp.getName() or whatever returns a string from this SalesItem object - I dont know what it looks like - you never said!
}
}
It is however essential you actually understand what is going on here not just copy paste and run?! This wont actually do anything anyway until you have a call to the topMenu method passing it 1, so you will need to workout how you are going to interact with your gs object whether its by keyboard input, mouse click on a gui or something else :)
To call a method outside the current instance you have multiple options:
make the method static (so that it won't be attached to any particular instance) and call it through MyClass.method(), this has sense if it is a stateless object, mostly an utility method
create a static instance variable that can be accessed (so method is not static but the specific object is), then call it through SomeClass.stock.method(), this has sense when you want a single object of a specific type throughout the program
create a normal instance variable inside the class from which you want to call the method (this has sense just if the object contained is used in a HAS-A relationship). Then you call it simply doing this.stock.method() (you can omit this)
You need to tell the compiler where to get the methods from if the method is not in the same class. The best way of doing this would be to create an object that refers to the class you're trying to reach (using the New Java keyword and the appropriate syntax, i.e. ClassName objectName = new ClassName() - you may want to include any parameters you may have).
Have a look at this other StackOverflow answer - the user had a question very similar to yours, so it may help.
Also, there is a pretty good tutorial on objects and classes on TutorialsPoint. I suggest you have a look at it and give it a go. Try understanding the concept behind what you're trying to achieve first - I can guarantee you it will help later on as this is a very fundamental concept in OO programming.

Closure in Java or something like it

I have been trying to find a way to incorporate something similar to Closure in Java 1.6 since I'm developing for Android.
What I want (in a perfect world) I have a class, we will call it "Item".
I then have an arrayList of these.
ArrayList<Item> items = new ArrayList<item>;
In each one of them items.get(x) I want to save a block of code that will be executed when called. This block of code needs to take place in the scope of the class housing the ArrayList items.
My only, half brained idea, would be to create the methods in the class that housed "items" and save the name of the function in each of the "item" instances, then use reflection to call those methods....
I'm pretty doubtful that this could be possible, but this is the place I will find an answer either way.
Thanks ahead of time for any help.
What you need is an interface like
interface Closure{
public void exec();
}
and create an anonymous class for each "closure" code you want
Closure closure = new Closure() {
public void exec(){
// code here
}
}

Android / Java - How do I call upon a function in a separate *.java file?

I do an import of the full package name / java file, and if I do a <classname>.<method>, SOMETIMES I can get it to access - other times I get a lot of can't use a static in a non static bunch of talk.
I'll admit I'm new to Java, so what do I need to do? Call a class instance first, then call my methods? I'm rather confused by this, as I want to put all of my 'functions' into a FunctionsList.java file, and all of my main Activity (UI) into a MyActivity.java file.
For example:
<MyActivity.java>
import com.example.FunctionsList;
private class MyActivity extends Activity {
FunctionsList.function();
}
9/10 times I get that static/non-static error.
If I put all of my functions into MyActivity.java, I have zero problems! Anyone help me on what I presume is a basic Java newbie issue?
Here's an example that will hopefully help you out a little.
public class MyFunctionClass {
public String myFunction() {
return "This is an instance function.";
}
public static String myStaticFunction() {
return "This is a static function.";
}
}
Then in your activity you have something like this.
public class MyActivity extends Activity {
#Override
public void onCreate() {
// If you want to call your static function, you do not
// require an instance of a MyFunctionClass object.
String myStaticString = MyFunctionClass.myStaticFunction();
// If you want to call your instance function, then you need
// to create a MyFunctionClass first.
MyFunctionClass variableName = new MyFunctionClass();
String myInstanceString = variableName.myFunction();
}
}
As Jon mentioned, you'll probably save yourself some frustration if you read up on object-oriented programming before diving in. There are some basic things that a new programmer will need to understand before diving in. Good luck!
If you want to use a non-static method, you have to have an instance of the class to call the method on. If you want to use a static method, you don't need an instance.
As an example, suppose you tried to call String.length() - what could that return? It's trying to find the length of something, but you haven't specified which string you're interested in. The same is true for other instance methods - the results will usually depend on which object you're calling them on, which is why they're instance methods to start with.
As an aside, I would strongly recommend you to learn the basics of Java first, before trying to use Android. That way when you get into genuinely tricky problems, you won't have to wonder whether it's part of Android or whether it's a simple Java error. See my answer on a related question for more advice about this.

Categories