Peter L.
Peter L.

Reputation: 157

Remove ActionListener from a class

i'm having some problems with actionlisteners and after some search i can't find anything about this here.

So i have a class "OctetsGraph" that extends JPanel and represents a graph, and another class called "DataGenerator" that implements ActionListener. DataGenerator is suposed to run everey X milisecond and add new data to a dataset that the graph updates from.

DataGenerator(int interval) 
        {
            super(interval, null);
            addActionListener(this);
        }

On the form i draw the graph on, i have a list, and each element on that list is suposed to have a "OctetsGraph". Renewing the graphs everytime i change a selected object is no problem. I have a "OctetsGraph" on the start of the program that i just set to null, and then create another "OctetsGraph" when selecting the other element. Problem is, the actionListener associated with it are still running...

I thought that the actionListneres would simply stop when setting the OctetsGraph object to null but they don't. So how can i solve this?

This is my list mouse pressed event that sets a new octet graph and a new action listner to the new object. What am i doing wrong?

private void jList1MousePressed(java.awt.event.MouseEvent evt) {                                    

   this.panel = new OctetsGraph(60000);

   jPanel2.removeAll();

   javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
   jPanel2.setLayout(jPanel2Layout);
   jPanel2Layout.setHorizontalGroup(
        jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
            .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, 20)
            .addComponent(panel)
            .addGap(20, 20, 20))
    );
    jPanel2Layout.setVerticalGroup(
        jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
        .addGroup(jPanel2Layout.createSequentialGroup()
            .addGap(20, 20, 20)
            .addComponent(panel)
            .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, 20))
    );

   jPanel2.revalidate();
   jPanel2.repaint();

    //Listener that fetches data every second
    panel.new DataGenerator(1000).start();
}

Is there a way where i can maybe remove the actionListeners active on "panel"?

Thank you in advance

Upvotes: 0

Views: 397

Answers (1)

camickr
camickr

Reputation: 324128

DataGenerator is suposed to run everey X milisecond and add new data to a dataset that the graph updates from.

So you should be using a Swing Timer to schedule the event.

Then you need to add a method to your OcetsGraph class, something like stopTimer(). (Maybe you also need a startTimer() method?)

I thought that the actionListneres would simply stop when setting the OctetsGraph object to null

Instead of setting the object to null, you invoke the stopTimer() method on the object. Once the Timer is stopped events will no longer be generated so processing will stop.

Edit:

First learn how to start/stop a Timer. Then when you understand the basic you modify your real application code:

import java.awt.*;
import java.awt.event.*;
import java.util.Date;
import javax.swing.*;

public class SSCCE extends JPanel implements ActionListener
{
    private Timer timer;
    private JLabel label = new JLabel("Press Start");

    public SSCCE()
    {
        setLayout( new BorderLayout(10, 10) );
        add(label, BorderLayout.PAGE_START);


        JButton start = new JButton("Start");
        start.addActionListener( new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                startTimer();
            }
        });
        add(start, BorderLayout.LINE_START);

        JButton stop = new JButton("Stop");
        stop.addActionListener( new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                stopTimer();
            }
        });
        add( stop );
        add(stop, BorderLayout.LINE_END);

        timer = new Timer(1000, this);
    }

    @Override
    public void actionPerformed(ActionEvent e)
    {
        label.setText( new Date().toString() );
    }

    private void startTimer()
    {
        timer.start();
    }

    private void stopTimer()
    {
        timer.stop();
    }

    private static void createAndShowGUI()
    {
        JFrame frame = new JFrame("SSCCE");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new SSCCE());
        frame.pack();
        frame.setLocationByPlatform( true );
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater( () -> createAndShowGUI() );
/*
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowGUI();
            }
        });
*/
    }
}

Edit 2:

If you need a reference then create a reference:

//panel.new DataGenerator(1000).start();
timer = panel.new DataGenerator(1000);
timer.start();

Of course the "timer" variable would need to be an instance variable of the class so you can later reference it. How you manage this is up to you. I can provide specific details based on the information provided.

Upvotes: 1

Related Questions