This forum is in archive mode. You will not be able to post new content.

Author Topic: [JAVA] local variable a is accessed from within inner class; needs to be declare  (Read 6308 times)

0 Members and 1 Guest are viewing this topic.

Offline evilhacker

  • Peasant
  • *
  • Posts: 128
  • Cookies: 222
    • View Profile
Me and Deathspirit are working on a server and we're stuck here:
Code: (java) [Select]
Christmas.java:61: local variable a is accessed from within inner class; needs to be declared final
Client c = (Client) PlayerHandler.players[a];
                                          ^
Christmas.java:123: local variable a is accessed from within inner class; needs to be declared final
Client c = (Client) PlayerHandler.players[a];
                                          ^
2 errors

Tried whatnot and just can't seem to figure out how to fix this.

The Christmass class:
Code: (java) [Select]
import java.io.*;
 
//Hoodconnection, bitch. :)
 
public class Christmas {
 
public void treeChange(int a) {
Client c = (Client) PlayerHandler.players[a];
if (c.tree == 0) {
    c.makeGlobalObject(3211, 3426, 10652 , 5, 10);
}
if (c.tree == 1) {
    c.makeGlobalObject(3211, 3426, 10653 , 5, 10);
}
if (c.tree == 2) {
    c.makeGlobalObject(3211, 3426, 10654 , 5, 10);
}
if (c.tree == 3) {
    c.makeGlobalObject(3211, 3426, 10658, 5, 10);
}
if (c.tree == 4) {
    c.makeGlobalObject(3211, 3426, 10660, 5, 10);
    }
}
 
public void baubleBoxCheck(int a) {
Client c = (Client) PlayerHandler.players[a];
    if (c.playerHasItem(6826) && c.playerHasItem(6832) && c.playerHasItem(6838) && c.playerHasItem(6844) && c.playerHasItem(6850)) {
        //Green
        c.greenB = 1;
        c.sM("You added baubles to the box.");
    }
    if (c.playerHasItem(6827) && c.playerHasItem(6833) && c.playerHasItem(6839) && c.playerHasItem(6845) && c.playerHasItem(6851)) {
        //Pink
        c.pinkB = 1;
        c.sM("You added baubles to the box.");
    }
    if (c.playerHasItem(6825) && c.playerHasItem(6831) && c.playerHasItem(6837) && c.playerHasItem(6843) && c.playerHasItem(6849)) {
        //Blue
        c.blueB = 1;
        c.sM("You added baubles to the box.");
    }
    if (c.playerHasItem(6823) && c.playerHasItem(6829) && c.playerHasItem(6835) && c.playerHasItem(6841) && c.playerHasItem(6847)) {
        //Yellow
        c.yellowB = 1;
        c.sM("You added baubles to the box.");
    }
    if (c.playerHasItem(6824) && c.playerHasItem(6830) && c.playerHasItem(6836) && c.playerHasItem(6842) && c.playerHasItem(6848)) {
        //Red
        c.redB = 1;
        c.sM("You added baubles to the box.");
    }
    c.fullBauble();
    c.doubleBaubleCheck();
    }
 
public void doubleBaubleCheck(int a) {
EventManager.getSingleton().addEvent(
    new Event() {
        public void execute(EventContainer g) {
Client c = (Client) PlayerHandler.players[a];
if (c.greenB == 0) {
        c.sM("Green bauble - none.");
} else if (c.greenB == 1) {
        c.deleteItem(6826, 1);
        c.deleteItem(6832, 1);
        c.deleteItem(6838, 1);
        c.deleteItem(6844, 1);
        c.deleteItem(6850, 1);
        c.sM("Green bauble - check.");
        }
if (c.pinkB == 0) {
        c.sM("Pink bauble - none.");
} else if (c.pinkB == 1) {
        c.deleteItem(6827, 1);
        c.deleteItem(6833, 1);
        c.deleteItem(6839, 1);
        c.deleteItem(6845, 1);
        c.deleteItem(6851, 1);
        c.sM("Pink bauble - check.");
        }
if (c.blueB == 0) {
        c.sM("Blue bauble - none.");
} else if (c.blueB == 1) {
        c.deleteItem(6825, 1);
        c.deleteItem(6831, 1);
        c.deleteItem(6837, 1);
        c.deleteItem(6843, 1);
        c.deleteItem(6849, 1);
        c.sM("Blue bauble - check.");
        }
if (c.yellowB == 0) {
        c.sM("Yellow bauble - none.");
} else if (c.yellowB == 1) {
        c.deleteItem(6823, 1);
        c.deleteItem(6829, 1);
        c.deleteItem(6835, 1);
        c.deleteItem(6841, 1);
        c.deleteItem(6847, 1);
        c.sM("Yellow bauble - check.");
        }
if (c.redB == 0) {
        c.sM("Red bauble - none.");
} else if (c.redB == 1) {
        c.deleteItem(6824, 1);
        c.deleteItem(6830, 1);
        c.deleteItem(6836, 1);
        c.deleteItem(6842, 1);
        c.deleteItem(6848, 1);
        c.sM("Red bauble - check.");
        }
            //Mod Brandon
            g.stop(); // stops the event from running
        }
    }, 500); // executes after 2,000 ms = 2 seconds
};
 
 
public void fullBauble(int a) {
EventManager.getSingleton().addEvent(
    new Event() {
        public void execute(EventContainer g) {
Client c = (Client) PlayerHandler.players[a];
if (c.greenB == 1 && c.pinkB == 1 && c.blueB == 1 && c.redB == 1 && c.yellowB == 1) {
        c.deleteItem(6853, 1);
        c.addItem(6855, 1);
        c.greenB = 0; c.pinkB = 0; c.blueB = 0; c.yellowB = 0; c.redB = 0;
    int Bauble[] = {6826, 6832, 6838, 6844, 6850, 6827, 6833, 6839, 6845, 6851, 6825, 6831, 6837, 6843, 6849, 6823, 6829, 6835, 6841, 6847, 6824, 6830, 6836, 6842, 6848 };
        for(int i = 0; i < Bauble.length; i++) {
                c.deleteItem(Bauble[i], 1);
                }
            }
            //Mod Brandon
            g.stop(); // stops the event from running
        }
    }, 300); // executes after 2,000 ms = 2 seconds
};
}//Last bracket

