• 欢迎来到Minecraft插件百科!
  • 对百科编辑一脸懵逼?帮助:快速入门带您快速熟悉百科编辑!
  • 因近日遭受攻击,百科现已限制编辑,有意编辑请加入插件百科企鹅群:223812289

“Event API Reference”的版本间的差异

来自Minecraft插件百科
跳转至: 导航搜索
在实现监听器接口的插件中注册事件监听器
 
(未显示9个用户的20个中间版本)
第1行: 第1行:
 +
[[Event API Reference/en|点击此处浏览原文]]
 
{{待翻译}}
 
{{待翻译}}
 
== 介绍 ==
 
== 介绍 ==
  
'''Events''' are how the CraftBukkit server tells your plugin that something has happened in the world.  Bukkit defines many events, in multiple categories; e.g. player actions (player logged in, player clicked a block, player died, player respawned...), block events (block placed, block broken, block's neighbour changed...), entity events (a mob targeted you, a creeper exploded...), world-wide events (a world loaded or unloaded, a chunk loaded or unloaded), and many more. Due to unknown reasons there is no longer any links to official Javadocs as they have all been taken off line.
+
服务器里发生的事情,服务器会用'''事件''' 来告诉你。 '''Bukkit'''中有各种各样的事件,例如 玩家的互动(玩家登录, 玩家点击了一个方块, 玩家死了,玩家重生...), 方块的动态(方块被放置, 方块被破坏, 方块附近的实体被改变...), 实体事件(一个怪物看上了你, 一个苦力怕帮你收集土方块...), 世界事件 (一个世界被加载或卸载, 一个区块被加载或卸载)等等. 由于MC官方的一些原因,他们的JavaDocs都挂了= =
'''事件''',就是CraftBukkit服务器告诉插件,这个世界发生了什么的一种方式。Bukkit定义了许多种类的不同事件;例如:玩家行为(玩家登入、玩家点击某个方块、玩家死亡、玩家重生...)、方块事件(方块被放置、方块被扣掉、相邻方块发生变化...)、实体事件(有东西瞄准了你、苦力怕爆炸...)、世界元事件(世界载入或卸载、区块载入或卸载...)、等等其它的分类。Due to unknown reasons there is no longer any links to official Javadocs as they have all been taken off line.
 
 
 
  
 
== 基础 ==
 
== 基础 ==
To keep this section simple, we're going to only work with PlayerLoginEvent. Lets start with setting up the method
+
为了保持简单易懂,这一节只讨论一种事件——PlayerLoginEnvent(玩家登录事件)。让我们从创建一个监听器开始吧。
为了保持简单易懂,这一节只讨论一种事件——PlayerLoginEnvent。让我们从创建一个监听/处理该事件的方法开始吧。
 
  
 
=== 创建方法 ===
 
=== 创建方法 ===
In order for your plugin to handle an event call, you need to create a method for it:
+
为了让你的插件能够监听并处理该事件的回调,你需要为它创建一个方法,这个方法就是事件'''监听器'''。
为了让你的插件能够监听并处理该事件的回调,你需要为它创建一个方法。
 
 
<source lang="java">@EventHandler
 
<source lang="java">@EventHandler
 
public void onLogin(PlayerLoginEvent event) {
 
public void onLogin(PlayerLoginEvent event) {
 
     // 你自己的代码...
 
     // 你自己的代码...
 
}</source>
 
}</source>
Before this method can be invoked by Bukkit when the "PlayerLoginEvent" is fired, we need to annotate it. We do this with EventHandlers.
+
你需要向Bukkit注册你的监听器,这样服务器才会在"PlayerLoginEvent"触发时调用该监听器。我们需要给监听器打上 @EventHandler 批注。
你还需要向Bukkit声明一下,这样服务器才会在"PlayerLoginEvent"触发时调用该函数。我们需要用到EventHandlers来做到这一点。
 
  
 
=== @EventHandler ===
 
=== @EventHandler ===
The "@EventHandler" class is an Annotation, which goes just above your method. It looks like this:
+
"@EventHandler" 是一个能打在某个方法上的批注,就像这样:
“@EventHandler”类是一个Annotation,一般就放在你的方法上面。就像这样:
+
<source lang="java">@EventHandler // 优先级 默认为NORMAL级</source>
<source lang="java">@EventHandler // EventPriority(事件优先级)默认为NORMAL</source>
+
这样一来,这所对应的方法就成为了一个 优先级 为NORMAL的监听器。
This marks your method as an EventHandler with the EventPriority as NORMAL.
 
这样一来,这一方法就标记为了一个EventPriority(事件优先级)为NORMAL的EventHandler(事件监听/处理器)。
 
  
The EventHandler can take an EventPriority to specify the priority of the method, like so:
+
你可以设置EventHandler标签的EventPriority属性来自定义事件的优先级,例如:
EventHandler可以通过EventPriority来自定义事件的优先级,例如:
+
<source lang="java">@EventHandler(priority = EventPriority.HIGHEST) // 将优先级设为HIGHEST级
<source lang="java">@EventHandler(priority = EventPriority.HIGHEST) // 方法优先级设为最高
+
@EventHandler(priority = EventPriority.LOW) // 优先级设为LOW级</source>
@EventHandler(priority = EventPriority.LOW) // 方法优先级设为低</source>
 
  
Here's what it would look like in your class:
+
你的监听器应该看上去像是这样:
你的回调函数看起来应该和下面这个相类似:
 
 
<source lang="java">@EventHandler
 
<source lang="java">@EventHandler
 
public void onLogin(PlayerLoginEvent event) {
 
public void onLogin(PlayerLoginEvent event) {
第40行: 第32行:
  
 
=== 添加监听器 ===
 
=== 添加监听器 ===
In order for Bukkit to be able to register your EventHandler's, the class which contains your event handling methods must implement  the ''Listener'' (org.bukkit.event.Listener) interface, e.g.:
+
为了让Bukkit能够注册你的监听器,你需要给你的监听器所在的类实现Listener接口(org.bukkit.event.Listener)。例如这样:
  
 
<source lang="java">public final class MyPlayerListener implements Listener {
 
<source lang="java">public final class MyPlayerListener implements Listener {
第48行: 第40行:
 
     }
 
     }
 
} </source>
 
} </source>
 
+
监听器的方法名(例子中是“onlogin”的东西)并不重要;只要符合命名规则,起什么名字,你开心就好。
The name of the method (''onLogin'' in the above example) does not matter;  you may call the method anything you like inside your listener.
+
你可能想知道:“Bukkit怎么知道监听那个事件呢?”。Bukkit是通过上面例子中你定义的“PlayerLoginEvent”这个参数知道的。
 
+
{{warning|一个监听器只能监听一个事件,否则Bukkit是不会注册它的!}}
You may be wondering.. "How does Bukkit know which event to listen to?" It knows that by the event parameter you specify in the method's signature - in the above example: <code>PlayerLoginEvent</code>.
+
你的插件的主类 (就是继承JavaPlugin的那个类) 也可以成为一个事件监听器。在你的插件非常小的时候,这样就很方便了。比如:
 
 
{{Note|You ''must'' specify a single specific event or Bukkit will not be able to register it}}
 
 
 
Your main plugin class (i.e. the class which extends JavaPlugin) can also be an event listener, and this might make sense if your plugin is very small.  E.g.:
 
 
<source lang="java">
 
<source lang="java">
 
public class MyPlugin extends JavaPlugin implements Listener {
 
public class MyPlugin extends JavaPlugin implements Listener {
第69行: 第57行:
 
}
 
}
 
</source>
 
</source>
=== EventHandler Parameters ===
+
 
The @EventHandler annotation can take parameters to further define how the event handler behaves. At the moment you can specify:
+
=== EventHandler的参数 ===
 +
@EventHandler 批注可以设置某些参数来改变监听器的某些作用等。在某些情况下,你可以设置这些参数:
  
 
{| class="wikitable" cellspacing="0" cellpadding="5" border="1"
 
{| class="wikitable" cellspacing="0" cellpadding="5" border="1"
 
|-
 
|-
! Name
+
! 名称
! Type
+
! 类型
! Default
+
! 默认值
! Description
+
! 描述
! Values
+
!
  
 
|-
 
|-
第84行: 第73行:
 
| EventPriority
 
| EventPriority
 
| EventPriority.NORMAL
 
| EventPriority.NORMAL
| Sets the priority of your method
+
| 设置监听器优先级
 
|
 
|
 
* EventPriority.MONITOR
 
* EventPriority.MONITOR
第97行: 第86行:
 
| boolean
 
| boolean
 
| false
 
| false
| If set to true, your method will not get the event if the event has been cancelled
+
| 如果设为true,在事件被其他监听器关闭的时候,你的监听器将监听不到这个事件
 
|  
 
|  
 
* true
 
* true
第105行: 第94行:
  
  
==== Event Priorities ====
+
==== 事件优先级 ====
There are six priorities in Bukkit that are called in the following order
+
Bukkit中的监听器拥有六个优先级
 
* EventPriority.LOWEST
 
* EventPriority.LOWEST
 
* EventPriority.LOW
 
* EventPriority.LOW
第114行: 第103行:
 
* EventPriority.MONITOR
 
* EventPriority.MONITOR
  
Every plugin gets a say in what happens, and every plugin must get a chance to know the outcome of an event. So, we pass events to plugins even after they've been cancelled. A plugin can actually uncancel an event after another plugin cancelled it. This is where priorities become really important.
+
每个插件可能会在一个事件触发时做出不同的相应,并且有的插件可能想更快的知道一个事件的发生。并且,有时候Bukkit传递事件给每个插件的时候,甚至这个事件已经被其他插件关闭了。某些情况下,其他插件刚把这个事件关掉,另外一个插件监听到了以后又把这个事件开开了。这样乱七八糟的冲突发生了以后,这就很尴尬了。
  
Let's say a BLOCK_PLACE event is being handled. The lowest priority listener is called to get its say in whether it should be cancelled or not. Then the low priority listener is called to see if it wants to override the lowest, etc. Eventually it hits monitor, and at this point nothing should change the outcome of the event. Monitor should be used to see the outcome of an event, without changing any aspect of it.
+
比如 方块放置 被触发了,LOWEST优先级的监听器将会最先对这个事件做出决定,比如关闭它什么的。然后LOW优先级的监听器将会被触发,这时候可以重写LOWEST级监听器刚刚做出的修改,以此类推。Eventually it hits monitor, and at this point nothing should change the outcome of the event. MONITOR级的监听器 should be used to see the outcome of an event, without changing any aspect of it.
 
If we have three plugins enabled; one is a basic area protection plugin, one is a fancy plugin using signs, and another is a logging plugin.
 
If we have three plugins enabled; one is a basic area protection plugin, one is a fancy plugin using signs, and another is a logging plugin.
 
The protection plugin listens on Priority.LOWEST. It says they can't place blocks in this area, and cancels the event.
 
The protection plugin listens on Priority.LOWEST. It says they can't place blocks in this area, and cancels the event.
第125行: 第114行:
 
If you want to act when an event happens, but not change the outcome, use MONITOR. '''It's really really important that you use MONITOR, or an event might get cancelled after you've acted on it, and it's even more important that you don't change the outcome of the event on MONITOR or it'll break other plugins.'''
 
If you want to act when an event happens, but not change the outcome, use MONITOR. '''It's really really important that you use MONITOR, or an event might get cancelled after you've acted on it, and it's even more important that you don't change the outcome of the event on MONITOR or it'll break other plugins.'''
  
== Registering Events ==
+
'''中文简单解释'''
To register your methods, the class containing the EventHandler(s) must implement the Listener class.
+
 
 +
优先级越高的方法越早调用
 +
 
 +
优先级再高(除了MONITOR) setCanceled() 方法也不能阻止其它插件监听到它
 +
 
 +
在MONITOR上搞 setCanceled(false) 其它插件会给你玩死~
 +
 
 +
== 注册事件(监听器) ==
 +
要注册你的方法,包含EventHandler的类必须是implent了Listener类的
 
<blockquote><source lang="java">import org.bukkit.event.Listener;
 
<blockquote><source lang="java">import org.bukkit.event.Listener;
  
 
public final class LoginListener implements Listener {
 
public final class LoginListener implements Listener {
 
}</source></blockquote>
 
}</source></blockquote>
 
+
你只需要提供一个插件和一个监听器来在PluginManager里注册它们
You only need to provide a plugin and a listener to register them in the PluginManager.
 
 
<blockquote><source lang="java">getServer().getPluginManager().registerEvents(Listener, Plugin);</source></blockquote>
 
<blockquote><source lang="java">getServer().getPluginManager().registerEvents(Listener, Plugin);</source></blockquote>
  
=== Example Listener ===
+
=== 监听器示例 ===
This listener contains two EventHandlers. One listening on HIGH, and one on NORMAL.
+
这个监听器包含两个EventHandlers,一个监听级别是HIGH并且另一个是NORMAL。
 
<blockquote><source lang="java">import org.bukkit.event.Listener;
 
<blockquote><source lang="java">import org.bukkit.event.Listener;
 
import org.bukkit.event.EventHandler;
 
import org.bukkit.event.EventHandler;
第154行: 第150行:
 
}</source></blockquote>
 
}</source></blockquote>
  
=== Registering Events in Plugin ===
+
=== 在插件中注册事件监听器 ===
 +
注册事件需要监听器和对应插件,幸运的是,我们拥有属于我们自己的登陆监听器,现在我们来写一个登陆插件吧
 
The registerEvents method requires a listener and a plugin. Luckily, we already have our LoginListener. Now for the LoginPlugin!
 
The registerEvents method requires a listener and a plugin. Luckily, we already have our LoginListener. Now for the LoginPlugin!
 
<blockquote><source lang="java">import org.bukkit.plugin.java.JavaPlugin;
 
<blockquote><source lang="java">import org.bukkit.plugin.java.JavaPlugin;
第165行: 第162行:
  
  
==== Registering Events with Plugin as Listener ====
+
==== 在实现监听器接口的插件中注册事件监听器 ====
You could even have the events in the main class, for example:
+
<ref>准确来说是在实现了监听器接口的继承了JavaPlugin的类中注册事件(笑</ref>
 +
你甚至可以在主类中创建监听器,像这样:
 
<blockquote><source lang="java">import org.bukkit.plugin.java.JavaPlugin;
 
<blockquote><source lang="java">import org.bukkit.plugin.java.JavaPlugin;
 
import org.bukkit.event.Listener;
 
import org.bukkit.event.Listener;
第183行: 第181行:
 
}</source></blockquote>
 
}</source></blockquote>
  
