2011-05-15 44 views
21

여기 내 문제가 있습니다 : jList와 팝업 메뉴가 있습니다. jList를 마우스 오른쪽 버튼으로 클릭하면 팝업 메뉴가 표시됩니다. 문제는 마우스가 가리키는 jList 항목이 선택되지 않는다는 것입니다. 그리고 그렇게하고 싶습니다. 목록의 항목을 가리키고 오른쪽 단추를 누르면 두 가지 일이 발생합니다. 클릭 한 항목을 선택하고 팝업 메뉴를 표시하십시오. 자바 스윙 팝업 메뉴와 jlist

나는이 시도 :

jLists.addMouseListener(new MouseAdapter() { 

    @Override 
    public void mousePressed(MouseEvent e) { 
      jList.setSelectedIndex(jList.locationToIndex(e.getPoint())); 
    } 
}); 

jList.setComponentPopupMenu(jPopupMenu); 

을하지만 그것은 단지 팝업 메뉴를 보여줍니다. 내가이 줄을 삭제하면 :

jList.setComponentPopupMenu(jPopupMenu); 

다음 선택 작업을 마우스 오른쪽 단추로 클릭 (단, 팝업 메뉴가 표시되지 않습니다).

그럼 두 가지 기능 (둘 다)을 작동시키는 가장 좋은 방법은 무엇이라고 생각하십니까?

영어로 죄송합니다.

답변

27

setComponentPopupMenu하지 마십시오.

public void mousePressed(MouseEvent e) {check(e);} 
public void mouseReleased(MouseEvent e) {check(e);} 

public void check(MouseEvent e) { 
    if (e.isPopupTrigger()) { //if the event shows the menu 
     jList.setSelectedIndex(jList.locationToIndex(e.getPoint())); //select the item 
     jPopupMenu.show(jList, e.getX(), e.getY()); //and show the menu 
    } 
} 

이 작동합니다 다음 MouseAdapter에서 다음을 수행합니다.

편집 : 일부 플랫폼 때 팝업 마우스 프레스 릴리스에 대한 몇 가지 다른를 표시하기 때문에 코드는 이제 모두 pressrelease 이벤트를 확인. 자세한 내용은 the Swing tutorial을 참조하십시오.

+0

테스트되지 않은 코드의 팬은 아니지만'isPopupTrigger()'확인을위한 투표를 강요 당했다. –

+0

예, 작동합니다.감사 ! – VaclavDedik

+0

@Vena, @ Andrew Thompson : 천만에. –

9

setComponentPopupMenu (계속해서 크로스 플랫폼 방식으로 팝업의 마우스 및 키보드 호출을 처리하므로 좋음) JPopupMenu.show(Component, int, int)을 덮어 쓰면 해당 행을 선택할 수 있습니다. 당신의 팝업이있는 x를 키보드를 통해 호출 (당신은 또한 당신의 대상 구성 요소에 getPopupLocation를 오버라이드 (override)하지 않는) 경우, 당신은 JPopupMenu.show 얻을 예 위치는 구성 요소의 중간 될 것

JPopupMenu jPopupMenu = new JPopupMenu() { 
    @Override 
    public void show(Component invoker, int x, int y) { 
     int row = jList.locationToIndex(new Point(x, y)); 
     if (row != -1) { 
      jList.setSelectedIndex(row); 
     } 
     super.show(invoker, x, y); 
    } 
}; 

jList.setComponentPopupMenu(jPopupMenu); 

참고. 이 경우 이미 선택 항목이있는 경우 선택 항목을 변경하지 않으려 고합니다.

키보드 대 마우스 호출 문제를 해결하기위한 해결책은 구성 요소의 클라이언트 속성을 getPopupLocation으로 설정하고 팝업을 표시 할 때 확인하는 것이 었습니다. getPopupLocation에 대한 인수는 키보드를 통해 호출 할 때 null이됩니다. 다음은 핵심 코드입니다 (구성 요소 및 팝업 메뉴에서 사용할 수있는 유틸리티 클래스로 구현되었을 수 있음).

private static final String POPUP_TRIGGERED_BY_MOUSE_EVENT = "popupTriggeredByMouseEvent"; // NOI18N 

public static Point getPopupLocation(JComponent invoker, MouseEvent event) 
{ 
    boolean popupTriggeredByMouseEvent = event != null; 
    invoker.putClientProperty(POPUP_TRIGGERED_BY_MOUSE_EVENT, Boolean.valueOf(popupTriggeredByMouseEvent)); 
    if (popupTriggeredByMouseEvent) 
    { 
     return event.getPoint(); 
    } 
    return invoker.getMousePosition(); 
} 

public static boolean isPopupTriggeredByMouseEvent(JComponent invoker) 
{ 
    return Boolean.TRUE.equals(invoker.getClientProperty(POPUP_TRIGGERED_BY_MOUSE_EVENT)); 
} 

그런 다음 구성 요소에 getPopupLocation를 오버라이드 (override) :

@Override 
public Point getPopupLocation(MouseEvent event) 
{ 
    return PopupMenuUtils.getPopupLocation(this, event); 
} 

팝업 위치에있는 행을 선택 (또는 어떤 조치가 이해 할 수 있는지 여부를 결정하기 위해 JPopupMenu.show의 재정에 isPopupTriggeredByMouseEvent 전화

JPopupMenu jPopupMenu = new JPopupMenu() { 
    @Override 
    public void show(Component invoker, int x, int y) { 
     int row = jList.locationToIndex(new Point(x, y)); 
     if (row != -1 && PopupMenuUtils.isPopupTriggeredByMouseEvent((JComponent) invoker)) { 
      jList.setSelectedIndex(row); 
     } 
     super.show(invoker, x, y); 
    } 
}; 
+1

누락 부분 = 'JList의 새로운 JList의 () { @Override 공개 getPopupLocation 포인트 (이벤트 된 MouseEvent) { 복귀 JListUtility.getPopupLocation (이 이벤트)이고; } } ' – palindrom

+0

감사합니다. @palindrom. 나는'getPopupLocation' 사용법을 포함하도록 답변을 업데이트했습니다. –