Java - MouseListener на JPanel не запускается - PullRequest
0 голосов
/ 13 декабря 2011

У меня есть JPanel с использованием BorderLayout, который состоит из 2 компонентов. A JLabel в NORTH и JList в CENTER.

Я добавил MouseListener на панель и на данный момент закодировал окно сообщения, которое появится на mouseEntered.

Проблема в том, что событие вызывается только в том случае, если курсор входит в область, занятую меткой. Мне нужно, чтобы событие срабатывало, когда мышь входит во всю область панелей.

Есть идеи, что я делаю не так?

Редактировать: код для создания панели

JPanel p = new JPanel();
p.setLayout(new BorderLayout());
p.add(new JLabel("Label"), BorderLayout.NORTH);
p.add(new JList(), BorderLayout.CENTER);
p.addMouseListener(new MouseListener(){
        @Override
        public void mouseEntered(MouseEvent e) {
            JOptionPane.showMessageDialog(null, "Entered Panel");
        }
        //Other overriden methods
        ...
    });

Ответы [ 3 ]

4 голосов
/ 13 декабря 2011

Начиная с jdk7, вы можете украсить любой JComponent с помощью JLayer и зарегистрировать слой, чтобы получать все события, отправленные его дочерним элементам, что-то вроде

    JTable list = new JTable(30, 5);
    JComponent panel = new JPanel(new BorderLayout());
    panel.setBorder(BorderFactory.createEmptyBorder(50, 50, 50, 50));
    panel.add(new JLabel("we are label"));
    panel.add(new JScrollPane(list));
    LayerUI<JComponent> ui = new LayerUI<JComponent>() {

        @Override
        protected void processMouseEvent(MouseEvent e, JLayer<? extends JComponent> l) {
            if (e.getID() == MouseEvent.MOUSE_ENTERED) {
                System.out.println(e.getSource().getClass() + " at " + e.getPoint());
            }
        } 
    };
    JLayer<JComponent> layer = new JLayer<JComponent>(panel, ui);
    layer.setLayerEventMask(AWTEvent.MOUSE_EVENT_MASK );   

Обратите внимание, что это внутренне обрабатывается AWTEventListener, как и решение, предложенное в блоге Роба. Преимущество решения Роба в том, что оно будет работать и в изолированной среде (поскольку у базового класса JLayer есть необходимые привилегии).

Для более ранних версий jdk существует проект JXLayer (часть SwingLabs), который является прямым предшественником нового базового класса. У него нет проблем с разрешениями, потому что он внутренне использует немного другой подход для захвата всех событий.

2 голосов
/ 13 декабря 2011

Я думаю, что проблема в том, что JList является компонентом, который получает событие мыши. Я не уверен, что это лучший способ справиться с проблемой, но не могли бы вы добавить того же слушателя мыши в JList?

0 голосов
/ 13 декабря 2011

Любой компонент, имеющий MouseListener, получит событие мыши и не будет передано на панель.

Вы можете добавить MouseListener для каждого компонента, но что, если дизайн вашей панели изменится. Не забывайте, что у вас, вероятно, есть полоса прокрутки справа от вашего JList, поэтому, если пользователь войдет в панель справа, событие не будет сгенерировано, пока мышь не переместится через полосу прокрутки в список.

Вместо этого вы можете рассмотреть возможность использования Global Event Listener для прослушивания событий mouseEntered. Затем, когда событие получено, вам нужно проверить, является ли источник события самой панелью или дочерним компонентом панели. Вы должны быть в состоянии использовать:

SwingUtiltities.isDescendingFrom(...)

, чтобы помочь с этой проверкой.

...