2013-12-19 3 views
5

У меня проблема с прослушивателями мыши, добавленными к двум различным панелям один поверх другого. Оба они используют методы mouseEntered() и mouseExited().Несколько панелей с MouseListener друг на друга

Ожидаемый результат теста кода сильфона:

  • Когда я парить на раме красный прямоугольник должен быть сделан видимым
  • Когда я парить на красной прямоугольника в кадре он должен повернуться синий.
  • Когда моя мышь покидает теперь синий прямоугольника (но все еще внутри кадра) он должен повернуть красный
  • Когда моя мышь покидает кадр целиком теперь красного прямоугольник не должен быть виден

Если я пытаюсь переместить указатель мыши на цветной прямоугольник, он продолжает мигать от видимого до невидимого. Системная печать показывает, что я имею в виду, она продолжает активировать Mouse Entered и Mouse Exited каждый раз, когда я двигаюсь или нажимаю мышью. Есть ли способ предотвратить вызов метода mouseExited() каждый раз, когда я двигаюсь или нажимаю на мышь?

Вот код теста:

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class Sandbox extends JPanel { 

    public static void main(String[] args) { 
     JFrame frame = new JFrame(); 
     frame.setSize(500, 500); 
     frame.add(new Sandbox()); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setVisible(true); 

    } 

    public Sandbox() { 
     super(new BorderLayout()); 

     final JPanel panelA = new JPanel(); 
     panelA.setBackground(Color.red); 
     panelA.setPreferredSize(new Dimension(155, 155)); 
     panelA.setVisible(false); 

     this.add(panelA, BorderLayout.WEST); 

     this.addMouseListener(new MouseAdapter() { 
      @Override 
      public void mouseEntered(MouseEvent e) { 

       System.out.println(" - MOUSE ENTERED "); 
       panelA.setVisible(true); 
      } 

      @Override 
      public void mouseExited(MouseEvent e) { 

       System.out.println(" - MOUSE EXITED "); 
       panelA.setVisible(false); 
      } 

     }); 

     panelA.addMouseListener(new MouseAdapter() { 

      @Override 
      public void mouseEntered(MouseEvent e) { 

       System.out.println(" # MOUSE ENTERED "); 
       panelA.setBackground(Color.blue); 

      } 

      @Override 
      public void mouseExited(MouseEvent e) { 
       panelA.setBackground(Color.red); 
       System.out.println(" # MOUSE EXITED "); 
      } 

     }); 

    } 

} 
+2

+1 вопрос на этой неделе – mKorbel

ответ

2

У вас есть такое поведение, потому что у вас есть 2 слушателей. Когда вы пытаетесь изменить цвет на blue, он изменился, но из первого слушателя выполнил panelA.setVisible(false);, и вы этого не видите.

Вы можете исправить это в следующем виде: изменение кода mouseExited() метода в первом слушателя:

@Override 
    public void mouseExited(MouseEvent e) { 
     if(!panelA.contains(e.getPoint())){ 
      panelA.setVisible(false); 
     } 
     System.out.println(" - MOUSE EXITED "); 
    } 

EDIT: еще один фикс для выхода из кадра при наведении курсора мыши на panelA: изменение mouseExited для второго слушателя:

@Override 
public void mouseExited(MouseEvent e) { 
    panelA.setBackground(Color.red); 
     if (!Sandbox.this.contains(e.getPoint())) { 
      panelA.setVisible(false); 
     } 

     System.out.println(" # MOUSE EXITED "); 
    } 
@Override 
public void mouseExited(MouseEvent e) { 
    panelA.setBackground(Color.red); 
     if (!Sandbox.this.contains(e.getPoint())) { 
      panelA.setVisible(false); 
     } 

     System.out.println(" # MOUSE EXITED "); 
    } 
+0

сейф может быть с добавлением/удалением (делегировать события from_ только на один MouseListener можно добавить во время выполнения) MouseListener от JFrame до JPanel и наоборот, несколько строк кода более того – mKorbel

Смежные вопросы