[英]How to prevent a disabled JMenuItem from hiding the menu when being clicked?
在我的Java swing應用程序中,我注意到當我在JPopupMenu中單擊禁用的JMenuItem時,它隱藏了菜單,但是我不想隱藏它,好像沒有點擊任何內容。 有辦法防止這種情況嗎?
-----------------------------------> 更新:添加代碼示例:
JMenuItem saveMenuItem = new JMenuItem();
saveMenuItem.setEnabled(false);
saveMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
saveMenuItemActionPerformed();
}
});
add(saveMenuItem);
private void saveMenuItemActionPerformed() {
System.out.println( "Save clicked." );
}
我認為在Java7中這已得到修復。
不知道如何預防。 但你可以setVisible(false)來防止它被顯示。 此外,如果用戶單擊禁用菜單,則不會執行任何操作。
禁用JMenuItem時,應使用jMenuItem.removeActionListener()方法刪除與該JMenuItem關聯的ActionListener。 如果你刪除那個動作將不會調用監聽器,彈出窗口將不會消失。 我希望這有助於實現您的目標。
簡而言之,你可以這樣做,但你必須編寫自己的鼠標監聽器,這可能需要從jdk源代碼中進行大量的復制和粘貼,這不是一個好主意,而且我不確定哪些許可限制它會把你的代碼。
我會從這個方法開始挖掘:
javax.swing.plaf.basic.BasicMenuItemUI.Handler#mouseReleased
這似乎是菜單處理機制隱藏彈出窗口的入口點。 我會仔細看看
javax.swing.plaf.basic.BasicPopupMenuUI.MouseGrabber#stateChanged
編輯 @Burhan Valikarimwala開發答案,試試這個apporach:從禁用的JMenuItem中刪除所有動作監聽器並將它們存儲在一些靜態臨時結構中(假設一個Map<WeakReference<JMenuItem>, List<MouseListener>>
),這樣它會不要隱藏彈出窗口。 再次啟用菜單項時,請添加所有偵聽器。 將它變成一些util方法,它將是無縫的。
你試過這個方法了嗎: http : //download.oracle.com/javase/6/docs/api/javax/swing/JMenuItem.html#setArmed%28boolean%29
“設置菜單項以便可以選擇它”,如果設置為false,我想這會成功。
我能提出的唯一解決方案,因為你點擊禁用JMenuItem使其隱藏的問題如下:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
public class PopupMenuDisableNoCloseTest extends JPanel implements ActionListener
{
public static void main(String[] args)
{
PopupMenuDisableNoCloseTest p = new PopupMenuDisableNoCloseTest();
p.setPreferredSize(new Dimension(200, 300));
p.setBackground(Color.GREEN);
JPanel contentPane = new JPanel();
contentPane.add(p);
final JFrame f = new JFrame();
final JPopupMenu popup = new JPopupMenu();
final JMenuItem menuItem1 = new JMenuItem("A popup menu item");
menuItem1.addActionListener(p);
menuItem1.addMouseListener(new MouseAdapter()
{
@Override
public void mousePressed(MouseEvent e)
{
System.out.println(" menuItem1 mousePressed e.getPoint()=" + e.getPoint());
}
@Override
public void mouseReleased(MouseEvent e)
{
System.out.println(" menuItem1 mouseReleased e.getPoint()=" + e.getPoint());
if(!menuItem1.isEnabled())
popup.setVisible(true);
}
});
menuItem1.setEnabled(false);
popup.add(menuItem1);
JMenuItem menuItem2 = new JMenuItem("Another popup menu item");
menuItem2.addActionListener(p);
popup.add(menuItem2);
MouseListener popupListener = new PopupListener(popup);
f.addMouseListener(popupListener);
f.setContentPane(contentPane);
f.setSize(800, 600);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e)
{
JMenuItem source = (JMenuItem) (e.getSource());
String s = "Action event detected. Event source: " + source.getText();
System.out.println("s=" + s);
}
static class PopupListener extends MouseAdapter
{
JPopupMenu popup;
PopupListener(JPopupMenu popupMenu)
{
popup = popupMenu;
}
@Override
public void mousePressed(MouseEvent e)
{
maybeShowPopup(e);
}
@Override
public void mouseReleased(MouseEvent e)
{
maybeShowPopup(e);
}
private void maybeShowPopup(MouseEvent e)
{
if(e.isPopupTrigger())
{
popup.show(e.getComponent(),
e.getX(), e.getY());
}
}
}
}
基本上隱藏發生在你的發布在JMenuItem的邊界內時,因此我們檢查它是否被禁用然后我們再次顯示彈出窗口。 到目前為止,已經確定它將被隱藏。 我正在嘗試使用指向組件外部的不同MouseEvent調用super.mouseRelease並使用前一個,但它沒有任何幫助。
無論如何這個解決方案有效 享受,博羅
這已經過測試和運作。
外觀和感覺決定如何處理禁用菜單項上的鼠標事件。 無論如何,您可以使用自定義MenuItem
攔截不需要的事件。 只需使用該代碼(復制/粘貼):
public class CustomMenuItem extends JMenuItem {
public CustomMenuItem(String text) {
super(text);
}
public CustomMenuItem() {
super();
}
protected void processMouseEvent(MouseEvent e) {
if (isEnabled()) super.processMouseEvent(e);
}
}
首先,根據您的需求調整代碼(可選)。
最后, 用 CustomMenuItem
替換任何JMenuItem
。
而已!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.