Object within another object, require them to modify values used elsewhere - java

I have currently created a new CountDownTimer object in my java file, I then have that timer have an onFinish() method where it makes another new CountDownTimer object that has required functionality in it's own onFinish() method.
However when I create a boolean value outside of the second timer (and maintain it as false) and then attempt to modify this boolean to true within the onFinish() method of the second timer it gives me the error:"Variable [boolean variable name] is accessed from within inner class, needs to be declared final".
When I declare the variable final though I absolutely cannot modify it.
So what is the most effective way to go about resolving this problem? I cannot lose the functionality of the timers, yet my experience with java is very shallow. I apologise if this question seems silly.
I would love to also use something like a getter/setter method but with a timer I am not sure if that would even be effective.
Thank you to everyone who replies in advance! It is greatly appreciated! :)
For the sake of clarity: I require the timer to set a boolean flag that will detect that the second timer has indeed finished. This will set the boolean flag to true and then with that I modify the functionality of a button I created. In a similar fashion I also desire this second timer to initialize a long value to be referenced outside of it as well.
If the boolean = false then the button causes a rejection of the user.
If the boolean = true then the button accepts the user.
And then I use the long number obtained below.
Code as requested:
boolean clickAppropriate = false;
new CountDownTimer(t1, t2) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
mTextField.setText("text");
new CountDownTimer(t3, t4) {
public void onTick(long millisUntilFinished) {
public void onFinish() {
long startTime = System.nanoTime();
clickAppropriate = true;
}
}.start();
}
}.start();

Easiest fix I see here without modifying the structure of your solution is to choose ´final boolean[] clickAppropriate = new boolean[1]´ and work with ´clickAppropriate[0]´ element instead. Choosing AtomicBoolean might give extra benefit if you work with multiple threaded environment.

You can use the this keyword together with the outer class (The class where the boolean is declared) name to access its member.
Example:
public class Outer {
public boolean bool = false;
public class Inner {
public void displayOuterClassVariable () {
System.out.println(Outer.this.bool);
}
}
}
In your case, you need to use your outer class name with clickApprpriate. But it seems like your variable is declared in a method. You have to put that variable in the class in order to use this syntax.

This is an interesting question. The way that you have your code currently structured, you will not be able to alter the contents of your clickAppropriate variable from within your anonymous CountDownTimer class declaration.
This is what Oracle writes in regards to accessing local variables from within Anonymous Classes:
"An anonymous class cannot access local variables in its enclosing scope that are not declared as final or effectively final."
http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html
This is the reason why your compiler is giving you this error.
One way that you can access and alter your clickApproriate variable from within your anonymous class is to change this variable from being a local variable to being a class variable.
I was able to successfully compile the below code without any errors.
public class Main
{
static boolean clickAppropriate;
public static void main(String args[])
{
clickAppropriate = false;
new CountDownTimer()
{
public void onFinish()
{
clickAppropriate = true;
};
}.start();
}
}
One thing that I would point out that is not evident - your use of anonymous classes is in affect overriding any code declared in your class file. For example, each time you declare your anonymous class CountDownTimer as follows:
new CountDownTimer(t1, t2) {
public void onTick(long millisUntilFinished) {
}
};
This is overriding any code in the onTick() method that might be present in the CountDownTimer class file. This is correct when the onTick() method is abstract, but might not be what you had intended if this method is a regular class method. Best of luck.

Related

Variable is accessed from within inner class

I have these varibles:
private boolean MineRunning;
private BigInteger MineProfit;
etc....
I want to call the countdown method:
countdown(MineRunning, MineProfit, MineTime, MineProgressbar, MineProgressstatus);
ca. 10 Times for different things
The method:
private void countdown(boolean running, BigInteger profit, BigInteger time, ProgressBar progressBar, int progressStatus) {
if(!running && Reference.Storage_Filled.add(profit).compareTo(Reference.Storage_Capacity) == 0 ||
!running && Reference.Storage_Filled.add(profit).compareTo(Reference.Storage_Capacity) == -1){
running = true;
new CountDownTimer(time.longValue(), Reference.countDownInterval.longValue()){
public void onTick(long millisUntilFinished){
progressStatus++;
progressBar.setProgress(progressStatus);
}
public void onFinish(){
Reference.totalGravel = Reference.totalGravel.add(profit);
Gravelrefresh();
progressStatus = 0;
progressBar.setProgress(progressStatus);
running = false;
}
}.start();
}
}
If I call this method i get an error:
variable is accessed from within inner class
I dont want to make the varibles to final because I have to edit these in the method. What can I do instead?
Thanks.
If your inner class is performing work on a separate thread, which seems to be the case here, you cannot access variables from this inner class. What you can do however, you can pass these variables as parameters to your inner class constructor, create new variables, copy them and manipulate.
Or you just declare them as final, that's not a problem most of the time.
Any variable accessed by an inner class must either be final or be a class scoped variable. There is no way around that. Either don't update those variables, or follow the rules.
Adding final normally isn't a problem. Final doesn't prevent you from mutating an object, it just prevents you from assigning to the reference. You can still call a function like setProgress that changes its internal state.
What if you make those variables static
private static boolean MineRunning;
private static BigInteger MineProfit;
...
And make your method parameter less
private void countdown(){
//Your code here
}

