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;
}
}
Related
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
I would like to call different code (callbacks) from within a background thread loop and use that background thread to perform the work. It would be similar to delegates in C#.
public class test {
private boolean keepRunning;
private boolean messageReady;
private MyClass myClass;
void LongBackgroundWork(){
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
while (keepRunning) {
if (messageReady){
myClass.callback(); // call different methods here
// to be decided at runtime and run on this worker thread
}
}
}
});
thread.start();
}
}
I want to use the background thread not the UI thread. I want to set a callback from within myClass to choose what code is called. It's easy in C# how to do it Java.
I don't have much experience in Java and don't understand what mechanism to use. Should I be using a handler? Can a handler run code on a background thread?
I'd wager you want to have a pattern where an event or some occurence happens and you need to initiate a code block somewhere.
A pattern that could help you is perhaps an Observer Wiki and firing off to the event. You can also check out this SO question here if you'd like: Delegate vs Callback in Java
In your case, I think you'd want to have someone handle the responsibility of what you have to do when a message is ready. So what you're looking for is someone to perform the action, once the event is read (message ready).
Take for example Class Foo is your container of listeners, or also called an Observer that will be notified of any events. You can have a list of callbacks here to some object that is responsible for your logic to do what you need to do next.
Then you would have an Observable object or a class that would implement some logic when notified. You could then have various class objects perform the necessary logic by implementing the callback function required.
Example:
// Observer
public class Foo {
// List of objects that implement Callbacks interface
private List<Callbacks> mList;
public Foo() {
// Initialize here
}
public void addListener(Callbacks cb) {
mList.add(cb);
}
public void notifyListeners() {
for ( Callback cb : mList) {
cb.onCallback();
}
}
// Public interface to be implemented by users
public interface Callback {
void onCallback();
}
}
Then just have a class implement this object and you can pass it along if you'd like.
// Bar implements Foo.Callback interface
public class Bar implements Foo.Callback {
public class Bar() {}
#Override
public void onCallback() {
// Perform logic here
}
}
Finally in your code, you'd just create the Foo object, add a listener, and notify them when it's time to fire your event.
if i understood you properly,you cant do this on UI thread, basically when android see Thread like this it will expect that it's a long operation however you can call it by AsyncTask or Handler
you can make something like this
private class MyAsyncTask extends AsyncTask<Void,Void,Void>{
protected Void doInBackground() {
MyClass myClass=new MyClass();
myClass.LongBackgroundWork();
}
return totalSize;
}
}
this is how yo can call your thread otherwise you have to use Handler instead
Handler handler=new Handler();
handler.post(new Runnable(){
MyClass myClass=new MyClass();
myClass.LongBackgroundWork();
})
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I have a problem when I want to run several methods not in the main thread. I created a class extends from Runnable and put all my tasks there. There are a lot of tasks actually. Then in the main thread I created a new instance of Thread and passed my runnable class as a parameter, but what I got is that the run method is the only code which executed in the thread, and if call any method inside the runnable class it will execute in the main thread instead of the new thread.
Example:
public class ConnectionManager implements Runnable {
#Override
public void run() {
login();
}
public void login() {
//Login Logic
}
public void sendMessage() {
//Send Message Via TCP Connection
}
public void updateInfo() {
//Update Information
}
public void logOut() {
//LogOut Logic
}
}
Now I wanted to call any of these methods in another thread, so I did this:
public class Login implements SomeInterface {
private Thread thread;
private ConnectionManager connection;
public void main(String[] args) {
connection = new ConnectionManager();
thread= new Thread(connection);
thread.start(); // This will execute the run method and the login process works fine.
}
#Override
public void someCallback() {
connection.sendMessage();//this call is not executed and block the main thread !!
}
}
What am I supposed to do to run all my methods in another thread without making a new thread for each method?
You should split your logic
public class Logger implements Runnable {
#Override
public void run() {
// login logic here;
}
}
public class MessegeSender implements Runnable {
#Override
public void run() {
//Send Message Via TCP Connection
}
}
public class MessegeSender implements Runnable {
#Override
public void run() {
//Update Information
}
}
public class MessegeSender implements Runnable {
#Override
public void run() {
//LogOut Logic
}
}
And then in some client:
Runnable logger = new Logger(credentials);
Executors.newSingleThreadExecutor().execute(logger);
Well this is how threads work in java. One possibility is to use Actors in java. You will have to download the Akka framework here:http://akka.io/downloads/.
Actors works by messages, they act in a separate process and are even driven messages. In other words depending on the message you send to the actor it will process a corresponding method.
Check in the following link for instances: http://doc.akka.io/docs/akka/snapshot/java/untyped-actors.html
The method run equivalent in java actors is onReceive().
And to send a message to the actor, myActor.tell(...)
Hope this helps you!!!!
Well, that is the way threads work in Java. When You call connection.sendMessage() Your method just treats ConnectionManager and runs it's code. You need to execute Your method in another threads run(), or it will not run. Perhaps You need a way to comunicate with Your thread to make it execute a method in run() or just explore the possibilities that Future objects give You?
That's how does Runnable or Multithread handling work.
You should never call the run() directly and only this function and other function calls inside this function are executed in the new thread.
Basically your Runnable class should only contains one public function: the run() and you should not call it directly...
I suggest you to put other functions in their own classes. As you can see the workflow is not continuous, sendMessage() is not called directly after login() (otherwise you can do it inside run() and don't need that someCallback()).
Otherwise what should that new thread supposed to do in the time between? block and wait for sendMessage()? That's not a good design. So you should start a new thread for sendMessage().
I have a JTextArea inside a class that I want to update dynamically. Currently it is only displaying the text I append to it after all the processing is done. I have tried to implement the following to fix it:
public NewConsole(){
initComponents();
}
public void write(final String s){
SwingUtilities.invokeLater(new Runnable() {
public void run() {
textarea.append(s);
}
});
}
Console gets instantiated in a parent class as:
protected NewConsole console = new NewConsole();
and to output to it, all the children call:
console.write("Append this..");
EDIT: Here's some more information:
public abstract class Parent{
protected NewConsole console = new NewConsole();
public Parent(){}
protected abstract int doSomething();
}
public class Child extends Parent{
public Child(){
console.write("I want this to update dynamically");
doSomething();
console.write("And this..");
}
public int doSomething(){
//Quite intensive processing here
}
}
The intensive processing done in doSomething is blocking the EDT, preventing UI updates. Use a SwingWorker instead to perform this functionality.
Use execute to start the worker. Move any required calls to console.write to either doInBackground or done.
You might try calling invokeAndWait() in place of invokeLater(), but in fact there is not enough information to be sure of an answer here.
I think of invokeLater() as "put this in your queue of things to do", and invokeAndWait() as "put this in the queue of things to do, and I'll suspend while you do them". I don't know if this change will fix your problem, but it seems like something to try based on what you've told us.
As an addition to my current application, I need to create a separate thread which will periodically do some processing
I've create a new class to do all this, and this class will be loaded on startup of my application.
This is what I have so far :
public class PeriodicChecker extends Thread
{
static
{
Thread t = new Thread(new PeriodicChecker());
while(true)
{
t.run();
try
{
Thread.sleep(5000l);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
/**
* Private constructor to prevent instantiation
*/
private PeriodicChecker()
{
}
#Override
public void run()
{
System.out.println("Thread is doing something");
// Actual business logic here, that is repeated
}
}
I want to make constructor private to prevent other people from attempting to instantiate this class accidentally. How can I achieve this?
Also, is there anything bad about my implementation of such requirements? I'm only creating one thread which will run then sleep, have I missed anything obvious? I haven't worked with threads before
Java offers ScheduledExecutorService to schedule and run periodic tasks or tasks with delay. It should provide all the features you need. Timer is another class that offers similar functionalities, but I would recommend the ScheduledExecutorService over Timer for its flexibility of configuration and better error management.
You have some conceptual erros in your code... for example:
You should call start() and not run(), because you are running the method sequentially and not simultaneously.
You can call start() only once, not once in each loop iteration. After that, the thread is in state TERMINATED, you should create a new thread to run it again
You should not create the thread in the static block, it is a bad practice, and maybe the Thread is running before you want it to run.
You should read some examples about thread, it is a little difficult to unserstand at the beginning, and you can have undesired effects very easily.
Here is a little example, that may do something similar to that you want:
public class PeriodicChecker extends Thread
{
#Override
public void run()
{
while(true) {
System.out.println("Thread is doing something");
Thread.sleep(5000);
}
}
}
public OtherClass {
public static void main(String args[]) {
Thread t = new PeriodicChecker();
t.start();
}
}
If you want that none can create a new Thread, you could create a singleton, so you will be sure that none is creating more threads.
I'd recommend you to consider Timer class - it provides functionality for periodic tasks execution.
Also you may take a look at "Timer & TimerTask versus Thread + sleep in Java" question discussion - there you can find some arguments and examples.
First of all to answer your specific question, you have already achieved your objective. You have declared your constructor to be private meaning no external class can call it like new PeriodicChecker().
Looking at your code however, there are a number of other problems:
Firstly, you are creating an instance of your class within its own static constructor. The purpose of a static constructor is to initialise any static state that your class may have, which instances of your class may then depend on. By creating an instance of the class within the static constructor, all of these guarantees go out the window.
Secondly, I don't think your thread is going to behave in the way you expect it to behave, primarily because you don't actually start another thread :). If you intend to start a new thread, you need to call the start() method on that thread object. Calling run() as you do does not actually create a new thread, but simply runs the run() method in the current thread.
Nowadays when you want to create a new thread to do something, the reccomended way of achieving this is to not extend Thread, but instead implement the Runnable interface. This allows you to decouple the mechanism of the thread, from the behaviour you intend to run.
Based on your requirements, I would suggest doing away with a top-level class like this, and instead create either a private inner class within your application start-up code, or even go for an anonymous inner class:
public class Main {
public static void main(String[] args) {
new Thread(new Runnable() {
#Override
public void run() {
while(true) {
System.out.println("Thread is doing something");
Thread.sleep(5000);
}
}
}).start();
}
}
It is almost never right to extend Thread. If you ever find yourself doing this, step back, take a look and ask yourself if you really need to change the way the Thread class works.
Almost all occurances where I see extends Thread the job would be better done implementing the Runnable interface or using some form of Timer.