=== Registering Events in your Listener ===
+
=== 在监听器中注册事件监听器 ===
 
There are many ways to register your events. Here's an example where you register them in your listener class.
 
There are many ways to register your events. Here's an example where you register them in your listener class.
 
<blockquote><source lang="java">import org.bukkit.event.Listener;
 
<blockquote><source lang="java">import org.bukkit.event.Listener;
第215行: 第213行:
 
}</source></blockquote>
 
}</source></blockquote>
  
== Un-registering events or listeners ==
+
== 在监听器中注销事件监听器 ==
You can un-register individual events, entire listener classes or all events registered by your plugin or even by other plugins!
+
你可以自己取消个人事件,整个注册侦听器类或所有事件由你的插件或者其他插件!
  
==== Un-register specific event ====
+
==== 注销特定的事件监听器 ====
Each event class has the getHandlerList() static method, call that and then you can use .unregister() method.
+
每个事件类getHandlerList()静态方法,调用,然后你可以使用.unregister()方法。例子:
Example:
 
 
<blockquote><source lang="java">
 
<blockquote><source lang="java">
 
PlayerInteractEvent.getHandlerList().unregister(plugin);
 
PlayerInteractEvent.getHandlerList().unregister(plugin);
第228行: 第225行:
 
Now you know why you'll need the getHandlerList() in your custom events.
 