Java default constructor without initialization

I have a class similar to the below one with all static methods. Hence the class was not initialized while used in other classes. I have to check a condition before invoking any static methods from this class. Even if i add a default constructor it will not get called. Could someone suggest ideas to have solution without instantiating this class in all of its usages? It need be a default constructor could be a simple other solution.
I need to check everytime the network connectivity before making the call. Static Initializer gets called only first time on load.
public class ABCServerUtil {
public static boolean checkServer() {...bla...bla...}
}
I need some thing like below piece of code to be called and to be exit.
public ABCServerUtil(){
if(!isNetworkOnline())
return;
}
If you need to check the condition every time one of the static methods is called, you don't have much choice but to do what you're doing: Call a method to do the check at the beginning of each of those methods.
If you only need to check the condition once when the class is initially loaded/initialized, you can use a static initializer:
public class ABCServerUtil {
static {
// Code here runs when the class is loaded
}
// ...
}
Use a static Initialization block
static {
//whatever code for initialization
}
A class can have any number of static initialization blocks
they can appear anywhere in the class body
static initialization blocks are called in the order that they appear in the source code.
You should be called every time when method called
public class Test {
public static void checkServer() {
if (!checkNetwork()) {
return;
}
}
public static void checkClient() {
if (!checkNetwork()) {
return;
}
}
private static boolean checkNetwork() {
return true; // or false depending on network condition
}
}
You can use a static initialiser.
static {
// code here
}
It will be run before any method of property (static or otherwise) of the class is first accessed.
you can directly call a static method with the class name like this,
boolean val=ABCServerUtil.checkServer();
some tutorial is given here
Since there's already 5 answers saying the same thing and none of them seem to be what you're after:
A tool like Byte Buddy sounds like what you need.
I think that this is your solution: Static initializer in Java
In practice you need a block of code executed the first time that your class is loaded.

Modify the action of a class depending on a option in a another class?

