I have been making a bukkit plugin, which shows up in the plugins list but when I do what I want the code to do nothing happens.
public class MyClass extends JavaPlugin implements Listener {
#EventHandler
public void onInteract(PlayerInteractEvent event) {
Player player = event.getPlayer();
if (player.isSneaking()) {
player.sendMessage("Fire!");
Arrow arrow = player.launchProjectile(Arrow.class);
arrow.setShooter(player);
arrow.setGravity(false);
arrow.setSilent(true);
arrow.setBounce(false);
Block attach = arrow.getAttachedBlock();
Location attachlocation = attach.getLocation();
attachlocation.getWorld().createExplosion(attachlocation, 3);
arrow.setVelocity((player.getEyeLocation().getDirection().multiply(1000)));
}
}
}
I can't see you registering your listener. Bukkit needs to know what objects are listeners (you're not doing this) and it needs to know what methods to execute (with the #EventHandler annotation)
You can register the listener with PluginManager's registerEvents(Listener listener, Plugin plugin) method. A smart idea is to do this inside your onEnable method, to ensure your listener is registered as soon as your plugin starts.
public class MyClass extends JavaPlugin implements Listener {
#Override
public void onEnable() {
this.getServer().getPluginManager().registerEvents(this, this);
}
// rest of your code
}
Just a quick tip,
If you want to register a listener for a different class then the code in #onEnable() would be:
public void onEnable() {
this.getServer().getPluginManager().registerEvents(this, this); //You have to
register the main class as a listener too.
this.getServer().getPluginManager().registerEvents(new EventClass(), this);
}
Thanks!
The listener class code you are trying to call would be helpful to try and debug this scenario. You must make sure the following is true:
1) Class implements Listener
2) You register the class using:
Bukkit.getServer().getPluginManager().registerEvents(new [class] /* class of listener. this if it's your main class */, this/* your main class */);
3) You remembered #EventHandler before every event.
If you are learning bukkit programming it may be worth checking out this video: https://youtu.be/Rinjdx6c6r8 and this series:
https://www.youtube.com/watch?v=bVySbfryiMM&list=PLAF3anQEEkzREsHA8yZzVhc3_GHcPnqxR
Related
I have heard of ways to run code later like run task later and other scheduler methods but I want to do it inside of an event which I am having trouble with. Here is some code for an example of where I want to run it:
public class InventoryEvents implements Listener {
#EventHandler
public void onOpen(InventoryOpenEvent e) {
// Run later code here
}
}
When I try using code for something like run task later here or outside of it or even in another class I get a lot of errors relating to the class not extending JavaPlugin or me trying to use it in an event.
Any help is appreciated, thanks :)
You will need to create your scheduled task inside the onOpen method that's handling the InventoryOpenEvent.
Bukkit.getScheduler().runTaskLater(main, new Runnable() {
#Override
public void run() {
//Run your delayed code in here
}
}, 100L);//replace 100 with how many ticks you want to wait before the code executes
The main is where your errors are coming from. You need to use an instance of whatever class extends JavaPlugin (this would be your main class). I recommend passing the instance of your main into the Listener class in the constructor so you can use it as needed. An example would be as follows:
public class NamedListener implements Listener {
private Main main;
public NamedListener(Main main){
this.main = main;
}
}
Whenever we want to create a listener, we implement a listener interface. For example, lets implement SensorEventListener.
Now we have to override the methods of this listener interface.
public void onSensorChanged(SensorEvent event);
and
public void onAccuracyChanged(Sensor sensor, int accuracy);
What I don't understand is:
Why and how these methods work when I automatically use them?
Why does onAccuracyChanged method gets called when the accuracy changes?
After all, onAccuracyChanged is just an empty method that we override because our formula (or the interface we implement) requires us to do so. If it is something magical caused by the lower levels
When and why would someone actually use an interface in his/her
self-project regardless of android?
Here is a suitable answer. Allow me to give you an example about listeners.
Listeners:
Suppose there is a class that fetches data in the background, the Worker, and another class that is interested in that data, the InterestedClass.
public class Worker extends Thread{
interface DataFetchedListener{
void onDataFetched(String data);
}
private DataFetchedListener listener;
#Override
public void run(){
String data = fetchData();
// Data fetched inform your listener so he can take action
listener.onDataFetched(data);
}
public void setDataFetchedListener(DataFetchedListener listener){
this.listener = listener;
}
private String fetchData(){
// returns the fetched data after some operations
return "Data";
}
}
public class InterestedClass implements Worker.DatafetchedListener{
#Override
public void onDataFetched(String data){
doSomethingWith(data);
}
private doSomethingWith(String data){
// just print it in the console
System.out.println("Data fetched is -> " + data);
}
}
The Worker does not care which class will manipulate its data, as long as that class follows the contract of DataFetchedListener.
Equally this means that any class is able to do something with the data (InterestedClass just prints it in the console) but Worker does not need to know which class is that, just that it implements its interface.
The main could go like this...
public class Application{
public static void main(String[] args){
InterestedClass interested = new InterestedClass();
Worker worker = new Worker();
worker.setDataFetchedListener(intereseted);
worker.start(); // Starts Worker's thread
}
}
When the Worker will fetch the data then it will notify its listener (currently the interested object) and the listener will act accordingly (interested will print the data to the console).
In computing, an interface is a shared boundary across which two or more separate components of a computer system exchange information.(Wikipedia)
You may wish to respond to some events either system events or user events. But for that you need to know when the event you wish to capture occurs and also what must be done at that time.
And for that you open a confidential EAR to listen to events. But that will not be sufficient since you need to be notified too so that you can reply according to the event. You set callbacks that will notify when an event occur. Those empty body methods we create inside an interface.
A Listener is that interface that hears and notify back through callbacks.
So how can all that be used? And how all these do interact?
First create an interface with empty bodies methods that you intend to call when an event occurs:
public interface MyListener{
void actionOneHappens(Object o);
void actionTwo();
void actionThree();
}
Create a class that handles something, for example counts:
public class MyCounter{
//create a member of type MyListener if you intend to exchange infos
private MyListener myListener;
//let's create a setter for our listener
public void setMyListener(MyListener listener)
{
this.myListener=listener;
}
MyCounter(){
}
//this method will help us count
public void startCounting()
{
new CountDownTimer(10000,1000)
{
#Override
public void onTick(long millisUntilFinished) {
//I want to notify at third second after counter launched
if(millisUntilFinished/1000==3)
{
// I notify if true :
//as someone can forget to set the listener let's test if it's not //null
if(myListener!=null){
myListener.actionThree();
}
}
}
#Override
public void onFinish() {
}
}.start();
}
}
You can then create an object of type MyCounter and know when it's at three:
MyCounter myCounter=new MyCounter();
myCounter.setMyListener(new MyListener()
{
//then override methods here
#override
void actionOneHappens(Object o){
}
#override
void actionTwo()
{}
#override
void actionThree()
{
//Add you code here
Toast.makeText(getApplicationContext(),"I'm at 3",Toast.LENGTH_LONG).show()
}
});
//start your counter
myCounter.startCounting();
And it's done!! That's how we proceed.
Interfaces have no implementation and for using them we have two options:
A class that implement them
An anonymous class
And consider this code:
interface TestInterface {
void doSomething();
}
class TestClass{
private TestInterface ti;
public TestClass(TestInterface ti){
this.ti = ti;
}
public void testActionMethod(){
ti.doSomething();
//some other codes
}
}
class OurOwnLauncherApp{
public static void main(String[] args) {
TestClass tc = new TestClass(new TestInterface() {
#Override
public void doSomething() {
System.out.println("Hi!");
}
});
tc.testActionMethod();
TestClass tc2 = new TestClass(new TestInterface() {
#Override
public void doSomething() {
System.out.println("Bye!");
}
});
tc2.testActionMethod();
}
}
In here we have:
An Interface (Just like what you asked)
A function class the uses that interface
An application somewhere that we don't know (Maybe your phone app, maybe your friends phone app, etc)
What this code does, it gives an anonymous class (which implements TestInterface) to the testActionMethod and with calling doSomething method inside testActionMethod, we invert the calling back to our own method. that's why you will see this result:
Hi!
Bye!
This is exactly a simplified version of listener interfaces and how they work
There is no magic thing. Generally, the event-listener mechanism is as follow:
For some entities, there is the possibility to listen to some events on that entity (let name this entity as event generator). So some way should exist for other entities to listen to these changes (let name these entities as listeners). Now a listener registers itself as a listener of event generator. When an event occurs on the event generator, it calls the related method of registered listeners.
As a simple example assume a button. The button may generate an event for some actions such as click. Now if a listener wants to aware when the button is clicked, it should register itself as a listener of that button. On the other hand, the button should provide a unified way of registering the listeners. This unified way is the interface. Each entity which implements the interface could register itself as a listener for click on that button:
1- Listener implements the interface
2- Listener registers itself as a listener of button (Event Generator)
3- Event Generator calls the appropriate method of all registered listeners (this method is a method of the interface).
For your case, android provides a manager which you could register a listener on some sensors by it: android.hardware.SensorManager.registerListener(). All things occurs here (which is not magic!). When you register an entity (which implemented the related interface, SensorEventListener) as a sensor listener, changes in that sensor will cause to call methods of the listener).
Herbert Schildt describes the event source as an object that generates an event.
General form-
public void addTypeListener(TypeListener el)
My question is - where is this method declared and defined. in which class of which package. I have tried google but in vain.
Kindly help!
An event source can be any class you choose. If you're, like, creating a game, the Player class could be an event source. This is a small example for a Player class with player listeners.
public class Player {
public List<PlayerListener> listeners = new ArrayList<PlayerListener>();
// ...
public void addPlayerListener(PlayerListener listener) {
listeners.add(listener);
}
// ...
public void firePlayerEvent(PlayerEvent event) {
for(PlayerListener listener : listeners) {
listener.onPlayerEvent(event);
}
}
}
The addPlayerListener(PlayerListener) method adds an instance of PlayerListener to the list of listeners the Player object will notify if some player event was fired (see firePlayerEvent(PlayerEvent)).
In case you need some reference, I'm doing a homework for university that includes events. You can check it out at BitBucket.
The class example below MyAppender is called from the logback.xml file.
When the append() is called by logback i have no reference to the
class MyAppenderso i cannot attach any Observer or register a Listener
Does logback have some Listener the Swing gui can register or what should i do?
Have been reading the logback manual but i cannot figure this out.
public class MongoAppender extends AppenderBase<ILoggingEvent> {
public MongoAppender () {
}
#Override
public void start() {
super.start();
}
public void append(ILoggingEvent event) {
// Inserting log event into MongoDb
// just got an error...
// how do i send this error back to Swing Gui?
}
}
In the append i did not make and call to the gui.
I ended up writing to the DB whatever needed to be saved.
This of course is cleaner and safer then having classes trying to
address each other.
public class MyActivity extends AbstractActivity implements ContextChangedEvent.Handler
{
public MyActivity()
{
ClientFactory.INSTANCE.getEventBus().addHandler(ContextChangedEvent.TYPE, this);
}
#override
public void onContextChanged()
{
//do stuff
}
}
//The getEventBus Implementation:
public EventBus getEventBus()
{
if (eventBus == null)
eventBus = new ResettableEventBus(new SimpleEventBus());
return eventBus;
}
When I add a breakpoint in the onContextChange() method, I get the following behavior:
on the first Place, i break only once for each event fired
after a place changed, I break twice
after another place change, 3 times....
Since I'm using a new instance of MyActivity for each place, my guess is that I break in several instances of MyActivity. The ResettableEventBus should unregister all handler on each place change.
I am missing something?
With ResettableEventBus you still have to call removeHandlers (plural) to detach everything. ResettableEventBus only keeps track of your handlers and adds a function to remove all handlers that was attached to this instance.
If you are using ActivityManager and passing in your eventbus, ActivityManager will wrap your EventBus in ResettableEventBus and pass it to you in start.
ActivityManager(myActivityMap, ClientFactory.INSTANCE.getEventBus());
...
public class MyActivity extends AbstractActivity implements ContextChangedEvent.Handler
{
public MyActivity()
{
}
#override
public void onContextChanged()
{
// do Stuff
}
#override
public void start(AcceptsOneWidget panel, EventBus eventBus) {
eventBus.addHandler(ContextChangedEvent.TYPE, this);
}
}
If you use the eventBus passed to you in "start", ActivityManager will automatically clean the handlers you attach to it automatically for you.
Also I would suggest constructing a SimpleEventBus in your factory instead of ResettableEventBus. There is a bug in the current version of ResettableEventBus that causes issue if you nest it (Memory Leak).
http://code.google.com/p/google-web-toolkit/issues/detail?id=5700
This is more of a FYI. Also don't remove any handlers manually from the passed in eventbus. This is caused by the same bug as above.