Utilizzo di un ActionListener in una classe per avviare un timer in un'altra classe
-
07-07-2019 - |
Domanda
Ho una classe (simulazione) che crea un'istanza di un'altra classe (GUI). All'interno della GUI della classe è presente un pulsante (start) a cui è associato un listener di azioni.
Ho bisogno di questo listener d'azione per avviare un timer in simulazione, ma non riesco a capire come farlo.
Simulazione codice in classe:
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!");
}
Codice nella GUI di classe:
panel1.add(button1a);
button1a.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent event) {
Simulation.StartTimer();
}
} );
L'errore che Eclipse mi dice che c'è, è che per " Simulation.timer.start (); " :
Impossibile fare un riferimento statico al metodo non statico StartTimer () dal tipo Simulation.
Tuttavia, il metodo StartTimer () non può essere statico in quanto sembra interrompere il timer ...
Qualsiasi aiuto sarebbe molto apprezzato.
Soluzione
Passa this
come argomento al costruttore GUI
.
In generale è meglio evitare tali riferimenti ciclici. Sia GUI
che Simulator
diventano dipendenti l'uno dall'altro. L'essenza della soluzione è quella di separare la GUI dall'interessante comportamento specifico del dominio.
(A proposito: eviterei fortemente l'uso di variabili statiche per qualsiasi cosa diversa dalle costanti. Eviterei anche variabili di istanza non private. Ma punta a non estendere JFrame
!)
Esistono alcune orribili placche da caldaia che dovresti aggiungere per impedire il multithreading.
public static void main(final String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() { public void run() {
Simulation sim = new Simulation();
}});
}
Altri suggerimenti
Quello che vorrei fare è che la tua classe GUI esponga il pulsante tramite un metodo getButton (), quindi dopo aver creato l'oggetto GUI, la tua classe Simulation può aggiungere il proprio ActionListener al pulsante, ad es. control.getButton (). addActionListener (new ActionListener () ... ecc.