How do I remove listeners according to the state of the component?

1

I have a JLabel that receives an event, and would like to disable this event when the component is disabled (setEnable = false), and only activate it again when the component is enabled.

What I did:

import java.awt.Cursor;
import java.awt.event.ItemEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.ImageIcon;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class NovoClass extends JFrame {

    private JPanel painel = new JPanel();

    public NovoClass() {
        setSize(200, 150);
        ImageIcon image = new ImageIcon(getClass().getResource("/imagens/botãoExcluir.png"));
        JLabel imagelabel = new JLabel(image);
        JCheckBox check = new JCheckBox("Enable/Disable");

        imagelabel.addMouseListener(getMouseListener());
        imagelabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
        painel.add(imagelabel);
        imagelabel.setEnabled(false);
        add(painel);
        painel.add(check);

        check.addItemListener((ItemEvent e) -> {
            if (check.isSelected() == true) {
                imagelabel.setEnabled(true);
                imagelabel.addMouseListener(getMouseListener());
            } else {
                imagelabel.setEnabled(false);
                //retirar evento.
            }
        });

        setVisible(true);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public MouseListener getMouseListener() {

        return new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                JOptionPane.showMessageDialog(null, "Clicou aqui !");
            }
        };
    }

    public static void main(String[] args) {
        NovoClass novo = new NovoClass();
    }
}
    
asked by anonymous 30.07.2017 / 22:20

1 answer

2

A more interesting approach is to filter this directly in the listener, rather than by adding and removing it according to some component status.

To do this, simply recover the component clicked and check if it is active, if yes, displays the alert, if not, do nothing. Your example would look like this (look at method getMouseListener() ):

import java.awt.event.ItemEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.ImageIcon;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class NovoClass extends JFrame {

    private JPanel painel = new JPanel();

    public NovoClass() {
        setSize(200, 150);
        ImageIcon image = new ImageIcon(getClass().getResource("/imagens/botãoExcluir.png"));
        JLabel imagelabel = new JLabel(image);
        JCheckBox check = new JCheckBox("Enable/Disable");

        imagelabel.addMouseListener(getMouseListener());
        imagelabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
        painel.add(imagelabel);
        imagelabel.setEnabled(false);
        add(painel);
        painel.add(check);

        check.addItemListener((ItemEvent e) -> {
            if (check.isSelected() == true) {
                imagelabel.setEnabled(true);
            } else {
                imagelabel.setEnabled(false);
                //retirar evento.
            }
        });

        setVisible(true);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public MouseListener getMouseListener() {

        return new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {

                JComponent comp = (JComponent) e.getSource();

                if(comp.isEnabled()){
                    JOptionPane.showMessageDialog(null, "Clicou aqui !");
                }
            }
        };
    }

    public static void main(String[] args) {

        SwingUtilities.invokeLater(NovoClass::new);
    }
}

Proving that it really works:

    
30.07.2017 / 23:08