Now you know why you'll need the getHandlerList() in your custom events.
  
==== Un-register all events ====
+
==== 注销所有事件监听器 ====
 
Using the HandlerList class and its unregisterAll() static method you can easily unregister events from listener classes or plugins.
 
Using the HandlerList class and its unregisterAll() static method you can easily unregister events from listener classes or plugins.
 
Example:
 
Example:
第237行: 第234行:
 
</source></blockquote>
 
</source></blockquote>
  
== Creating Custom Events ==
+
== 创建自定义事件 ==
Creating custom events is very simple, you can use the same system that Bukkit uses without ruining performance.
+
创建一个自定义事件是非常简单的,你可以使用跟Bukkit用的一样的系统,而不需要担心服务器性能的问题。
  
There are two (2) things to keep in mind when you create a Custom Event. They are "extend Event" and "static handlers." With static handlers, you must input the following code into your custom event:
+
在你创建一个自定义事件的时候,有两个东西你要记住——"继承 Event " "静态的 handlers" 。你必须像下面这样写来做静态的handlers:
  
 
<blockquote><source lang="java">private static final HandlerList handlers = new HandlerList();
 
<blockquote><source lang="java">private static final HandlerList handlers = new HandlerList();
第251行: 第248行:
 
     return handlers;
 
     return handlers;
 
}</source></blockquote>
 
}</source></blockquote>
This block of code makes the EventHandlers contained inside your own event, keeping any unrelated events completely separated.
+
这块代码可以让 EventHandlers 更方便的操作事件,使无关的事件完全的分开。
  
