Interactive Books

May 12, 2015
Interactive Books
  • Interactive Books

    How to create a book with click and hover events



    This is how you can create a book with click and hover events.


    Creating the Book(top)

    To begin with, we will need to obtain the BookMeta from a ItemStack. Only an ItemStack with Material.BOOK_AND_QUILL or Material.WRITTEN_BOOK have this.
    Code (Java):
    ItemStack book = new ItemStack(Material.WRITTEN_BOOK);
    BookMeta bookMeta = (BookMeta) book.getItemMeta();

    Getting the Pages(top)

    BookMeta is the Bukkit interface for the CraftMetaBook object in CraftBukkit. As of when this guide was written, the BookMeta interface does not have a method to obtain the pages as a list of IChatBaseComponent objects (which is what is stored in CraftMetaBook). This means we will have to get the pages using reflection. Here is an example of how you can do that.
    Code (Java):
    List<IChatBaseComponent> pages = (List<IChatBaseComponent>) CraftMetaBook.class.getDeclaredField("pages").get(bookMeta);
    Any changes we make to this list will update the book and so there is no need to set the field back after we are done with it.


    Creating a Page With Click/Hover Events(top)

    Using the BungeeCord chat component API (which is included in the spigot server jar) you can produce an IChatBaseComponent which contains click and hover events.
    Alternatively you could generate your own jsonString which will enable you to use book specific events.
    Code (Java):
    BaseComponent text; //this is the base component we will be turning into a page

    //convert the base component into a json string
    String pageJson = ComponentSerializer.toString(text);

    //get an IChatBaseComponent object which represents this json string
    IChatBaseComponent page = IChatBaseComponent.ChatSerializer.a(pageJson);

    //add this page to the pages list
    pages.add(page);

    Finish Creating the ItemStack(top)

    Once you've finished adding the pages, don't forget to add this new BookMeta to the original ItemStack! You can also set a title and an author for the book.
    Code (Java):
    bookMeta.setTitle("Interactive Book");
    bookMeta.setAuthor("gigosaurus");

    book.setItemMeta(bookMeta);

    An Example Book(top)

    Code (Java):
    //create the book
    ItemStack book = new ItemStack(Material.WRITTEN_BOOK);
    BookMeta bookMeta = (BookMeta) book.getItemMeta();
    List<IChatBaseComponent> pages;

    //get the pages
    try {
        pages = (List<IChatBaseComponent>) CraftMetaBook.class.getDeclaredField("pages").get(bookMeta);
    } catch (ReflectiveOperationException ex) {
        ex.printStackTrace();
        return;
    }

    //create a page
    TextComponent text = new TextComponent("Click me");
    text.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "http://spigotmc.org"));
    text.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder("Goto the spigot website!").create()));

    //add the page to the list of pages
    IChatBaseComponent page = ChatSerializer.a(ComponentSerializer.toString(text));
    pages.add(page);

    //set the title and author of this book
    bookMeta.setTitle("Interactive Book");
    bookMeta.setAuthor("gigosaurus");

    //update the ItemStack with this new meta
    book.setItemMeta(bookMeta);
  • Loading...
  • Loading...