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);
}
};
Nie był wielkim fanem nietestowanego kodu, ale został zmuszony do oddania głosu za sprawdzenie 'isPopupTrigger()' - good call. –
Tak, to działa.Dzięki ! – VaclavDedik
@Vena, @Andrew Thompson: Nie ma za co. –