=== Custom Event Example ===
+
=== 自定义事件示例 ===
The following example shows how easy it is to create your own "CustomEvent."
+
下面的这个例子向你展示如何简单地创建一个你自己的事件——“CustomEvent事件”。
 
<blockquote><source lang="java">import org.bukkit.event.Event;
 
<blockquote><source lang="java">import org.bukkit.event.Event;
 
import org.bukkit.event.HandlerList;
 
import org.bukkit.event.HandlerList;
第279行: 第276行:
 
}</source></blockquote>
 
}</source></blockquote>
  
==== Calling your Custom Event ====
+
==== 调用你的自定义事件 ====
You are in control of creating and calling your events, where you call it is completely up to you. Here's an example
+
你可以自由地创建并触发事件,也可以自由地选择在何处触发。以下是一个例子:
<blockquote><source lang="java">// Create the event here
+
<blockquote><source lang="java">// 创建一个自定义事件对象
 
CustomEvent event = new CustomEvent("Sample Message");
 
CustomEvent event = new CustomEvent("Sample Message");
// Call the event
+
// 触发事件(创建好自定义事件对象,要使用本语句触发事件,否则什么都不会发生)
 
Bukkit.getServer().getPluginManager().callEvent(event);
 
Bukkit.getServer().getPluginManager().callEvent(event);
// Now you do the event
+
// 然后继续操作事件
 