This is a question about style. What is the cleanest solution to this case:
I have a Runnable class:
class R implements Runnable {
public void run(){
System.out.print("hello")
}
}
And another class that starts this class like this:
Thread t = new Thread(new R());
t.start;
My question is that if i need run to do something a bit more different depending on an radio button selected in the class that starts the thread what would be the best way to pass it on to the Runnable class?
Should i just make a constructor and add a Boolean witch action to perform? Or make a public boolean and set it to true false before running the thread? Or should i define an Enum in R class with the different actions and pass it on? Or some other way?
I would agree that the best way is for the Runnable's constructor to accept whatever parameters are required for execution. For example:
class R implements Runnable {
private final boolean myBool;
public R(boolean myBool) {
this.myBool = myBool;
}
public void run(){
if (myBool) {
System.out.print("hello");
} else {
System.out.print("goodbye");
}
}
}
In general, making public global variables (the other alternative you've mentioned) is bad practice. The method listed above ensures encapsulation; only the things that need to know about the value know about it. This ensures that as your system grows more complex, no other classes are messing up your values :-)

Call a non static void from another class

I am trying to end an never ending circle. I need to call a void that is not static from another class. The reason that I do not make it static is that some things are very hard to make static. (Everything inside a static void needs to be static).
I am trapped in a circle where I need to call a non static void from another class. I can not make it static because it some code do not like to be passed.
Till now I solved it sort of by a handler:
public static void change(){
//This is called to change a boolean
start=true;}
private void startDone(){
int timeBetweenChecks = 50;
final Handler h = new Handler();
h.postDelayed(new Runnable(){
public void run(){
if (start==false){
startDone();
} else{
//Do something
}
}
}
}, timeBetweenChecks);
};
The problem with this is that I have to run a handler that is checking if something has changed pretty often(In my case).
Is there any way of calling the non static startDone() directly?
If you are asking if there is a way to call a non-static method of a class without instantiating an object of that class, then no.
If I don't own a dog, I cannot tell my dog to sit.
The answer to your question is: No, you cannot call a non-static method from a static method without an instance of the class containing the non-static method.
To solve your problem: maybe the best way would be to broadcast an intent from change().
Something like:
public static void change(Context c){
start=true;
c.sendBroadcast(new Intent("CHANGE_HAS_BEEN_CALLED"));
}
Then in the non-static code of your activity you can register a receiver like this:
IntentFilter filter = new IntentFilter();
filter.addAction("CHANGE_HAS_BEEN_CALLED");
registerReceiver(new BroadcastReceiver() {
#Override public void onReceive(Context context, Intent intent) {
if (start==false){
startDone();
} else{
//Do something
}
}
}, filter);
By definition, if startDone() is non-static, then it makes no sense to call it unless you've instantiated the class that contains it. A non-static method is an instance method, which means it can return a different result for every object of its enclosing type.
I think what you want is a class that only contains startDone(). You want to instantiate the class once for your entire application, and then be able to call startDone().
Suppose the class is called ItsDone. Instantiate it as a singleton, then return the singleton when you do a "new", and call startDone().
a handler that is checking
if something has changed pretty often (In my case).
Sounds like callback to me. You pass a piece of code to that "something", and this piece of code is executed by "something" whenever its state changes. If you have control over this "something", it's very easy to implement such behavior, if you don't (if "something" is a part of some library), it probably has this behavior implemented (of course, if it is well-designed).
Anyway, checking the state "something" by querying it every, say, 50 ms is not the way to go.
The accepted answear for this question is a better solution then the solutions that are already sugested. Hope this will help anybody googling.

inner class non-final variable java

I needed to change variables inside an inner class and I got the infamous "Cannot refer to a non-final variable inside an inner class defined in a different method" error.
void onStart(){
bt.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
int q = i;
}
});
}
I quickly made a class that held all of the things I wanted to change and made a final version of the class outside the inner class
class temp{
int q;
}
void onStart(){
final temp x = new temp();
bt.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
x.q = i;
}
});
}
This seems to be what I need and it works but I am wondering if this is how to correctly work around the problem. Also, I really hate using the word temp to name my class. Is there an actual programming term for what I did so that I make a more descriptive name for my class?
You can simply create an inner class instead of an anonymous one (like you are currently doing). Then you have a constructor and any other methods you want to set your members. No hackiness required (like the array of 1 case).
I find this cleaner if the class requires any exchange of data with its outer class, but admit it is a personal preference. The array of 1 idiom will work as well and is more terse, but frankly, it just looks fugly. I typically limit anonymous inner classes to those that just perform actions without trying to update data in the outer class.
For example:
private MyListener listener = new MyListener();
void onStart(){
bt.setOnClickListener(listener);
}
class MyListener implements OnClickListener
{
String name;
int value;
void setName(String newName)
{
name = newName;
}
void setValue(int newValue)
{
value = newValue;
}
public void onClick(View v)
{
// Use the data for some unknown purpose
}
}
If there are multiple threads involved, then appropriate synchronization will have to be used as well.
I posted a similar answer in my other thread here. Basically the idea is to create a "wrapper" which wraps over pretty much any Object type. Since final in Java stands for "no reassignment" and not "constant", this trick pretty much works out fine. But as mentioned in the original post, make sure you tread with caution when using it in a multi-threaded environment.
I would keep a reference to your on click listener in the outer class, and make the int a member variable in your listener. Just store the variable in the listener on click, then grab the variable in the outer class when you need it, rather than setting it at the point of the click.
To put it simply, if the inner class needs to change it, make it a variable in the inner class.
Since you appear to be setting multiple things (from the comments), make a method in the main class, button1WasClicked(), (a better name might be doUpdate, doSave etc. - something relevant to what the button does), put the proper code there, and call it from the inner class / listener. (If you are using Swing I'd make it an Action, YMMV)
That way if later on there is a menu or an intent or a gesture that needs to execute the same stuff, the call is there.

Categories