- bonbon
- 会議室デビュー日: 2003/05/30
- 投稿数: 8
|
投稿日時: 2004-02-13 10:25
SwingのJMenuBarを使ってナビゲーションバーを作成しています。
JMenuBarのデフォルトの動きは
1)JMenuBarのJMenuをクリックするとJPopupMenuが表示される。
2)異なるJMenuにマウスが入るとJPopupMenuが表示される。
3)3)のJMenuをクリックするとJPopupMenuが閉じる。
となっています。
この動きを
4)JMenuにマウスが入るとJPopupMenuが表示される。
5)JMenuからマウスが出るとJPopupMenuが閉じる。
という動きに変えたいと思っています。
MouseAdapter、addMouseListener、mouseEntered又はmouseExitを
使えば、できそうなのですがaddMouseListenerを行う対象オブジェクトを
はじめ、具体策がわかりません。
お手数ですがご教示よろしくお願いします。
|
- Wata
- ぬし
- 会議室デビュー日: 2003/05/17
- 投稿数: 279
|
投稿日時: 2004-02-13 13:26
こんにちは、Wataです。
なぜこのような挙動が必要なのかわかりませんが、
引用: |
|
bonbonさんの書き込み (2004-02-13 10:25) より:
4)JMenuにマウスが入るとJPopupMenuが表示される。
|
はJMenuにMouseListenerを追加して、mouseEnteredイベントを拾って、
JMenu#processMenuDragMouseEvent()をコールすることによってできましたよ。
# MenuDragMouseEventは自作します。
5)の消すほうはあまり上手い方法は思いつきませんが、
多分、JMenu#getPopupMenu()で取得したポップアップメニューに
リスナーを追加することになると思います。
|
- bonbon
- 会議室デビュー日: 2003/05/30
- 投稿数: 8
|
投稿日時: 2004-02-13 18:13
ご回答ありがとうございます。
早速、作成してみます。
このような挙動にしたいのはJMenuにマウスを入れるとJPopupMenuが表示され、
JMenuからマウスを入れるとJPopupMenuが閉じるという挙動の方がユーザーは分
かり易いと思うからです。
そもそもナビゲーションバーを作るなら、Javaではなく、JavaScriptで十分
かもしれませんが。
現在、誰でもPARAMの中を変更するだけでナビゲーションメニューを変更できないか
ということにトライ中です。
|
- さくらば
- 大ベテラン
- 会議室デビュー日: 2002/11/12
- 投稿数: 145
|
投稿日時: 2004-02-13 18:18
こんにちは、さくらばです。
引用: |
|
bonbonさんの書き込み (2004-02-13 10:25) より:
4)JMenuにマウスが入るとJPopupMenuが表示される。
5)JMenuからマウスが出るとJPopupMenuが閉じる。
という動きに変えたいと思っています。
MouseAdapter、addMouseListener、mouseEntered又はmouseExitを
使えば、できそうなのですがaddMouseListenerを行う対象オブジェクトを
はじめ、具体策がわかりません。
|
単に JMenu に MouseListener をつけるだけではだめです。表示される
ポップアップメニューも MouseListener を add するようにします。
ただ、面倒なのがメニューからポップアップメニューにマウスカーソルを
動かすときに、メニューにもポップアップメニューにも含まれない場所が
あるということです。ここを通る間にイベント処理をさせないように工夫
が必要でした。
というわけで、こんなサンプルを作ってみました。Win XP で J2SE 1.4.2_03
と J2SE 1.5 beta で動作チェックしています。
ちょっと長いのですが、ご容赦を。
コード: |
|
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.MenuElement;
import javax.swing.MenuSelectionManager;
import javax.swing.SwingUtilities;
public class MenuSample {
public MenuSample() {
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(100, 100, 200, 100);
JMenuBar bar = new JMenuBar();
MenuCreator creator = new MenuCreator("File");
JMenu menu = creator.getMenu();
menu.add(new JMenuItem("Open"));
menu.add(new JMenuItem("Save"));
menu.add(new JMenuItem("Exit"));
bar.add(menu);
creator = new MenuCreator("Edit");
menu = creator.getMenu();
menu.add(new JMenuItem("Copy"));
menu.add(new JMenuItem("Cut"));
menu.add(new JMenuItem("Paste"));
bar.add(menu);
frame.setJMenuBar(bar);
frame.setVisible(true);
}
class MenuCreator {
private MenuSelectionManager mng;
private JMenu menu;
private boolean flag;
public MenuCreator(String title) {
mng = MenuSelectionManager.defaultManager();
menu = new JMenu(title);
menu.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent event) {
// メニューにマウスが入ったらポップアップメニューを表示
// MenuSelectionManager を使用したのはクリックされた時の
// 処理と同じにするため
MenuElement[] me = new MenuElement[3];
me[0] = (MenuElement)menu.getParent();
me[1] = menu;
me[2] = menu.getPopupMenu();
mng.setSelectedPath(me);
}
public void mouseExited(MouseEvent event) {
// メニューからポップアップメニューや他のメニューに遷移した時の
// ことを考えて invokeLater を使用
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// 他のメニューが選択状態だったらそのまま
JMenuBar parent = (JMenuBar)menu.getParent();
int count = parent.getMenuCount();
for (int i = 0; i < count; i++) {
JMenu mm = parent.getMenu(i);
if (mm.isSelected() && mm != menu) {
return;
}
}
// ポップアップメニューが表示されていたら
// ポップアップメニューを閉じて、
// 選択状態を非選択状態にする
if (!flag) {
MenuElement[] me = new MenuElement[2];
me[0] = (MenuElement)menu.getParent();
mng.setSelectedPath(me);
}
}
});
}
});
JPopupMenu popup = menu.getPopupMenu();
popup.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent event) {
flag = true;
}
public void mouseExited(MouseEvent event) {
// ポップアップメニューからマウスが出たら
// ポップアップメニューを閉じて、
// メニューを選択状態から非選択状態にする
JPopupMenu popup = (JPopupMenu)event.getSource();
Point point = event.getPoint();
if (!popup.contains(point.x, point.y)) {
MenuElement[] me = new MenuElement[1];
me[0] = (MenuElement)menu.getParent();
mng.setSelectedPath(me);
flag = false;
}
}
});
}
public JMenu getMenu() {
return menu;
}
}
public static void main(String[] args) {
new MenuSample();
}
}
|
|
- Wata
- ぬし
- 会議室デビュー日: 2003/05/17
- 投稿数: 279
|
投稿日時: 2004-02-13 19:18
引用: |
|
さくらばさんの書き込み (2004-02-13 18:18) より:
こんにちは、さくらばです。
単に JMenu に MouseListener をつけるだけではだめです。表示される
ポップアップメニューも MouseListener を add するようにします。
ただ、面倒なのがメニューからポップアップメニューにマウスカーソルを
動かすときに、メニューにもポップアップメニューにも含まれない場所が
あるということです。ここを通る間にイベント処理をさせないように工夫
が必要でした。
(後略)
|
うーむ。勉強になります。
ところで、JMenuを入れ子にする場合はもう少し改造が要りそうですね。
|
- bonbon
- 会議室デビュー日: 2003/05/30
- 投稿数: 8
|
投稿日時: 2004-02-14 19:54
さくらばさん。
貴重なプログラムのご教示ありがとうございます。
参考にさせていただきます。
しかし、JMenuBarのデフォルトの動きを変更するだけでも結構、
複雑なのですね。
JAVAの勉強として、JMenuBarのデフォルトでもつアクションを調べて
みたい気もします。それにはソースを見るしかないのでしょうか?
|