xor

  • Guest
You can't access a variable from within an inner class unless it's static or final in the parent class.


Also, why are you using this everywhere:



Code: [Select]
EventManager.getSingleton().addEvent(...

Singletons are a generally bad idea to begin with, I'd redesign your code.
« Last Edit: August 27, 2011, 05:57:37 PM by xor »

Offline evilhacker

  • Peasant
  • *
  • Posts: 128
  • Cookies: 222
    • View Profile
So... i need to make "public static int a" in the client class?

Also the event manager is not made by us. Blame the other dude. :P

xor

  • Guest
No, you need to redesign your code :P

The whole reason you're getting these inner class access errors is because of those EventManagers.

Offline evilhacker

  • Peasant
  • *
  • Posts: 128
  • Cookies: 222
    • View Profile
I was afraid you'd say that. Isn't there another way around? We need the event managers, they serve like timers for the stuff we want done.

xor

  • Guest
Why not just use Threads instead of event managers? Is EventManager something you have created yourselves?


I recommend you read the following and implement your event handlers better:

Lesson: Writing Event Listeners
http://download.oracle.com/javase/tutorial/uiswing/events/index.html




Another solution would be to create the new Event() outside of the singleton and just pass it to addevent. Like so.


Code: [Select]

public void doubleBaubleCheck(int a) {

    Event ev = new Event() {
        public void execute(EventContainer g) {
            Client c = (Client) PlayerHandler.players[a];
            // ... your other shit here
        }
    }, 500);

    EventManager.getSingleton().addEvent(ev);
}


This may run into a similar issue though..




Option 3


Because you're probably looking for Timers more than EventManagers. Take a look at this:


http://download.oracle.com/javase/1.4.2/docs/api/java/util/Timer.html
« Last Edit: August 29, 2011, 02:41:40 PM by xor »

Offline evilhacker

  • Peasant
  • *
  • Posts: 128
  • Cookies: 222
    • View Profile
Thanks a lot for the tips.

I tried the solution, but i'm now getting this:
Code: (java) [Select]
Christmas.java:15: <identifier> expected
    }, 500);
      ^
Christmas.java:15: illegal start of expression
    }, 500);
          ^
2 errors

Can't seem to figure out how to exactly fix this. I tried looking at an other EventManager method and the brackets and all that look exactly like this one.

Offline DeathSpirit

  • Serf
  • *
  • Posts: 23
  • Cookies: 0
  • I am god.
    • View Profile