Bukkit.getServer().broadcastMessage(event.getMessage());</source></blockquote>
 
Bukkit.getServer().broadcastMessage(event.getMessage());</source></blockquote>
  
Remember: You are in control of your events. If you don't call it, and act upon it, it doesn't happen!
+
请你记住!你正在控制你的自定义事件的对象。如果你不触发它,那就啥都不会发生。
  
==== Listening to a Custom Event ====
+
==== 监听一个自定义事件 ====
How do you listen to a custom event you say? Simple, the same way as listening to a normal event!
+
如何监听一个自定义事件呢?简单!就像监听Bukkit其他普通的事件是一样的!
 
<blockquote><source lang="java">import org.bukkit.event.Listener;
 
<blockquote><source lang="java">import org.bukkit.event.Listener;
 
import org.bukkit.event.EventHandler;
 
import org.bukkit.event.EventHandler;
第298行: 第295行:
 
     @EventHandler
 
     @EventHandler
 
     public void normalLogin(CustomEvent event) {
 
     public void normalLogin(CustomEvent event) {
         // Some code here
+
         // 你的代码
 
     }
 
     }
 
}</source></blockquote>
 
}</source></blockquote>
  
==== Making your CustomEvent Cancellable ====
+
==== 使得你的自定义事件具有可撤销性 ====
If you ever want to make your event cancellable, remember one thing: "implements Cancellable." Just like you would import Listener. It's really that simple, let me show you an example!
+
如果你想让你的自定义事件可以被撤销,记得,要“继承Cancellable类”。就像你继承Listener那样。这十分简单,让我向你展示一个例子!
 
<blockquote><source lang="java">import org.bukkit.event.Event;
 
<blockquote><source lang="java">import org.bukkit.event.Event;
 
import org.bukkit.event.HandlerList;
 
import org.bukkit.event.HandlerList;
第338行: 第335行:
 
}</source></blockquote>
 
}</source></blockquote>
  
Afterwards, you would check if a plugin had cancelled the event in your code, before processing normally
+
之后,你需要在你执行相应代码前,检查一下是否有插件把你的事件撤销掉了。
<blockquote><source lang="java">// Create the event here
+
<blockquote><source lang="java">// 创建一个事件对象
 
CustomEvent event = new CustomEvent("Sample Message");
 
CustomEvent event = new CustomEvent("Sample Message");
// Call the event
+
// 触发事件
 
Bukkit.getServer().getPluginManager().callEvent(event);
 
Bukkit.getServer().getPluginManager().callEvent(event);
// Check if the event is not cancelled
+
// 检查一下是否事件被撤销
 
if (!event.isCancelled()) {
 
if (!event.isCancelled()) {
     // Now you do the event
+
     // 现在在这里做些什么吧!
 
     Bukkit.getServer().broadcastMessage(event.getMessage());
 
     Bukkit.getServer().broadcastMessage(event.getMessage());
 
}</source></blockquote>
 
}</source></blockquote>
  
