英文:
Can't cancel Timer Task without creating another object in JDA
问题
I understand that you want a translation of the provided code and explanation without additional information. Here's the translated code:
// Command Handler Class
else if (command.equals("bitcoin-scheduled-alert-start")) {
ScheduledAlert scheduledAlert = new ScheduledAlert(event.getTextChannel());
scheduledAlert.start(LocalTime.of(21, 0, 0));
event.reply("The daily closing price of Bitcoin will be displayed from now on!").queue();
} else if (command.equals("bitcoin-scheduled-alert-stop")) {
ScheduledAlert disabledScheduledAlert = new ScheduledAlert(event.getTextChannel());
disabledScheduledAlert.stop();
event.reply("The current scheduled alert has been stopped!").queue();
}
public class ScheduledAlert {
private final Timer timer;
private TimerTask task;
private final TextChannel channel;
private final String symbol;
public ScheduledAlert(TextChannel channel) {
this.channel = channel;
this.symbol = "BTC";
this.timer = new Timer();
}
public void start(LocalTime time) {
if (task != null) {
task.cancel();
}
task = new TimerTask() {
@Override
public void run() {
System.out.println("Started");
CryptoPrice cmcApi = new CryptoPrice(symbol);
double price = cmcApi.getPrice(symbol);
NumberFormat formatter = NumberFormat.getCurrencyInstance(Locale.US);
String priceString = formatter.format(price);
System.out.println((priceString));
channel.sendMessage("The closing price of Bitcoin is " + priceString).queue();
}
};
ZonedDateTime now = ZonedDateTime.now(ZoneId.of("America/Sao_Paulo"));
ZonedDateTime scheduledTime = ZonedDateTime.of(now.toLocalDate(), time, now.getZone());
if (now.compareTo(scheduledTime) > 0) {
scheduledTime = scheduledTime.plusDays(1);
}
long delay = Duration.between(now, scheduledTime).toMillis();
timer.schedule(task, delay, TimeUnit.DAYS.toMillis(1));
}
public void stop() {
if (task != null) {
task.cancel();
task = null;
System.out.println("Stopped");
}
}
}
Is there anything else you would like to know or translate?
英文:
Mainly, I'm coding a discord bot that gets the price of any crypto (integrated with CoinMarketCapAPI) and returns the price to the user. I created a command that sends the price of Bitcoin on its closing time (12 am GMT or 9pm BRT) when triggered, but when I try to cancel it, the price still shows at given time.
I know what i'm doing wrong, but there's no clear solution in my mind:
When I call the alert class, it creates an object with its own timer, but I can't access the same object on another discord command, I have to create a different one.
//Command Handler Class
else if (command.equals("bitcoin-scheduled-alert-start")) {
ScheduledAlert scheduledAlert = new ScheduledAlert(event.getTextChannel());
scheduledAlert.start(LocalTime.of(21,00, 00));
event.reply("The daily closing price of Bitcoin will be displayed from now on!").queue();
} else if (command.equals("bitcoin-scheduled-alert-stop")) {
ScheduledAlert disabledScheduledAlert = new ScheduledAlert(event.getTextChannel());
disabledScheduledAlert.stop();
event.reply("The current scheduled alert has been stopped!").queue();
}
public class ScheduledAlert { //Bitcoin update at every candle close (12 am GMT [9 pm BRT])
private final Timer timer;
private TimerTask task;
private final TextChannel channel;
private final String symbol;
public ScheduledAlert(TextChannel channel) {
this.channel = channel;
this.symbol = "BTC";
this.timer = new Timer();
}
public void start(LocalTime time) { //Getting the time from BotCommands parameter
// Cancel the task if it is already scheduled (NOT WORKING)
if (task != null) {
task.cancel();
}
task = new TimerTask() { //Start TimerTask
@Override
public void run() {
System.out.println("Started");
CryptoPrice cmcApi = new CryptoPrice(symbol); //Get Bitcoin price
double price = cmcApi.getPrice(symbol);
NumberFormat formatter = NumberFormat.getCurrencyInstance(Locale.US);
String priceString = formatter.format(price);
System.out.println((priceString));
channel.sendMessage("The closing price of Bitcoin is " + priceString).queue();
}
};
ZonedDateTime now = ZonedDateTime.now(ZoneId.of("America/Sao_Paulo")); //Sync date with time zone
ZonedDateTime scheduledTime = ZonedDateTime.of(now.toLocalDate(), time, now.getZone());
if (now.compareTo(scheduledTime) > 0) {
scheduledTime = scheduledTime.plusDays(1); //If the command has been triggered after time in LocalTime, set it to next day at the set time
}
long delay = Duration.between(now, scheduledTime).toMillis();
timer.schedule(task, delay, TimeUnit.DAYS.toMillis(1));
}
public void stop() {
if (task != null) {
task.cancel();
task = null;
System.out.println("Stopped");
}
}
Is there a way to access that same object?
答案1
得分: 0
你可以使用Map来将创建的ScheduledAlert
实例映射到某个唯一标识符。
如果我假设文本频道包含某个唯一且恒定的标识符(我的意思是你永远不会为相同的频道获得不同的标识符),你可以使用Map<String, ScheduledAlert>
,其中键是event.getTextChannel().getId()
。
英文:
You could use a Map to keep created ScheduledAlert
instances mapped to some unique identifier.
If i assume that text channel contains some unique and constant identifier (i mean you will never get different id for the same channel), you can use Map<String, ScheduledAlert>
, where keys are event.getTextChannel().getId()
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论