Why not just use Threads instead of event managers? Is EventManager something you have created yourselves?


I recommend you read the following and implement your event handlers better:

Lesson: Writing Event Listeners
http://download.oracle.com/javase/tutorial/uiswing/events/index.html




Another solution would be to create the new Event() outside of the singleton and just pass it to addevent. Like so.


Code: [Select]

public void doubleBaubleCheck(int a) {

    Event ev = new Event() {
        public void execute(EventContainer g) {
            Client c = (Client) PlayerHandler.players[a];
            // ... your other shit here
        }
    }, 500);

    EventManager.getSingleton().addEvent(ev);
}


This may run into a similar issue though..




Option 3


Because you're probably looking for Timers more than EventManagers. Take a look at this:


http://download.oracle.com/javase/1.4.2/docs/api/java/util/Timer.html

Yes, I wrote the EventManager:
A simple interface for an Event.
Code: [Select]
public interface Event {
 /**
  * Called when the event is executed.
  *
  * @param container
  *            The event container, so the event can dynamically change the
  *            tick time etc.
  */
 public void execute(EventContainer container);
}
Holds extra data for an event (for example the tick time etc).
Code: [Select]
public class EventContainer {
 /**
  * The tick time in milliseconds.
  */
 private int tick;
 /**
  * The actual event.
  */
 private Event event;
 /**
  * A flag which specifies if the event is running;
  */
 private boolean isRunning;
 /**
  * When this event was last run.
  */
 private long lastRun;
 /**
  * The event container.
  *
  * @param evt
  * @param tick
  */
 protected EventContainer(Event evt, int tick) {
  this.tick = tick;
  this.event = evt;
  this.isRunning = true;
  this.lastRun = System.currentTimeMillis();
  // can be changed to 0 if you want events to run straight away
 }
 /**
  * Executes the event!
  */
 public void execute() {
  this.lastRun = System.currentTimeMillis();
  this.event.execute(this);
 }
 /**
  * Gets the last run time.
  *
  * @return
  */
 public long getLastRun() {
  return this.lastRun;
 }
 /**
  * Returns the tick time.
  *
  * @return
  */
 public int getTick() {
  return this.tick;
 }
 /**
  * Returns the is running flag.
  *
  * @return
  */
 public boolean isRunning() {
  return this.isRunning;
 }
 /**
  * Stops this event.
  */
 public void stop() {
  System.out.println("EventManager: EventManaged command has been executed.");
  this.isRunning = false;
 }
}
Manages events which will be run in the future. Has its own thread since some
events may need to be ran faster than the cycle time in the main thread.
Code: [Select]
import java.util.ArrayList;
import java.util.List;
public class EventManager implements Runnable {
 /**
  * A reference to the singleton;
  */
 private static EventManager singleton = null;
 /**
  * The waitFor variable is multiplied by this before the call to wait() is
  * made. We do this because other events may be executed after waitFor is
  * set (and take time). We may need to modify this depending on event count?
  * Some proper tests need to be done.
  */
 private static final double WAIT_FOR_FACTOR = 0.5;
 /**
  * Gets the event manager singleton. If there is no singleton, the singleton
  * is created.
  *
  * @return The event manager singleton.
  */
 public static EventManager getSingleton() {
  if (singleton == null) {
   singleton = new EventManager();
   singleton.thread = new Thread(singleton);
   singleton.thread.start();
  }
  return singleton;
 }
 /**
  * Initialises the event manager (if it needs to be).
  */
 public static void initialise() {
  getSingleton();
 }
 /**
  * A list of events that are being executed.
  */
 private List<EventContainer> events;
 /**
  * The event manager thread. So we can interrupt it and end it nicely on
  * shutdown.
  */
 private Thread thread;
 /**
  * Initialise the event manager.
  */
 private EventManager() {
  events = new ArrayList<EventContainer>();
 }
 /**
  * Adds an event.
  *
  * @param event
  *            The event to add.
  * @param tick
  *            The tick time.
  */
 public synchronized void addEvent(Event event, int tick) {
  events.add(new EventContainer(event, tick));
  notify();
 }
 @Override
 /**
  * Processes events. Works kinda like newer versions of cron.
  */
 public synchronized void run() {
  long waitFor = -1;
  List<EventContainer> remove = new ArrayList<EventContainer>();
  while (true) {
   // reset wait time
   waitFor = -1;
   // process all events
   for (EventContainer container : events) {
    if (container.isRunning()) {
     if ((System.currentTimeMillis() - container.getLastRun()) >= container
       .getTick()) {
      container.execute();
     }
     if (container.getTick() < waitFor || waitFor == -1) {
      waitFor = container.getTick();
     }
    } else {
     // add to remove list
     remove.add(container);
    }
   }
   // remove events that have completed
   for (EventContainer container : remove) {
    events.remove(container);
   }
   remove.clear();
   // no events running
   try {
    if (waitFor == -1) {
     wait(); // wait with no timeout
    } else {
     // an event is running, wait for that time or until a new
     // event is added
     int decimalWaitFor = (int) (Math.ceil(waitFor
       * WAIT_FOR_FACTOR));
     wait(decimalWaitFor);
    }
   } catch (InterruptedException e) {
    break; // stop running
   }
  }
 }
 /**
  * Shuts the event manager down.
  */
 public void shutdown() {
  this.thread.interrupt();
 }
}

 
 

