ここに私の問題があります:私はjListとポップアップメニューを持っています。 jListを右クリックすると、ポップアップメニューが表示されます。問題は、マウスが指しているjListアイテムが選択されないことです。そして、私はそれをしてもらいたいのです。リスト内の項目にカーソルを合わせて右ボタンを押すと、2つのことが起こります。クリックした項目を選択して、ポップアップメニューを表示します。
私はこれを試しました:
jLists.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
jList.setSelectedIndex(jList.locationToIndex(e.getPoint()));
}
});
jList.setComponentPopupMenu(jPopupMenu);
ただし、ポップアップメニューのみが表示されます。この行を削除した場合:
jList.setComponentPopupMenu(jPopupMenu);
次に、右クリックで選択が機能します(ただし、ポップアップメニューは表示されません)。
では、これら2つの機能(両方)を機能させるための最良の方法は何だと思いますか?
私の英語に感謝し、申し訳ありません。
setComponentPopupMenu
は行わないでください。 MouseAdapter
で次の手順を実行します。
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
}
}
これはうまくいくはずです。
EDIT:一部のプラットフォームではマウスを押すとポップアップが表示されるため、コードはpress
イベントとrelease
イベントの両方をチェックするようになりました。その他のリリース時。詳細については、 Swingチュートリアル を参照してください。
引き続きsetComponentPopupMenu
を使用する場合(クロスプラットフォームの方法でポップアップのマウスとキーボードの呼び出しを処理するので便利です)、JPopupMenu.show(Component, int, int)
をオーバーライドして適切な行を選択できます。
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
もオーバーライドしない場合)、JPopupMenu.show
で取得したx、yの位置がコンポーネントの中点になることに注意してください。 。この場合、すでに選択範囲がある場合は、選択範囲を変更したくないでしょう。
キーボードとマウスの呼び出しの問題を解決するために私が思いついた解決策は、コンポーネントのクライアントプロパティを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
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);
}
};