Solved Accessing Config File inside a GUI

Discussion in 'Spigot Plugin Development' started by aws404, Mar 8, 2018.

  1. Hi, I would like to start by saying I am quite new to Java so there might be an obvious mistake I am making but that's why i'm here, for help!
    So I am trying to make a GUI that takes values from a config file in place of the name, lore and other values, I continue to get a null pointer exception during the enable of the plugin and wondered if anyone could tell me what i'm doing wrong. It only occurs when I try to access the Config file and works fine if i just use normal values.

    Inventory Class:
    Code (Text):
    package aws404.capitalskyblock.challenges;

    import java.util.Arrays;

    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.Material;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.inventory.InventoryClickEvent;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.meta.ItemMeta;

    public class Inventory implements Listener {
        private Main plugin;
        public Inventory(Main plugin) {
            this.plugin = plugin;

        public static void createButton(int Slot, String name, org.bukkit.inventory.Inventory inv) {
            ItemStack item = new ItemStack(Material.STICK);
            ItemMeta meta = item.getItemMeta();
            meta.setDisplayName(ChatColor.GOLD + "" + ChatColor.BOLD + FileManager.config.getString("challenges." + name + ".display"));
            meta.setLore(Arrays.asList(ChatColor.WHITE + FileManager.config.getString("challenges." + name + ".desc") ,ChatColor.GRAY +  "test", "", ChatColor.GOLD + "Rewards:",ChatColor.GRAY + FileManager.config.getString("challenges." + name + ".rewards")));
            inv.setItem(Slot, item);
    //Main Menu
        public static org.bukkit.inventory.Inventory challenges = Bukkit.getServer().createInventory(null, 9, ChatColor.GOLD + "" + ChatColor.BOLD + "Capital" + ChatColor.WHITE + ChatColor.BOLD + "Challenges");

        static {
            createButton(0, "walkingstick", challenges);
            //Click Actions
            public void click(InventoryClickEvent e) {
                Player p = (Player) e.getWhoClicked();
                ItemStack clicked = e.getCurrentItem();
                org.bukkit.inventory.Inventory inv = e.getInventory();

                if (inv.getName().equals(challenges.getName())) {
                    p.sendMessage("GUI Clicked");
    FileManager Class:
    Code (Text):
    package aws404.capitalskyblock.challenges;


    import org.bukkit.configuration.file.YamlConfiguration;

    public class FileManager {

        public static YamlConfiguration config;
        private static File configFile;
        static Main plugin;
        public FileManager(Main pluginX) {
        plugin = pluginX;
        configFile = new File(plugin.getDataFolder(), "config.yml"); //The file (you can name it what you want)
        config = YamlConfiguration.loadConfiguration(configFile); //Take the file and basically turning it into a .yml file
        try {
        } catch (IOException e) {
    And the config.yml:
    Code (Text):
        display: Walking Sticks
        type: hand
        material: STICK
        name: Grandpas Walking Stick
        desc: Use the Enhanced Crafting Table to create Grandpas Walking Stick.
        rewards: 20x Sticks
        display: Crafting Table
        type: block
        material: WORKBENCH
        name: i
        desc: Create a crafting table
        rewards: 20x Logs
    Thanks in advance!
  2. The problem is that your GUI is created whenever that class is initialized by the class loader since the createButton method is called in a static block. Your config field on the other hand is only initialized whenever you create your FileManager, which is after the class loader initializes your GUI class, thus the field is at that time null.

    To solve this you could make it so your GUI class doesn't do stuff in static blocks, since it's completely unnecessary. Instead just call stuff like createButton in the constructor. If you do that you have better control over what will be executed when, since you are the one calling it, not the JVM. Aside there is no reason to make that stuff static anyways, so that should be a good solution.
    You could of course, also put your config stuff in a static block. However this will lead to multiple problems since you don't know which class will be initialized first. This completely depends on when stuff is needed and when you edit something in another file that may cause the classes the load in a different order, causing the same error again.

    So I'd recommend just doing what I said in the first solution: don't make your GUI class static when not needed and call your constructors in the correct order.
  3. for strings in your config.yml you should surround them with '.


    Code (Text):
        display: 'Walking Sticks'
        type: 'hand'
        material: STICK
        name: 'Grandpas Walking Stick'
        desc: 'Use the Enhanced Crafting Table to create Grandpas Walking Stick.'
        rewards: '20x Sticks'
  4. Note that this is only the case when using a reserved character in the scalar (YAML specification section 5.3, example 5.10).
  5. Thanks alot! That worked for me.

Share This Page