2009-11-12 3 views
1

JPanel에서 mouseListener에 문제가 있습니다. JPanel에 이미지 (크기 600 x 600)가 포함 된 JLabel을 추가하고 JPanel에 mouseListener를 추가합니다.JPanel에서 mouseListener 문제

나는 이미지를 클릭 할 때마다 이미지가 다른 이미지로 바뀌고 정상적으로 작동합니다. 그러나 문제는 이미지의 오른쪽이나 가운데를 클릭 할 때만 이미지가 다른 이미지로 변경된다는 것입니다. 상단 또는 왼쪽을 클릭해도 이미지가 변경되지 않습니다. 이것은 나를 혼란스럽게 만든다. 이미지 디스플레이 내의 모든 곳을 클릭하면 이미지가 다른 이미지로 변경되기를 원합니다.

private final int SECOND= 1; 
private final int FIRST = 0; 
int imageCounter = 0; 

JLabel picture; 
JPanel panel; 

... 

private mainLayout() { 
    GridBagLayout m = new GridBagLayout(); 
    Container c = (Container)getContentPane(); 
    GridBagConstraints con; 
    c.setLayout (m); 

    picture = new JLabel(); 
    picture.setIcon(getImages(myImage.get(imageCounter).get(FIRST))); //first Image 

    panel = new JPanel();  
    con = new GridBagConstraints(); 
    con.anchor=GridBagConstraints.CENTER; 
    con.gridy = 1; con.gridx = 0;  
    m.setConstraints(panel, con); 
    c.add(panel); 
    panel.add(picture); //add the pictures 

    panel.addMouseListener(l); 
    .... 
} 

MouseListener l = new MouseAdapter(){ 
    public void mouseClicked (MouseEvent e) 
    { 
    Point p = e.getPoint(); 
    if((panel.getBounds().contains(p)) 
     picture.setIcon(getImages(myImage.get(imageCounter).get(SECOND))); 
    } 
}; 
+0

JPanel 대신 JLabel에 리스너를 추가하려고 했습니까? – nandokakimoto

+0

고맙습니다. nandokakimoto ... thats가 내 문제를 해결했습니다 :-) – Jessy

답변

0

실제로 클릭하면 긍정적입니까? 마우스 클릭 이벤트는 마우스를 누르고 똑같은 지점에서 놓으면 시작됩니다. 클릭하는 동안 마우스가 최소한으로 움직이는 경우 이벤트는 시작되지 않습니다.

0

호기심에서 벗어나서 왜 이미지를 표시하는 데 JLabel을 사용하고 있습니까? JPanel을 확장 한 ImagePanel 클래스를 작성하는 것이 더 나을 것입니다. 그리고 paint() 메소드를 오버라이드하여 자신 만의 그림을 만들 수 있습니다. 그런 다음 MouseListeners를 패널에 바로 연결할 수 있습니다. 마우스 좌표가 왼쪽 패널 상단을 기준으로 할 수 있도록

Point p = e.getPoint(); 
if((panel.getBounds().contains(p)) 

마우스 리스너, 패널에 :이 불필요한 코드에있을 수 있습니다 것처럼

+1

-1이 기능이 JLabel에 이미 내장되어 있으면 사용자 지정 구성 요소를 만들고 사용자 지정 그림을 만드는 이유는 무엇입니까? 바퀴를 재발 명하지 마십시오. – camickr

+0

안녕하세요, Seth, jpg 형식으로 이미지를 표시하기 위해 JLabel을 사용했습니다. – Jessy

+0

나는 그것이 당신이 그림 위에 얼마나 많은 컨트롤을 원하는가에 달려 있다고 생각한다. 공정한 점. – Seth

2

문제는 보인다. panel.getBounds()은 부모 컨테이너가 무엇이든 관계없이 패널의 경계를 가져옵니다.

마우스 이벤트가 매우 이상하게 작동한다는 점은 주목할 가치가 있습니다. 그들은 마우스 리스너가 부착 된 구성 요소에 충돌 할 때까지 "거품을 일으키며"거품을냅니다. 따라서 마우스 수신기를 추가하면 실제로 구성 요소의 동작이 변경됩니다. 부모에게 리스너를 추가하면 구성 요소가 설정되는 정확한 방법 (임의로 변경 될 수 있음)에 따라 이벤트가 누락 될 수 있습니다. 이 문제를 해결하는 데는 여러 가지 방법이 있지만 그 중 좋은 것은 없습니다.

2

내가 겪은 문제는 이전 포스터와 마찬가지로 계층 구조에서 이벤트가 맴돌고있는 것과 같습니다. Camickr의 답변과 관련하여 결과를 알고있는 한 JPanel 또는 JLabel을 확장해도 실제로 문제가되지 않습니다. JPanel은 더 많은 기능을 제공하며 이미 많은 유용한 기능을 갖추고 있습니다. 그러나 다음과 같은 간단한 예를 들어 보겠습니다.

JPanel이 포함 된 전화 번호는 JParent입니다. JParent에는 전용 마우스 리스너 세트가 있습니다.

JParent에는 JChild이라는 구성 요소에 자식 JPanel이 포함되어 있습니다. JChild에는 자체 마우스 수신기 세트가 있습니다.

JChild이 아닌 곳을 클릭하면 어떻게됩니까? JParent 님의 응답을받습니다. JChild이 표시된 영역을 클릭하면 JChild 님의 마우스 이벤트 만 실행됩니다.

Java 스윙이 다른 양식의 간단한 양식/GUI 그리기 구현에서 사용 된 것과 다른 동작을 할 수 있으므로 디버깅에는 매우주의해야합니다. 이벤트는 기본적으로 원샷이며 가장 낮은 레벨의 구성 요소는 첫 번째 덩어리를 가져옵니다. 어쨌든 부모님의 행사를 시작하려고하면 x/y 좌표는 부모가 아닌 자녀를 기준으로합니다.나는 다른 곳으로 물건을 옮기기 위해 부모에게 특별히 접근해야하기 때문에 나 자신에 대한 좋은 일을 생각해 내려고 노력 중이다.

내가 생각할 수있는 가장 좋은 점은 디버그/생각하는 것이 엉망이 아니라는 것입니다. a) 각 개별 구성 요소에 고유 한 이벤트 집합이 포함되어 있고 '버블 링을 방지하려고합니다. '효과가 작용합니다. b) 부모의 모든 이벤트를 처리하십시오.

좋아요. 어떤 종류의 반응을 원하는지 파악하기 위해 구성 요소 클래스를 확인하는 것과 같은 불쾌한 일을 피하십시오 (예 : 어떤 종류의 마우스 오른쪽 버튼 클릭 메뉴와 같은 것)? 보여 주다).

편집 : 그래서 당신은 내가 발견 한 방법으로 이것을 처리 할 수 ​​있습니다. dispatchEvent 메시지를 사용하여 이벤트를 다시 체인으로 전달할 수 있습니다. 제 경우에는 첫 번째 이벤트를 중얼 거릴 때 (또는 변경) x-y 위치를 부모와 상대적인 것처럼 (오프셋을 사용하여) 보내야합니다. 나는 그것을 수행하는 더 좋은 방법은 모든 개별 구성 요소가 캡슐화 될 수 있기 때문에 전달을 통해서라고 말하고 싶습니다.

관련 문제