BKCommonLib/TabView

From BergerHealer Wiki
Jump to navigation Jump to search

« Go back

Introduction

BKCommonLib features an advanced method of changing what is shown when players press tab, previously known as the 'Player List'. With our service you can alter every cell of this list based on column and row indices. In combination, it features a name generation scheme that allows you to place the same text multiple times. Minecraft limits the text you can put to 16 characters, so we were forced to abide it. If you have the same text twice, this limit becomes 14 (due to the name generation appending two characters).

Initialization of your tab view

To use this service, first of all obtain a TabView instance while enabling your plugin. You can do this in onEnable, but doing it in the constructor or field area of your plugin class is fine too. For example:

public class MyPlugin extends JavaPlugin {
    private TabView tabView = TabView.createTab(3, 20);

    public void onEnable() {
    }

    public void onDisable() {
    }
}

Please note that it is not possible to create new tabs while the server is running. This is because BKCommonLib can not alter the shown player list dimensions of existing players, and it requires a re-login to fix. To avoid these bugs, the maximum dimensions of the tab view you need have to be specified while your plugin starts up. After loading up, you can demand player lists that are smaller than the one you create on startup, but you can not create larger ones. If you expect to be using a variable size tab list, be sure to initialize a tab view of the maximum size you expect.

The maximum width you can use is 3, the maximum height is 20. This is the same as the server enforces.

Altering your tab view

Now you have a TabView instance, what can you do with it? Well, you can set, for each cell, what text and ping icon to display in it. To do so there are many methods available to you. You can fill all cells at once, fill a single row or column, set an area or a single cell. You can also create sub-views into your TabView so you can send it to a method and alter it there, with bounds checking. Look into the JavaDoc and you'll be amazed at the possibilities.

Displaying your tab view

Updates for changes made in the tab are automatically sent to all viewers at the end of each server tick, so no worries of having to update manually each tick. To display your Tab View to a player, or to all players, use the displayTo and displayToAll methods. In the case of displayToAll, all players that join the server will automatically see your Tab View as well. If you want to see whether a Tab View is shown to a Player (for example, to provide a toggle), you can use the isDisplayedTo method.

What happens when two plugins try to display a tab? Well, the previous tab will be hidden and the new tab will be shown. Please, do not abuse this by forcing a display each tick. It is up to the users to decide what they want to see, so provide a command toggle! Don't automate or schedule the display of tabs, it will only cause annoyance by the users.

Displaying the default player list again

If you want to display the default player list again, or an empty list, use the TabView.DEFAULT or TabView.EMPTY constants. By calling TabView.DEFAULT.displayToAll() everyone sees the (auto-updated) player list again.

But I want both!

Adding automatic player name and ping updates to custom tabs would create a confusing API, so if you wish to show player names behind, around or after your own Tab View, it is best if you do this yourself. You can use a tick task to set all text and ping values in your custom tab view. No changes are sent if the name didn't change, so it won't cause lag. Updating the text or ping of a cell is pretty much instant, there is no heavy operation involved.

What if I want to show a different view per player?

You can do so by cloning the TabView instance created on startup. For example:

TabView myView = this.tabView.clone();
myView.set(0, 0, player.getName(), TabView.PING_NONE);
myView.displayTo(player);

If you want different (smaller!) sizes, you can use cloneResize(width, height).

Example

Below is an example code for displaying the player names, experience and their time lived in a table. A maximum of 17 players is supported. For initialization the example initialization code above was used. This code can be put anywhere, in this case it was put in a command handler. You can also place it in the enable logic of the plugin, but be aware that other plugins that do the same could cause conflicts then. It's best to allow users to toggle your Tab View on or off.

// Show header at line 1, 2 and 3
tabView.fillRow(0, "==============", TabView.PING_1);
tabView.fillRow(1, TabView.TEXT_NONE, TabView.PING_NONE);
tabView.setRowText(1, "Players", "Experience", "Time Alive");
tabView.fillRow(2, "==============", TabView.PING_1);
// Show scores
int line = 3;
for (Player player : Bukkit.getOnlinePlayers()) {
	tabView.set(0, line, player.getPlayerListName(), TabView.PING_FULL);
	tabView.set(1, line, "" + player.getTotalExperience(), TabView.PING_FULL);
	tabView.set(2, line, "" + (player.getTicksLived() / 20) + "s", TabView.PING_FULL);
	line++;
	// Out of bounds!
	if (line >= tabView.getHeight()) {
		break;
	}
}
// Display to everyone
tabView.displayToAll();

This creates the resulting image: TabView example result

Conflicting plugins

If there is another plugin that alters the player list view, it might not get to do what it wants to do since BKCommonLib blocks it when a custom TabView is being shown. When the DEFAULT TabView is shown, other plugins can safely send their messages, since BKCommonLib then allows these messages to go through. When DEFAULT is not shown, BKCommonLib will keep track of these discarded messages and send them again when DEFAULT is shown again.

So, if your plugin shows a custom TabView, it is best to allow players to toggle this off by showing the DEFAULT tab view. Any other plugin that was trying to show something will get a chance to do so then.

Some tips and tricks

  • To wipe everything previously shown, use fillAll("", 0)
  • To quickly set everything, use setArea/Column/RowText
  • You can clone an entire view using clone()
  • You can get a newly sized TabView by using cloneResize(newWidth, newHeight)
  • There are many TabView.PING_X constants to display certain ping icons
  • You do not have to limit the displayed text by 16, this is done for you