I have a problem and am new at making Minecraft plugins and writing code in general.
I am trying to make a plugin that waits about 15 seconds before executing the second command however the code I have now has an error when I try to do (plugin, new Runnable(). I have done some research and it most people say that is because I don't have this in my Main class. The problem is that I don't want it in my Main. So I was wondering what I have to do to make this work.
Code below. Thanks in advance for any help you can provide.
~Stone
#Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
if (sender instanceof Player){
//checks to see if player sent command
Player player = (Player) sender;
if (args.length >= 1) {
//too many arguments message
player.sendMessage(Utils.chat("&4There were too many arguments, I could not complete that command"));
}
if (player.hasPermission("reloadc.use")) {
//reloads server, sends message, and stores variable value
Bukkit.broadcastMessage(Utils.chat("&6Server will be reloaded in 15 seconds by &5" + player.getDisplayName()));
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
public void run() {
Bukkit.broadcastMessage(Utils.chat("&6This works"));
}
}, 20L);
Bukkit.broadcastMessage(Utils.chat("&6IT WORKED!!!!!"));
}
else if (!player.hasPermission("reloadc.use")) {
player.sendMessage(Utils.chat("&4You do not have permission to reload the server"));
player.sendMessage(Utils.chat("&5If you belive this is a mistake please contact an admin"));
}
}
return true;
}
}
The Code that is giving me problems is right here (the word plugin)
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
public void run() {
Bukkit.broadcastMessage(Utils.chat("&6This works"));
}
}, 20L);
Here are 3 images with the errors that it is giving me. The only change that i did not make was the getServer(). because it gave me more errors and did not change anything for the better at least from what I can tell.
1[]2
[]
Ok So I have completed the changes, everything says that it works but now when I run the command that I setup it does everything it should except wait for 15 seconds. It executes the text one after the other telling me that it will be reloaded in 15 seconds and then at the same time it tells me it worked. Nothing seems wrong to me now, it just says that it is running fine and my wait time is 300L which is server ticks. That should equal 15.
Images of completed code below.
In response to your update/edit:
Your error happens because you use plugin does not mean anything to your code. You need to declare it as a variable before you use in there, or assuming that you wrote all the code in one class for your plugin then you can easily replace plugin with this like so Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() {.
If it is in another class then to declare the variable you need to pass it in from another class or call it from your Main plugin class. The following will show you haw to pass it to your listener class.
In your main plugin class you need to do this, note how we add this to the function that is calling your command class new CommandClass(this) note that your class will have a different name than CommandClass:
public class Main extends JavaPlugin{
#Override
public void onEnable(){
new CommandClass(this);
}
}
And then in the command class, we modify it to receive the variable public CommandClass(Main plugin):
public class CommandClass implements CommandExecutor{
private Main plugin;
public CommandClass(Main plugin){
this.plugin = plugin;
}
}
Now your onCommand method will work because you have a reference to plugin in your class:
#Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
#Override
public void run() {
Bukkit.broadcastMessage(Utils.chat("&6This works"));
}
}, 300L);
}
Original answer edited a little to include some of the response to your screenshots:
I can see four problems:
Your error happens because you have not referenced your actual plugin, but just typed plugin.
Please note that the delay is in server ticks, so 20L will only have
a delay of 1 second. If you want 15 seconds delay then use 300L.
You didn't use the #Override annotation, but it is very important for the runnable task.
You could use getServer().getScheduler() instead of Bukkit.getScheduler(), just in case there is something funky going on with your code and you have managed to start more than one instance of the server.
Here is an updated version of your code with 1 and 3 fixed:
Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
#Override
public void run() {
Bukkit.broadcastMessage(Utils.chat("&6This works"));
}
}, 300L);
Here is an updated version of your code with suggestion 4 included:
getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
#Override
public void run() {
Bukkit.broadcastMessage(Utils.chat("&6This works"));
}
}, 300L);
Related
So I just started playing around with JDA API trying to create a little /info command which looked like shown below.
Issue: Unfortunately the bot does not react when I type /info.
While I was debugging, I found out, that the Info command never get's called and I will explain why later, after showing you the 3 classes that are involved in this problem.
public class InfoCommand extends Command {
public InfoCommand(String name) {
super(name);
}
#Override
public void handle(MessageReceivedEvent event, String... params) {
EmbedBuilder builder = new EmbedBuilder();
builder.setTitle("Test Title");
builder.setDescription("Test Description" );
builder.setFooter("Created by t0gepi");
builder.setColor(0xf45642);
event.getChannel().sendTyping().queue();
event.getChannel().sendMessageEmbeds(builder.build()).queue();
}
}
It has a method handle which will be called by a CommandManager, whenever /info is typed in the discord server.
So far so good.
Now the Main method is also quite simple. It just starts the bot and adds the CommandManager as a Listener to JDA:
public class Main {
public static JDA jda;
public static void main(String[] args) throws LoginException {
ResourceManager.init();
jda = JDABuilder.createDefault(ResourceManager.getProperty("discord.bottoken")).build();
jda.getPresence().setStatus(OnlineStatus.IDLE);
jda.getPresence().setActivity(Activity.playing("Sleeping"));
try {
jda.awaitReady();
} catch (InterruptedException e) {
e.printStackTrace();
}
CommandManager commandManager = new CommandManager();
commandManager.addCommand(new InfoCommand("info"));
jda.addEventListener(new CommandManager());
}
}
Lastly, let's get to the CommandManager:
public class CommandManager extends ListenerAdapter {
private Set<Command> commands;
public CommandManager(){
this.commands = new HashSet<>();
}
public void addCommand(Command command){
commands.add(command);
}
#Override
public void onMessageReceived(#NotNull MessageReceivedEvent event) {
String[] msg = event.getMessage().getContentRaw().split(" ");
String prefix = ResourceManager.getProperty("command.prefix");
String[] params = null;
if(!msg[0].startsWith(prefix)){
return;
}
if(msg.length > 1){
params = Arrays.copyOfRange(msg,1,msg.length);
}
Iterator<Command> iterator = commands.iterator();
Command command;
while(iterator.hasNext()){
command = iterator.next();
if(command.getAliases().stream().anyMatch(alias -> msg[0].equalsIgnoreCase(prefix + alias))){
command.handle(event, params);
return;
}
}
// Do nothing here if command wasn't found.
}
}
Now let's get to the actual issue, why does the InfoCommands handle method not get called? Keep in mind that
InfoCommand has bin initialized and added to the CommandManager
The CommandManagers onMessageReceived method is in fact being called when a message is typed
As I was debugging, I found out why but could not find an explanation to it.
The reason why the handle method of InfoCommand does not get called, is because as to the time when onMessageReceived gets called, the CommandManagers set of commands is empty.
Why is that? I added the InfoCommand in the beginning right?
When I added the InfoCommand in the beginning, the set of commands had a size of 1. All good. But when onMessageReceived got called, the set of Commands suddenly had a size of 0, which means that the Iterator doesn't have anything to iterate over.
Why is that? I furthermore found out the following:
As to the time where I initialized the CommandManager, the CommandManager had a different memory adress than when it's onMessageReceived method got called.
So somehow, JDA must have created another new instance of CommandManager and used that, instead of my instance, right?
I hope someone understands this and let me know if you have any questions :)
Thanks for reading that far and if you'd like, you can take a better look at all the files in this Project here. There really aren't much more.
You are creating a new instance of your command manager when you register it:
jda.addEventListener(new CommandManager());
Instead, you should just pass in the instance you previously created:
CommandManager commandManager = new CommandManager();
commandManager.addCommand(new InfoCommand("info"));
jda.addEventListener(commandManager);
I am using the first answer here to try to initiate a repeating task, updating a seekbar ("timeSlider") to show progress as an audio file plays. The repeating function is updateTimeSlider(). When initiated via postDelayed, updateTimeSlider gives a "cannot resolve symbol" error (see image at the bottom of this post). updateTimeSlider() does not give that error when on a line by itself (also shown in the image).
(Note that updateTimeSlider() on the line by itself is not really how the code will go. It's just there to demonstrate that it works in that position.)
Can anyone help me understand how to correct the problem in the postDelayed line?
Several people have suggested that I just forgot to write the do in doUpdateTimeSlider. I did not forget. I wanted to execute updateTimeSlider (without the do), which does execute just fine and does not produce an error outside of postDelayed. updateTimeSlider is a C++ function used via JNI (Java Native Interface) using a statement at the bottom of this Java file that looks like this:
private native void updateTimeSlider();
The JNI aspect of things is working fine, and updateTimeSlider() is the method I am trying to execute, not doUpdateTimeSlider.
As an aside, I did try putting doUpdateTimeSlider in there, and it also results in an error: Variable doUpdateTimeSlider may not have been initialized.
I also don't see what good it would do me if I could execute doUpdateTimeSlider since there is no code in it to actually update the the timeSlider seekbar.
public class PlayActivity extends AppCompatActivity {
private static final String TAG = "PlayActivity";
boolean playing = false;
private int timeSliderInterval = 1000; // 1 second
private Handler timeSliderHandler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_play);
final Runnable doUpdateTimeSlider = new Runnable() {
#Override
public void run() {
timeSliderHandler.postDelayed(updateTimeSlider, timeSliderInterval);
updateTimeSlider();
}
};
You could replace:
timeSliderHandler.postDelayed(updateTimeSlider, timeSliderInterval);
with:
timeSliderHandler.postDelayed(doUpdateTimeSlider, timeSliderInterval);
You forgot to write do in doUpdateTimeSlider.
As you can see here : https://stackoverflow.com/a/41413191/4409113
It is : doUpdateTimeSlider
final Runnable doUpdateTimeSlider = new Runnable() {
#Override
public void run() {
timeSliderHandler.postDelayed(doUpdateTimeSlider, timeSliderInterval);
updateTimeSlider();
}
};
Which #ρяσѕρєя K said the same.
Update:
To fix that may not have been initialized you can follow these links:
variable r might not have been initialized
"Variable example might not have been initialized" in anonymous class
So:
final Runnable etc = null;
final Runnable doUpdateTimeSlider = new Runnable() {
#Override
public void run() {
timeSliderHandler.postDelayed(etc, timeSliderInterval);
updateTimeSlider();
}
};
This should work now!
so, here is my today problem:
First of all, please note that I do NOT have the Matlab parallel toolbox available.
I am running java code witch interact with Matlab. Sometime Matlab directly call some java functions, sometimes it is the opposite. In this case, we use a notification system which comes from here:
http://undocumentedmatlab.com/blog/matlab-callbacks-for-java-events
We then address the notification in proper callbacks.
Here is a simple use case:
My user select a configuration file using the java interface, loaded into Matlab.
Using an interface listener, we notify Matlab that the configuration file has been selected, it then run a certain number of functions that will analyzes the file
Once the analysis is done, it is pushed into the java runtime, which will populate interface tables with the result. This step involve that matlab will call a java function.
Finally, java request the interface to be switched to an arbitrary decided tab.
This is the order of which things would happen in an ideal world, however, here is the code of the listener actionPerformed method:
#Override
public void actionPerformed(ActionEvent arg0) {
Model wModel = controller.getModel();
Window wWindow = controller.getWindow();
MatlabStructure wStructure = new MatlabStructure();
if(null != wModel) {
wModel.readMatlabData(wStructure);
wModel.notifyMatlab(wStructure, MatlabAction.UpdateCircuit);
}
if(null != wWindow) {
wWindow.getTabContainer().setSelectedComponent(wWindow.getInfosPannel());
}
}
What happen here, is that, when the notifyMatlab method is called, the code does not wait for it to be completed before it continues. So what happen is that the method complete and switch to an empty interface page (setSelectedComponent), and then the component is filled with values.
What I would like to, is for java to wait that my notifyMatlab returns a "I have completed !!" signal, and then pursue. Which involves asynchrounous code since Matlab will code java methods during its execution too ...
So far here is what I tried:
In the MatlabEventObject class, I added an isAcknowledge member, so now the class (which I originaly found in the above link), look like this (I removed all unchanged code from the original class):
public class MatlabEventObject extends java.util.EventObject {
private static final long serialVersionUID = 1L;
private boolean isAcknowledged = false;
public void onNotificationReceived() {
if (source instanceof MatlabEvent) {
System.out.println("Catched a MatlabEvent Pokemon !");
MatlabEvent wSource = (MatlabEvent) source;
wSource.onNotificationReceived();
}
}
public boolean isAcknowledged() {
return isAcknowledged;
}
public void acknowledge() {
isAcknowledged = true;
}
}
In the MatlabEvent class, I have added a future task which goal is to wait for acknowledgement, the methods now look like this:
public class MatlabEvent {
private Vector<IMatlabListener> data = new Vector<IMatlabListener>();
private Vector<MatlabEventObject> matlabEvents = new Vector<MatlabEventObject>();
public void notifyMatlab(final Object obj, final MatlabAction action) {
final Vector<IMatlabListener> dataCopy;
matlabEvents.clear();
synchronized (this) {
dataCopy = new Vector<IMatlabListener>(data);
}
for (int i = 0; i < dataCopy.size(); i++) {
matlabEvents.add(new MatlabEventObject(this, obj, action));
((IMatlabListener) dataCopy.elementAt(i)).testEvent(matlabEvents.get(i));
}
}
public void onNotificationReceived() {
ExecutorService service = Executors.newSingleThreadExecutor();
long timeout = 15;
System.out.println("Executing runnable.");
Runnable r = new Runnable() {
#Override
public void run() {
waitForAcknowledgement(matlabEvents);
}
};
try {
Future<?> task = service.submit(r);
task.get(timeout, TimeUnit.SECONDS);
System.out.println("Notification acknowledged.");
} catch (Exception e) {
e.printStackTrace();
}
}
private void waitForAcknowledgement(final Vector<MatlabEventObject> matlabEvents) {
boolean allEventsAcknowledged = false;
while(!allEventsAcknowledged) {
allEventsAcknowledged = true;
for(MatlabEventObject eventObject : matlabEvents) {
if(!eventObject.isAcknowledged()) {
allEventsAcknowledged = false;
}
break;
}
}
}
}
What happen is that I discover that Matlab actually WAIT for the java code to be completed. So my waitForAcknowledgement method always wait until it timeouts.
In addition, I must say that I have very little knowledge in parallel computing, but I think our java is single thread, so having java waiting for matlab code to complete while matlab is issuing calls to java functions may be an issue. But I can't be sure : ]
If you have any idea on how to solve this issue in a robust way, it will be much much appreciated.
I am searching a listener in Eclipse, that will detect if a file is changed externally by third party software, like MKS.
I used IResourceChangeListener and it worked. But problem is, it also listens other changes of the file. For example, when I delete the markers, it also listens and execute the codes I wanted after listening.
Is there any Listener, which listens only if the file is changed (newly opened/refreshed) by third party software?
Updated:
My code:
public class Startup implements IStartup {
IWorkspace workspace = ResourcesPlugin.getWorkspace();
IResourceChangeListener listener = new IResourceChangeListener() {
public void resourceChanged(IResourceChangeEvent event) {
if(event.getType() == IResourceChangeEvent.POST_CHANGE && IResourceDelta.MARKERS!=0){ //Filtering listener
System.out.println("Listener code should be implemented here");
}
System.out.println("listener is working"); //This line always get executed. That means the listener is working
}
};
#Override
public void earlyStartup() {
workspace.addResourceChangeListener(listener,IResourceChangeEvent.POST_CHANGE);
//... some time later one ...
// workspace.removeResourceChangeListener(listener);
}
}
I there a way to show a message from android java files in cordova? I've tried alert, log.i, console.log, print and System.out.println, but nothing works. By building the app, an error shows up.
for example:
log.w("test");
error: no suitable method found for w(String)
Only callbackContext works, but sends a success or failed return and the code stops at this point.
EDIT:
System.out hasn't appeared anything, now I try over hours to work with loadUrl but recieve error messages like this one:
error: variable mainView might not have been initialized
Code:
import org.apache.cordova.CordovaWebView;
public class VideoCapture extends CordovaPlugin {
#Override
public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException {
CordovaWebView mainView;
mainView.loadUrl("javascript:alert('hello');");
How do I implement the webView?
If you use System.out, it should appear on the logcat
if you want to execute javascript code from java you can use the loadUrl method, so you can use javascript alert or console.log. Example:
webView.loadUrl("javascript:alert('hello');");
or to run it on the UI Thread
cordova.getActivity().runOnUiThread(new Runnable() {
public void run() {
webView.loadUrl("javascript:alert('hello');");
}
});
or this to run on main thread
cordova.getThreadPool().execute(new Runnable() {
public void run() {
webView.loadUrl("javascript:alert('hello');");
}
});