2011-05-15 24 views
21

tutaj jest mój problem: Mam jList i menu podręczne. Po kliknięciu prawym klawiszem myszy na jList pojawi się menu podręczne. Problem polega na tym, że element jList, na który wskazuje mysz, nie wybierze. I chcę to zrobić. Kiedy wskażę kursor na pozycję na liście i naciśnij prawy przycisk, chcę, aby dwie rzeczy się wydarzyły. Wybierz element, na który kliknąłem i pokaż menu podręczne.Menu podręczne Java swing i jlist

Próbowałem to:

jLists.addMouseListener(new MouseAdapter() { 

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

jList.setComponentPopupMenu(jPopupMenu); 

Ale to tylko pokazuje menu podręczne. Gdybym usunąć tę linię:

jList.setComponentPopupMenu(jPopupMenu); 

następnie prawym przyciskiem myszy wybierz prace (ale menu podręczne nie pokazuje).

Jak myślisz, jaki jest najlepszy sposób, aby te dwie funkcje (obie) zadziałały?

Dzięki i przepraszam za mój angielski.

Odpowiedz

27

Nie rób setComponentPopupMenu. W MouseAdapter wykonaj następujące czynności:

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 
    } 
} 

to powinno działać.

EDIT: Kod sprawdza teraz obie press i release wydarzenia, ponieważ niektóre platformy pokazują, pop-upy, kiedy prasy myszy i niektórych innych na wydaniu. Aby uzyskać więcej informacji, patrz the Swing tutorial.

+0

Nie był wielkim fanem nietestowanego kodu, ale został zmuszony do oddania głosu za sprawdzenie 'isPopupTrigger()' - good call. –

+0

Tak, to działa.Dzięki ! – VaclavDedik

+0

@Vena, @Andrew Thompson: Nie ma za co. –

9

Jeśli chcesz nadal używać setComponentPopupMenu (co jest miłe, ponieważ obsługuje wywołania myszy i klawiatury w popup w sposób między platformami), możesz zastąpić JPopupMenu.show(Component, int, int), aby wybrać odpowiedni wiersz.

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); 

Zauważ, że gdy okienko jest wywoływana za pomocą klawiatury (i nie zastępują getPopupLocation również na swoim komponentu docelowego), X, Y położenie można dostać w JPopupMenu.show będzie środkiem boku komponentu. Jeśli istnieje już wybór w tym przypadku, prawdopodobnie nie chcesz zmieniać wyboru.

Rozwiązaniem, które wpadłem w celu rozwiązania problemu z klawiaturą a wywołaniem myszy było ustawienie właściwości klienta na komponencie po nadpisaniu getPopupLocation, a następnie sprawdzenie go po wyświetleniu wyskakującego okienka. Argument do getPopupLocation będzie null po wywołaniu za pomocą klawiatury. Oto podstawowy kod (być może zaimplementowany w klasie narzędziowej dostępnej dla twojego komponentu i jego menu podręcznego).

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)); 
} 

następnie zastąpić getPopupLocation w swojej części:

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

i nazywają isPopupTriggeredByMouseEvent w ręcznym z JPopupMenu.show w celu ustalenia, czy należy zaznaczyć wiersz w miejscu podręcznego (lub cokolwiek działanie może mieć sens dla element podstawowy):

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

brakującą częścią jest 'jList = new JList () { @Override publiczny punkt getPopupLocation (zdarzenie MouseEvent) { return JListUtility.getPopupLocation (this, event); } }; ' – palindrom

+0

Dzięki, @palindrom. Zaktualizowałem swoją odpowiedź, aby uwzględnić użycie 'getPopupLocation' –