== Video Tutorial ==
+
== 视频教程 ==
 
If you would prefer to watch a video tutorial version of this, please click [http://www.youtube.com/watch?v=PWQNsqwD-AY here].
 
If you would prefer to watch a video tutorial version of this, please click [http://www.youtube.com/watch?v=PWQNsqwD-AY here].
 
+
<references />
 
[[Category: Tutorials]]
 
[[Category: Tutorials]]

2018年7月24日 (二) 14:49的最新版本

点击此处浏览原文

Icon-info.png
本页面已存在其他语言的内容,请协助翻译为本地化的中文。
  • 点击此处开始翻译。
  • 如本模板出现在原文存档页面,请注意更新主页面后,仍需要去除此处该模板。
  • 如当前页面已经没有需要翻译的内容,请删去待翻译模板。
  • 有标题的大篇幅文章,如果短时间内无法全部翻译,请先把所有的标题翻译出来,以便之后的贡献者选择与翻译章节内容。

介绍

服务器里发生的事情,服务器会用事件 来告诉你。 Bukkit中有各种各样的事件,例如 玩家的互动(玩家登录, 玩家点击了一个方块, 玩家死了,玩家重生...), 方块的动态(方块被放置, 方块被破坏, 方块附近的实体被改变...), 实体事件(一个怪物看上了你, 一个苦力怕帮你收集土方块...), 世界事件 (一个世界被加载或卸载, 一个区块被加载或卸载)等等. 由于MC官方的一些原因,他们的JavaDocs都挂了= =

基础

为了保持简单易懂,这一节只讨论一种事件——PlayerLoginEnvent(玩家登录事件)。让我们从创建一个监听器开始吧。

创建方法

为了让你的插件能够监听并处理该事件的回调,你需要为它创建一个方法,这个方法就是事件监听器

@EventHandler
public void onLogin(PlayerLoginEvent event) {
    // 你自己的代码...
}

你需要向Bukkit注册你的监听器,这样服务器才会在"PlayerLoginEvent"触发时调用该监听器。我们需要给监听器打上 @EventHandler 批注。

@EventHandler

"@EventHandler" 是一个能打在某个方法上的批注,就像这样:

@EventHandler // 优先级 默认为NORMAL级

这样一来,这所对应的方法就成为了一个 优先级 为NORMAL的监听器。

你可以设置EventHandler标签的EventPriority属性来自定义事件的优先级,例如:

@EventHandler(priority = EventPriority.HIGHEST) // 将优先级设为HIGHEST级
@EventHandler(priority = EventPriority.LOW) // 优先级设为LOW级

你的监听器应该看上去像是这样:

@EventHandler
public void onLogin(PlayerLoginEvent event) {
    // 你自己的代码...
}

添加监听器

为了让Bukkit能够注册你的监听器,你需要给你的监听器所在的类实现Listener接口(org.bukkit.event.Listener)。例如这样:

public final class MyPlayerListener implements Listener {
    @EventHandler
    public void onLogin(PlayerLoginEvent event) {
        // Your code here...
    }
}

监听器的方法名(例子中是“onlogin”的东西)并不重要;只要符合命名规则,起什么名字,你开心就好。 你可能想知道:“Bukkit怎么知道监听那个事件呢?”。Bukkit是通过上面例子中你定义的“PlayerLoginEvent”这个参数知道的。 Warning.png 一个监听器只能监听一个事件,否则Bukkit是不会注册它的! 你的插件的主类 (就是继承JavaPlugin的那个类) 也可以成为一个事件监听器。在你的插件非常小的时候,这样就很方便了。比如:

public class MyPlugin extends JavaPlugin implements Listener {
  @Override
  public void onEnable() {
    getServer().getPluginManager().registerEvents(this, this);
  }

  @EventHandler
  public void onLogin(PlayerLoginEvent event) {
    getLogger().log(Level.INFO, "Player " + event.getPlayer().getName() + " is logging in!");
  }
}

EventHandler的参数

@EventHandler 批注可以设置某些参数来改变监听器的某些作用等。在某些情况下,你可以设置这些参数:

名称 类型 默认值 描述
priority EventPriority EventPriority.NORMAL 设置监听器优先级
  • EventPriority.MONITOR
  • EventPriority.HIGHEST
  • EventPriority.HIGH
  • EventPriority.NORMAL
  • EventPriority.LOW
  • EventPriority.LOWEST
ignoreCancelled boolean false 如果设为true,在事件被其他监听器关闭的时候,你的监听器将监听不到这个事件
  • true
  • false


事件优先级

Bukkit中的监听器拥有六个优先级

  • EventPriority.LOWEST
  • EventPriority.LOW
  • EventPriority.NORMAL
  • EventPriority.HIGH
  • EventPriority.HIGHEST
  • EventPriority.MONITOR

每个插件可能会在一个事件触发时做出不同的相应,并且有的插件可能想更快的知道一个事件的发生。并且,有时候Bukkit传递事件给每个插件的时候,甚至这个事件已经被其他插件关闭了。某些情况下,其他插件刚把这个事件关掉,另外一个插件监听到了以后又把这个事件开开了。这样乱七八糟的冲突发生了以后,这就很尴尬了。

比如 方块放置 被触发了,LOWEST优先级的监听器将会最先对这个事件做出决定,比如关闭它什么的。然后LOW优先级的监听器将会被触发,这时候可以重写LOWEST级监听器刚刚做出的修改,以此类推。Eventually it hits monitor, and at this point nothing should change the outcome of the event. MONITOR级的监听器 should be used to see the outcome of an event, without changing any aspect of it. If we have three plugins enabled; one is a basic area protection plugin, one is a fancy plugin using signs, and another is a logging plugin. The protection plugin listens on Priority.LOWEST. It says they can't place blocks in this area, and cancels the event. The fancy sign plugin listens on Priority.NORMAL. It says they can place signs here, and uncancels the event. The log plugin listens on Priority.MONITOR. It sees that the event was actually allowed, and logs it.

If you want to change the outcome of an event, choose very carefully from LOWEST to HIGHEST. Suggested generalized protection plugins on lowest, more specific plugins on normal, and override plugins on high. If you want to act when an event happens, but not change the outcome, use MONITOR. It's really really important that you use MONITOR, or an event might get cancelled after you've acted on it, and it's even more important that you don't change the outcome of the event on MONITOR or it'll break other plugins.

中文简单解释

优先级越高的方法越早调用

优先级再高(除了MONITOR) setCanceled() 方法也不能阻止其它插件监听到它

在MONITOR上搞 setCanceled(false) 其它插件会给你玩死~

注册事件(监听器)

要注册你的方法,包含EventHandler的类必须是implent了Listener类的

import org.bukkit.event.Listener;

public final class LoginListener implements Listener {
}

你只需要提供一个插件和一个监听器来在PluginManager里注册它们

getServer().getPluginManager().registerEvents(Listener, Plugin);

监听器示例

这个监听器包含两个EventHandlers,一个监听级别是HIGH并且另一个是NORMAL。

import org.bukkit.event.Listener;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerLoginEvent;

public final class LoginListener implements Listener {
    @EventHandler
    public void normalLogin(PlayerLoginEvent event) {
        // Some code here
    }

    @EventHandler(priority = EventPriority.HIGH)
    public void highLogin(PlayerLoginEvent event) {
        // Some code here
    }
}

在插件中注册事件监听器

注册事件需要监听器和对应插件,幸运的是,我们拥有属于我们自己的登陆监听器,现在我们来写一个登陆插件吧 The registerEvents method requires a listener and a plugin. Luckily, we already have our LoginListener. Now for the LoginPlugin!

import org.bukkit.plugin.java.JavaPlugin;

public final class LoginPlugin extends JavaPlugin {
    public void onEnable() {
        getServer().getPluginManager().registerEvents(new LoginListener(), this);
    }
}


在实现监听器接口的插件中注册事件监听器

[1] 你甚至可以在主类中创建监听器,像这样:

import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.event.Listener;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerLoginEvent;

public final class LoginPlugin extends JavaPlugin implements Listener {
    public void onEnable() {
        getServer().getPluginManager().registerEvents(this, this);
    }

    @EventHandler
    public void normalLogin(PlayerLoginEvent event) {
        // Some code here
    }
}

在监听器中注册事件监听器

There are many ways to register your events. Here's an example where you register them in your listener class.

import org.bukkit.event.Listener;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerLoginEvent;

public final class LoginListener implements Listener {
    public LoginListener(LoginPlugin plugin) {
        plugin.getServer().getPluginManager().registerEvents(this, plugin);
    }

    @EventHandler
    public void normalLogin(PlayerLoginEvent event) {
        // Some code here
    }

    @EventHandler(priority = EventPriority.HIGH)
    public void highLogin(PlayerLoginEvent event) {
        // Some code here
    }
}

The LoginPlugin would look like this:

import org.bukkit.plugin.java.JavaPlugin;

public final class LoginPlugin extends JavaPlugin {
    public void onEnable() {
        new LoginListener(this);
    }
}

在监听器中注销事件监听器

你可以自己取消个人事件,整个注册侦听器类或所有事件由你的插件或者其他插件!

注销特定的事件监听器

每个事件类getHandlerList()静态方法,调用,然后你可以使用.unregister()方法。例子:

PlayerInteractEvent.getHandlerList().unregister(plugin);
// this will unregister all PlayerInteractEvent instances from the plugin
// you can also specify a listener class instead of plugin.

Now you know why you'll need the getHandlerList() in your custom events.

注销所有事件监听器

Using the HandlerList class and its unregisterAll() static method you can easily unregister events from listener classes or plugins. Example:

HandlerList.unregisterAll(plugin);
// this will unregister all events from the specified plugin
// you can also specify a listener class instead of plugin.

创建自定义事件

创建一个自定义事件是非常简单的,你可以使用跟Bukkit用的一样的系统,而不需要担心服务器性能的问题。

在你创建一个自定义事件的时候,有两个东西你要记住——"继承 Event 类" 和 "静态的 handlers" 。你必须像下面这样写来做静态的handlers:

private static final HandlerList handlers = new HandlerList();

public HandlerList getHandlers() {
    return handlers;
}

public static HandlerList getHandlerList() {
    return handlers;
}

这块代码可以让 EventHandlers 更方便的操作事件,使无关的事件完全的分开。

自定义事件示例

下面的这个例子向你展示如何简单地创建一个你自己的事件——“CustomEvent事件”。

import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;

public final class CustomEvent extends Event {
    private static final HandlerList handlers = new HandlerList();
    private String message;

    public CustomEvent(String example) {
        message = example;
    }

    public String getMessage() {
        return message;
    }

    public HandlerList getHandlers() {
        return handlers;
    }

    public static HandlerList getHandlerList() {
        return handlers;
    }
}

调用你的自定义事件

你可以自由地创建并触发事件,也可以自由地选择在何处触发。以下是一个例子:

// 创建一个自定义事件对象
CustomEvent event = new CustomEvent("Sample Message");
// 触发事件(创建好自定义事件对象,要使用本语句触发事件,否则什么都不会发生)
Bukkit.getServer().getPluginManager().callEvent(event);
// 然后继续操作事件
Bukkit.getServer().broadcastMessage(event.getMessage());

请你记住!你正在控制你的自定义事件的对象。如果你不触发它,那就啥都不会发生。

监听一个自定义事件

如何监听一个自定义事件呢?简单!就像监听Bukkit其他普通的事件是一样的!

import org.bukkit.event.Listener;
import org.bukkit.event.EventHandler;

public final class CustomListener implements Listener {
    @EventHandler
    public void normalLogin(CustomEvent event) {
        // 你的代码
    }
}

使得你的自定义事件具有可撤销性

如果你想让你的自定义事件可以被撤销,记得,要“继承Cancellable类”。就像你继承Listener那样。这十分简单,让我向你展示一个例子!

import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Cancellable;

public final class CustomEvent extends Event implements Cancellable {
    private static final HandlerList handlers = new HandlerList();
    private String message;
    private boolean cancelled;

    public CustomEvent(String example) {
        message = example;
    }

    public String getMessage() {
        return message;
    }

    public boolean isCancelled() {
        return cancelled;
    }

    public void setCancelled(boolean cancel) {
        cancelled = cancel;
    }

    public HandlerList getHandlers() {
        return handlers;
    }

    public static HandlerList getHandlerList() {
        return handlers;
    }
}

之后,你需要在你执行相应代码前,检查一下是否有插件把你的事件撤销掉了。

// 创建一个事件对象
CustomEvent event = new CustomEvent("Sample Message");
// 触发事件
Bukkit.getServer().getPluginManager().callEvent(event);
// 检查一下是否事件被撤销
if (!event.isCancelled()) {
    // 现在在这里做些什么吧!
    Bukkit.getServer().broadcastMessage(event.getMessage());
}

视频教程

If you would prefer to watch a video tutorial version of this, please click here.

  1. 准确来说是在实现了监听器接口的继承了JavaPlugin的类中注册事件(笑