I want to create a list, add blocks to it and then use it in a BlockBreakEvent to check if the block is in the list and cancel the event if it’s not. But I can’t seem to create and add things in it any other way than in the actual event itself (which looks to me like it would create issues). The only thing that is working for me is creating the list in the event and adding blocks to it one by one which looks really messy compared to: creating the list in a separate class and just checking the list with if(Listname.contains(block)) does anyone know how I can achieve this? Whether its dependency injection, or whatever else. I just can’t figure out how to put it to use.
Here’s what I’ve tried and is currently working for me, but I believe it’s theoretically incorrect:
public class Event implements Listener { @EventHandler public void onBreak(BlockBreakEvent e) { List<Material> allowedblocks = new ArrayList<Material>(); allowedblocks.add(Material.STONE); //repeat this 10-50 times for whatever item Player p = e.getPlayer(); Material block = e.getBlock().getType(); if(allowedblocks.contains(block)){ p.sendMessage("Invalid block. Break cancelled"); e.setCancelled(true); }else{ p.sendMessage("Valid Block"); } } }
Advertisement
Answer
You can make allowedBlocks List a class field and fill it with elements inside of the constructor.
public class YourClass { private List<Material> allowedBlocks = new ArrayList<>(); public YourClass() { allowedBlocks.add(Material.STONE); //repeat this 10-50 times for whatever item } @EventHandler public void onBreak(BlockBreakEvent e) { Player p = e.getPlayer(); Material block = e.getBlock().getType(); if(allowedBlocks.contains(block)){ p.sendMessage("Valid Block"); } else { p.sendMessage("Invalid block. Break cancelled"); e.setCancelled(true); } } }
Another approach would be to make the list static and fill it with values inside of a static block. I would not recommend making the list static if you are planning to change its values, but if your allowed blocks are going to remain the same, it may be a good idea to even go further and make it public, so you can access it from anywhere without an instance of YourClass
public class YourClass { public static final List<Material> allowedBlocks; static { List<Materials> list = new ArrayList<>(); list.add(Material.STONE); //repeat this 10-50 times for whatever item //use an unmodifiable list, //so you do not accidentally change its content later allowedBlocks = Collections.unmodifiableList(list); } @EventHandler public void onBreak(BlockBreakEvent e) { Player p = e.getPlayer(); Material block = e.getBlock().getType(); if(allowedBlocks.contains(block)){ p.sendMessage("Valid Block"); } else { p.sendMessage("Invalid block. Break cancelled"); e.setCancelled(true); } } }
In the first case, there will be a list of allowedBlocks per instance of YourClass, which means, that every time you call new YourClass()
a new List will be created and filled. In the second case, there will be only one list which will be created and populated on class loading (at the very beginning of the program) start up.
P.S. I would rather use a Set instead of a List here, considering you are using contains
very often.