Использование ActionListener в одном классе для запуска таймера в другом классе
-
07-07-2019 - |
Вопрос
У меня есть класс (моделирование), который создает экземпляр другого класса (GUI). Внутри графического интерфейса класса есть кнопка (запуск), к которой прикреплен прослушиватель действий.
Мне нужен этот список действий, чтобы запустить таймер в симуляции, но я не могу понять, как это сделать.
Код в моделировании класса:
public class Simulation{
private static JFrame frame;
private static GUI control;
public static Integer xcontrol = 100, ycontrol = 100;
public Timer timer;
public int steps;
public static void main(String[] args) {
Simulation sim = new Simulation ();
}
public Simulation() {
frame = new JFrame("Action Listener Test");
frame.setLayout(new BorderLayout(1,0));
control = new GUI (xcontrol, ycontrol);
frame.getContentPane().add(control , BorderLayout.CENTER);
frame.setResizable(false);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public void StartTimer() {
timer.start();
System.out.println("It worked!");
}
Код в графическом интерфейсе класса:
panel1.add(button1a);
button1a.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent event) {
Simulation.StartTimer();
}
} );
Ошибка, которую Eclipse сообщает мне, заключается в том, что для " Simulation.timer.start (); "
Невозможно сделать статическую ссылку на нестатический метод StartTimer () из типа Simulation.
Однако метод StartTimer () не может быть статическим, так как это, кажется, нарушает таймер ...
Любая помощь будет принята с благодарностью.
Решение
Передайте this
в качестве аргумента конструктору GUI
.
В общем, лучше избегать таких циклических ссылок. И GUI
, и Simulator
становятся зависимыми друг от друга. Суть решения состоит в том, чтобы отделить GUI от интересного поведения, специфичного для предметной области.
(Кстати: я бы настоятельно не использовал статические переменные для чего-либо, кроме констант. Также избегайте непубличных переменных экземпляра. Но указывайте на то, что не следует расширять JFrame
!)
Для предотвращения многопоточности нужно добавить несколько отвратительных шаблонов.
public static void main(final String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() { public void run() {
Simulation sim = new Simulation();
}});
}
Другие советы
Я хотел бы, чтобы ваш класс графического интерфейса отображал кнопку с помощью метода getButton (), а затем после создания объекта графического интерфейса ваш класс Simulation может добавить свой собственный ActionListener к кнопке, например, control.getButton (). addActionListener (новый ActionListener () ... и т. д.