can't access arraylist

Discussion in 'Plugin Development' started by mrgreen33gamer, Sep 6, 2015.

Thread Status:
Not open for further replies.
  1. Offline

    mrgreen33gamer

    Hi there,

    So I did several tests with accessing arraylists in different classes just to see if classes were effecting the access, so far there is an issue I'm having with accessing arraylists.

    So here is the class:

    Code:java
    1.  
    2. package com.mrgreen33gamer.minigames;
    3.  
    4. import java.util.ArrayList;
    5. import java.util.List;
    6.  
    7. import org.bukkit.command.Command;
    8. import org.bukkit.command.CommandExecutor;
    9. import org.bukkit.command.CommandSender;
    10. import org.bukkit.entity.Player;
    11. import org.bukkit.event.EventHandler;
    12. import org.bukkit.event.Listener;
    13. import org.bukkit.event.player.PlayerMoveEvent;
    14.  
    15. public class Testy implements Listener, CommandExecutor {
    16.  
    17. public List<String> list = new ArrayList<String>();
    18.  
    19. @Override
    20. public boolean onCommand(CommandSender sender, Command cmd, String label, String[] arg) {
    21. if(label.equals("testy")){
    22. if(sender instanceof Player){
    23. Player player = (Player) sender;
    24. if(list.contains(player.getName())){
    25. player.sendMessage(">>> You've been removed.");
    26. list.remove(player.getName());
    27. }else{
    28. player.sendMessage(">>> You've been added.");
    29. list.add(player.getName());
    30. }
    31. }
    32. }
    33.  
    34. return false;
    35. }
    36.  
    37. @EventHandler
    38. public void PlayerMoveEvent(PlayerMoveEvent event){
    39. Player player = event.getPlayer();
    40. if(list.contains(player.getName())){
    41. player.teleport(event.getFrom());
    42. }
    43. }
    44.  
    45. }
    46.  
    47.  


    For some reason the MoveEvent isn't checking for me when I'm clearly contained when I use the command /testy.

    Any idea?
     
  2. Offline

    TomeDM

    Edits:
    - rephrased my wording
    - Deleted (false code)
     
    Last edited: Sep 6, 2015
  3. Offline

    Petersoj

    Did you register your events in your main class?
     
  4. Offline

    mrgreen33gamer

    @TomeDM Didn't change a thing. The event will work when I put something outside of it, but won't check for the LIST.

    @Petersoj I did.
     
  5. Offline

    SuperSniper

    @mrgreen33gamer
    You can't have Listener and CommandExecutor implementing into the same class, atleast not from my experience. Do this:

    1. Make your arraylist "public static"
    Show Spoiler
    Code:
    public static ArrayList<String> list =new ArrayList<String>();
    

    2. Make a new class called "Move" or anything you want and make it implement Listener.
    Show Spoiler
    Code:
    public class Move implements Listener {
    

    3. Put the PlayerMoveEvent into the "Move" class.
    Show Spoiler
    Code:
    public class Move implements Listener {
    
         
    @EventHandler
       public void PlayerMoveEvent(PlayerMoveEvent event) {
            Player player = event.getPlayer();
           if (Testy.list.contains(player.getName())) {
                player.teleport(event.getFrom());
           }
       }
    
    }
    


    4. Remove the PlayerMoveEvent and the implements Listener from your "Testy" class. (Only keep the onCommand)
    Show Spoiler
    Code:
    public class Testy implements CommandExecutor {
    
    public ArrayList<String> list = new ArrayList<String>();
    
    @Override
        public boolean onCommand(CommandSender sender, Command cmd, String label, String[] arg) {
            if(label.equals("testy")){
                if(sender instanceof Player){
                    Player player = (Player) sender;
                    if(list.contains(player.getName())){
                        player.sendMessage(">>> You've been removed.");
                        list.remove(player.getName());
                    }else{
                        player.sendMessage(">>> You've been added.");
                        list.add(player.getName());
                    }
                }
            }
    


    5. On your Main class (Inside your onEnable()), add this:
    Show Spoiler
    Code:
    Bukkit.getServer().getPluginManager().registerEvents(new Move(), this);
    getCommand("testy").setExecutor(new Testy());
    


    6. Add "Testy" as a command in your plugin.yml
    Show Spoiler
    Code:
    name: Name
    version: version
    main: main class
    description: description of pluign
    
    commands:
      testy:
        usage: /<command>
        description: description for command
    
     
  6. Offline

    Petersoj

    Okay just throwing some things out there.
    Did you add the "commands" part in to your plugin.yml?
    eg.
    Code:
    commands:
    testy:
      usage: /<command>
      description: hi
    
    Also you may not want to have public List<String> list = new ArrayList<String>();
    I did this once and for some reason it didn't work.
    Maybe try: public ArrayList<String> list = new ArrayList<String>();

    Also I usually put my "onCommand" method inside the main class so that I don't have to reference it from another class. Just a suggestion though, you don't have to do it.
     
  7. Offline

    mrgreen33gamer

    @SuperSniper I mean I changed the ArrayList to a static, but don't those cause memory leaks? Also, I'm trying to prevent the usage of static variables.

    @Petersoj Everything is registered. I'm trying to figure out how I cannot access my ArrayList...
     
  8. Offline

    mine-care

    @SuperSniper How about using instances, getters and setters, of Object Oriented Programing instead of using the static improperly?

    That isnt logic, This is called Upcasting in java, it shouldnt cause any problems at all. The only issue is that you can only use the methods of List<String> not ArrayList<String> but in this case it doesnt cause a problem.

    No. It depends on the variables stored in the list ;- )
     
  9. Offline

    Petersoj

    I don't know then... Maybe restart your IDE
    Possibly that you are not instantiating the ArrayList in the onEnable();
    I sometimes get nullPointerExceptions when I do that so maybe something like this?
    Code:
    public ArrayList<String> list;
    public void onEnable(){
       list = new ArrayList<String>;
    }
    
     
  10. Offline

    teej107

    @SuperSniper
    Oh boy.... where do I start :p

    Yes you can. Many mistakes people make from doing so is creating 2 separate instances. Only using 1 instance is fine and behaves normal.

    No. Static shouldn't be used just so you can have easy access to it. Learn about Object Oriented Programming.

    Now @mrgreen33gamer......
    Static doesn't cause memory leaks. There is much more to it than just that. If you don't know how to use static the right way, you better not use it until you understand why it is there.

    Speaking of ArrayList, Bukkit forums need to realize that the ArrayList isn't the only Collection out there. There are far better ones to serve your purpose (like a Set).
     
    Oxyorum and mine-care like this.
  11. Offline

    SuperSniper

    @teej107

    1. That was from my own experience of using Listener and CommandExecutor in the same class, I never said that it was an overall statement for everyone.

    2. You kinda got me there, I gotta admit, im not very perfect with using static and things like that, I just said it because im not very fluent with static and I don't really know any other ways to do it currently.
     
  12. Offline

    mrgreen33gamer

    @mine-care Lol. I've got some really old classes that are not define with publics, statics or finals and they work when being casted. Is it the new version of Java?

    @teej107

    I just tried

    Code:
        public Set<String> list = new HashSet<String>();
    That didn't do a thing o-o.

    EDIT: Imma head off. Sleepy time!
     
    Last edited: Sep 6, 2015
  13. Offline

    Petersoj

    Did you try my last post? I just wanna know If I helped.
     
  14. Offline

    teej107

    Yes, I was just making it clear that it is OK to implement both the CommandExecutor and Listener in the same class so the OP wouldn't have to do any more needless code than he has to.

    I knew that wouldn't fix your problem, but it was still a problem. May I see your class where you register the Listener and CommandExecutor?
    Are you sure that you are running "/<your_command> testy"? Btw, use Command#getName() rather than "label".
     
  15. Offline

    TomeDM

    @mrgreen33gamer
    Alright heres what you need to do (this will be very similar to @SuperSniper reply)
    1. Make a Main class that has a public static ArrayList in it
    ArrayList (open)

    Code:
    public class Main extends JavaPlugin
    {
        public static ArrayList<String> players = new ArrayList<String>();
    
    }

    2. Set the Listener and Executor to your other class (mine is called Tests)
    Main Class (open)

    Code:
    public class Main extends JavaPlugin
    {
        public static ArrayList<String> players = new ArrayList<String>();
    
        public void onEnable()
        {
            PluginManager pm = Bukkit.getPluginManager();
            pm.registerEvents(new Tests(), this);
            getCommand("testy").setExecutor(new Tests());
        }
    }
    

    3. In that other class you need to implement Listener and CommandExecutor
    Other Class (open)

    Code:
    public class Tests implements Listener, CommandExecutor {
    }
    

    4. Make your boolean the same as before (this is an edited version), but to get the ArrayList use Main.players OR [MainClass].[ArrayListVariable]
    Other Class (open)

    Code:
    public boolean onCommand(CommandSender player, Command cmd, String label, String[] arg) {
            if (label.equals("testy")) {
                if (player instanceof Player) {
                    if (!Main.players.contains(player.getName())) {
                        Main.players.add(player.getName());
                        player.sendMessage(ChatColor.RED + "You have been added");
                        return true;
                    } else if (Main.players.contains(player.getName())) {
                        Main.players.remove(player.getName());
                        player.sendMessage(ChatColor.RED + "You have been removed");
                        return true;
                    }
                    return true;
                }
                return true;
            }
    
            return true;
        }

    5. For the move event when i was testing it i had it send me a message to see if it changed the list,
    Change that if you wish
    MoveEvent (open)

    Code:
    @EventHandler
        public void PlayerMove(PlayerMoveEvent event)
        {
            Player player = event.getPlayer();
            if(Main.players.contains(player.getName()))
            {
                player.sendMessage("success!");
            }else if(!(Main.players.contains(player.getName())))
            {
                player.sendMessage("failed");
            }
        }


    Edits:
    - Reconstructed this reply
    - Minor Code Tweaks
     
    Last edited: Sep 6, 2015
  16. Offline

    caderape

    @mrgreen33gamer
    I guess your register your command and event in separate classes. Use the same instance for both in your onEnable. Or the list will be empty for your event, and not for your command.
     
  17. Offline

    mythbusterma

    @TomeDM

    Since when is using "public static" an excuse for laziness?

    Why does everyone keep pushing for bad practices on this forum?

    Don't use static so that you can use a class's name to access it's members, actually obtain an instance of said class and have a real getter method.

    Does encapsulation mean nothing any more?
     
    Oxyorum likes this.
  18. Offline

    RoboticPlayer

    A) The Bukkit API uses Java, not Javascript :)
    B) Please follow the Java Naming Conventions (don't name your main class "Main")
     
  19. Offline

    teej107

    And I'll give a a similar reply to the the reply I did from his post too :p
    You should practice encapsulation.

    And enough with the ArrayList! It is not what you need.

    [​IMG]
     
    mythbusterma likes this.
Thread Status:
Not open for further replies.

Share This Page