5

JPopupMenuアイテムが選択された、メニューが閉じられた、またはsetVisible(false)呼び出されたなどの理由で、アイテムが非表示になったときに通知を受け取りたいです。ここに私のテストコードがあります:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class A extends ComponentAdapter implements Runnable, ActionListener {
    private JButton b;

    public static void main(String[] args) {
        EventQueue.invokeLater(new A());
    }

    public void run() {
        JFrame f = new JFrame("Test");
        b = new JButton("Click me");
        b.addActionListener(this);
        f.add(b);
        f.pack();
        f.setVisible(true);
    }

    public void actionPerformed(ActionEvent e) {
        JPopupMenu pm = new JPopupMenu();
        pm.addComponentListener(this);
        pm.add("Popup...");
        pm.add("...menu!");
        pm.show(b, 10, 10);
    }

    public void componentShown(ComponentEvent e) { System.out.println("componentShown"); }
    public void componentHidden(ComponentEvent e) { System.out.println("componentHidden"); }
}

メニューの操作方法に関係なく、2 つのComponentListenerメソッドはどちらも呼び出されません。何故ですか?私JPopupMenuがいつ隠されているかを知る別の/より良い/正しい方法はありますか?

ありがとう、

キャメロン

4

1 に答える 1

6

JPopupMenu可視性変更イベント用の特別なリスナーがあります。

pm.addPopupMenuListener(new PopupMenuListener() {
    @Override
    public void popupMenuCanceled(PopupMenuEvent e) {
        System.out.println("cancelled");
    }

    @Override
    public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
        System.out.println("vanishing");
    }

    @Override
    public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
        System.out.println("appearing");
    }
});

ただし、メソッド名からわかるように、これらは可視性が変更される前にisVisible()呼び出されるため、イベント ハンドラーのどこかで呼び出す場合は、次のように注意する必要があります。

@Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
    updateMenu();
}

private void updateMenu() {
    if (!menu.isVisible()) { // this won't work!
        // perform some updates
    }
}

ComponentListenerメニューのイベントが消えない理由については、次のように説明できます。

component-hidden および component-shown イベントは、 Component の setVisible メソッドの呼び出しの結果としてのみ発生します。たとえば、コンポーネント非表示のイベントが起動されることなく、ウィンドウがアイコンに縮小される (アイコン化される) 場合があります。

出典: ComponentListener のチュートリアル (非標準的かもしれませんが、馬の口からです。)

JPopupMenuの の実装と併せて考えてみましょうsetVisible:

    public void setVisible(boolean b) {
        // Not supported for MenuComponents
    }

そして、それがどのように起こるかは知っているかもしれませんが、なぜそれが起こるのかはわかりません (正当な理由は何ですか? それはどこに適切に文書化されていますか?)

于 2010-06-14T03:47:46.183 に答える