|
どこでもとびだすポップアップメニュー JPopupMenu |
||||||
|
||||||
ポップアップメニューは使いにくいと思っていませんか。私は思っていました。 なぜかというと、ポップアップをとびださせるためには、自分でイベント処理をおこなってポップアップメニューを表示させなければいけなかったからです。 以前の方法で書いてみましょう。
ポップアップをさせたいコンポーネントに対してリスナ登録して、イベントが発生したらそれがポップアップさせる条件下を調べて、表示という流れです。
ここでは JTextArea コンポーネントに対してポップアップメニューを出そうとしています。そのために area に対して addMouseListener メソッドをコールしています。ポップアップさせるかどうかは次のように判定します。
MouseEvent クラスにはポップアップさせるかどうかを調べるためのメソッド isPopupTrigger が定義されているので、これを使用します。Windows の場合は右クリックで isPopuTrigger メソッドの戻り値が true になります。 そうしたら、JPopupMenu オブジェクトを表示します。表示させる位置はマウスポインタがある位置にしたほうがいいので、イベントから取得したマウスポインタの位置を使用しています。 たかがポップアップメニューにこれだけのことをしなくてはならないのです。 うーん、面倒くさい。
|
|
|||||
さて、Tiger です。 Tiger では JComponent クラスに setComponentPopupMenu メソッドが新たに定義されました。 これを使えばリスナ登録やイベント処理などなしに簡単にポップアップメニューをつけることができます。 先ほどのサンプルを Tiger の方法で書き直してみましょう。
同じように JTextArea にポップアップをさせます。
えっ、これだけ、と思いませんか。今までの苦労はなんだったんだろう。
|
|
||||||||||||||||||||||||||||||||||||||||||||
簡単になったのはいいのですが、どうもすべての Swing のコンポーネントがポップアップメニューを出せるわけではないようです。 それを確かめるためにこんなサンプルを作ってみました。
主要なコンポーネントに対して setComponentPopupMenu メソッドをコールしています。たとえば JButton に対しては次のようになっています。
これを実行すると次のようになります。 このサンプルで 1 つ 1 つポップアップメニューが表示されるか調べてみました。その結果が次の表です。
JLabel クラスが使えないのは意外でしたが、そんなもんなのでしょうか。JMenuBar クラスで使えないのは逆に当然ですね。
|
|
|||||||
ポップアップメニューを継承するといっても、JPopupMenu クラスを派生させるわけではありません。 GUI ではコンテナとコンポーネントは親子関係にありますが、親が使っているポップアップメニューを子供も使いたいということです。
ポップアップメニューを継承するには JComponent#setInheritsPopupMenu メソッドを使用します。このメソッドは引数が boolean で、true の時に親のポップアップメニューをそのまま使えるようになります。
PopupMenuSample3 クラスの中ではフレームのコンテントペインにポップアップメニューを設定しています。 コンテントペインには JPanel オブジェクトをはり、その中にもう 1 つ JPanel オブジェクトをはり、その中に JButton オブジェクトをはっています。 ところが、上述したように JPanel クラスはポップアップメニューを表示させることができません。 さて、このサンプルでは JButton オブジェクトにポップアップメニューが表示させることはできるのでしょうか。やってみましょう。 なんとできました。でも、JPanel のところではやっぱりポップアップメニューは表示されません。なんか不思議な感じです。
|
|
||||
今までポップアップメニューを使うにはイベント処理をしなくてはいけなかったので面倒だったのが、Tiger ではずいぶんすっきりしてしまいました。 このような改善は大歓迎。今まで面倒だからといって使っていなかった人も、どんどん使ってみましょう。
今回使用したサンプルはここからダウンロードできます。
(Oct. 2004) |
|