JButton ActionListener не запускается TimerTask - PullRequest
0 голосов
/ 09 марта 2019

Я создаю бота для игры, в которую играю, и создал графический интерфейс, чтобы пользователь бота мог контролировать, активен бот или нет. Чтобы сделать это, я сделал кнопку пуска / остановки, которая установит для переменной значение true. Каждая атака - это отдельный класс, и они расширяют класс TimerTask. Все они имеют в качестве реализации метода run (), который есть у TimerTask, и они просто делают

Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_1); //the ".VK_1" part will be different per class
robot.keyRelease(KeyEvent.VK_1);

В идеале пользователь должен нажимать кнопку, и запускаются TimerTasks, имитирующие нажатия клавиш, которые могут быть атаками в игре. Тем не менее, текст на кнопке не меняется, и TimerTasks никогда не запускаются. У кого-нибудь есть решение для этого? Мой код ниже. Заранее спасибо!

Main-Class:

package AQWGrindBot;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Timer;

public class Main {

    private static boolean playing = false;
    static Timer timer = new Timer();

    public static void main(String[] args) {
        int speed = 1000;
        final boolean[] startVar = {false};

        JFrame frame = new JFrame("AQW Attack Bot");


        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400,100);
        frame.setResizable(false);
        frame.setExtendedState(Frame.MAXIMIZED_BOTH);

        JButton start = new JButton("START");
        start.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (start.isSelected()) {
                    playing = !playing;
                    if (start.getText().equals("START")) {
                        start.setText("STOP");
                        toggleBot(true);
                    } else {
                        start.setText("START");
                        toggleBot(false);
                    }
                }
            }
        });

        frame.setLayout(new FlowLayout());
        frame.add(start);
        frame.setVisible(true);
    }

    private static void toggleBot(boolean check) {
        if (check) {
            timer.schedule(new AQWBotATK1(), 0, 1000);
            timer.schedule(new AQWBotATK3(), 0, 3000);
            timer.schedule(new AQWBotATK4(), 0, 17000);
        } else {
            timer.cancel();
        }
    }
}

P.S. Я нахожусь на macOS Мохаве. Я не знаю, важно ли это, но, очевидно, есть некоторые функции JFrame, которые не работают должным образом на Mac. Пожалуйста, скажите мне, если я пытаюсь реализовать один из них. Также я использую java.awt и объект Robot для имитации нажатия клавиш.

1 Ответ

1 голос
/ 09 марта 2019

У вас есть две основные проблемы, первая из них здесь:

if (start.isSelected()) {

Поскольку start - это JButton, isSelected() никогда не будет истинным, и если вы хотите этот тип функциональности, вам следуетиспользовать JToggleButton или JCheckBox или JRadioButton (последние два, которые идут от JToggleButton) и которые изменяют выбранное состояние при нажатии.

Итак,

JToggleButton start = new JToggleButton("START");

Другой вариант - создать собственное логическое поле для переключения и проверки нажатия кнопки, но тогда вы не получите визуальную обратную связь от кнопки, так какв его состояние.Можно также предположить, что вы используете состояние текста кнопки, полученного через getText()

Другая ваша проблема - использование java.util.Timer и java.util.TimerTask, поскольку это создает код, который потенциально не является Swingбезопасный.Почти всегда лучше использовать javax.swing.Timer или «Swing Timer» при создании таймеров для Swing GUI, поскольку гарантированно вызывается код в ActionListener таймера в потоке событий Swing.

...