xor

  • Guest
I may have miscalculated the brackets and shit cause your code is a bit messy :P

You should have known how to fix it if you wrote the EventManager! Just look at the definition.

Code: [Select]
public synchronized void addEvent(Event event, int tick) {

So you should remove the 500 bit from where you define a new Event() and use it in addEvent instead.

Code: [Select]
EventManager.getSingleton().addEvent(ev, 500);
« Last Edit: August 30, 2011, 02:03:06 PM by xor »

Offline DeathSpirit

  • Serf
  • *
  • Posts: 23
  • Cookies: 0
  • I am god.
    • View Profile
Yeah well, I asked Mitko to search for the solution since we're part of a development team, I want him to find out stuff too.  :D

Offline puddi

  • Voted Best Avatar
  • VIP
  • Royal Highness
  • *
  • Posts: 662
  • Cookies: -2074
  • Stop being a fag today!Join #puddimasterrace @ IRC
    • View Profile
u guys are dumb. simple solution is this
Code: [Select]
public void doubleBaubleCheck(int a) {

    Event ev = nɛw Event() {
        public void execute(EventContainer g); {
            Client c = (Client) PlayerHandler.players[a];
            // ... your other shit here
        }}
    }, 500);

    EventManager.getSingleton().addEvent(ev);
}}

Do you got a cool story you would like to share bro?

The following users thanked this post: puddi

xor

  • Guest


Yeah well, I asked Mitko to search for the solution since we're part of a development team, I want him to find out stuff too.  :D


So... did my suggestion fix the problem? :D




... and puddi, not only did you almost post a complete replica of my {broken} code, but you also added another bracket on the end, which would just cause another error to come up xD

Don't troll a programmer bish
« Last Edit: August 30, 2011, 05:01:23 PM by xor »

Offline DeathSpirit

  • Serf
  • *
  • Posts: 23
  • Cookies: 0
  • I am god.
    • View Profile


So... did my suggestion fix the problem? :D




... and puddi, not only did you almost post a complete replica of my {broken} code, but you also added another bracket on the end, which would just cause another error to come up xD

Don't troll a programmer bish
No, it didn't.

xor

  • Guest
That will be because the Event() is defined in-line, making it an inner-class. I figured as much.

First thing I would recommend is assigning all of those integer values to static finals (constants) so it actually makes more sense when reading the code. c.playerHasItem(6823) && c.playerHasItem(6829) && c.playerHasItem(6835) , doesn't make much sense unless you have an item lookup table.

Not sure how to fix your other problem with inner-classes, you should find a way to pass the variable to the Event class when you make it, perhaps another constructor, or the long winded way of redesigning your code. Which in the long run, might be simpler.

Offline DeathSpirit

  • Serf
  • *
  • Posts: 23
  • Cookies: 0
  • I am god.
    • View Profile
That will be because the Event() is defined in-line, making it an inner-class. I figured as much.

First thing I would recommend is assigning all of those integer values to static finals (constants) so it actually makes more sense when reading the code. c.playerHasItem(6823) && c.playerHasItem(6829) && c.playerHasItem(6835) , doesn't make much sense unless you have an item lookup table.

Not sure how to fix your other problem with inner-classes, you should find a way to pass the variable to the Event class when you make it, perhaps another constructor, or the long winded way of redesigning your code. Which in the long run, might be simpler.
Yes we had a item database

 



Want to be here? Contact Ande, Factionwars or Kulverstukas on the forum or at IRC.