Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

swing mouse listeners being intercepted by child components

I have a swing component that has several sub components. What I want to do change some label if the mouse is over any of those components, and then change it to something else if the mouse moves off all of the components. I'm trying to find a more efficient way to do this.

Currently I have mouse listeners over all of the child components that look something like:

class AMouseListener extends MouseAdapter {
    private boolean mouseOver;
    mouseEntered(MouseEvent e) { mouseOver = true; updateLabel(); }
    mouseExited(MouseEvent e) { mouseOver = false; updateLabel(); }

    void updateLabel() {
       String text = "not-over-any-components";
       // listeners are each of the listeners added to the child components
       for ( AMouseListener listener :listeners ) {
          if ( listener.mouseOver ) {
             text = "over-a-component";
             break;
          }
       }
    }
}

This works, but I feel like there should be a better way to handle this by only handling mouseEntered and mouseExited events on the parent container, but since the child components intercept these events, I'm not sure how to go about doing this (I don't necessarily have control over the child components so I Can't forward the mouse events to the parent event if I wanted to).

like image 745
Jeff Storey Avatar asked Jun 18 '12 21:06

Jeff Storey


1 Answers

For example

enter image description here

enter image description here

import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;

public class TestMouseListener {

    public static void main(String[] args) {
        final JComboBox combo = new JComboBox();
        combo.setEditable(true);
        for (int i = 0; i < 10; i++) {
            combo.addItem(i);
        }
        final JLabel tip = new JLabel();
        tip.setPreferredSize(new Dimension(300, 20));
        JPanel panel = new JPanel();
        panel.add(combo);
        panel.add(tip);
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.add(panel);
        frame.pack();
        frame.setVisible(true);
        panel.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseEntered(MouseEvent e) {
                tip.setText("Outside combobox");
            }

            @Override
            public void mouseExited(MouseEvent e) {
                Component c = SwingUtilities.getDeepestComponentAt(
                   e.getComponent(), e.getX(), e.getY());
                // doesn't work if you move your mouse into the combobox popup
                tip.setText(c != null && SwingUtilities.isDescendingFrom(
                   c, combo) ? "Inside combo box" : "Outside combobox");
            }
        });
    }

    private TestMouseListener() {
    }
}
like image 175
mKorbel Avatar answered Oct 28 '22 12:10

mKorbel