Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 单击其JPOpupMenus时,JPopupPanel关闭_Java_Swing_User Interface_Jpopupmenu - Fatal编程技术网

Java 单击其JPOpupMenus时,JPopupPanel关闭

Java 单击其JPOpupMenus时,JPopupPanel关闭,java,swing,user-interface,jpopupmenu,Java,Swing,User Interface,Jpopupmenu,我有一个JPopupPanel在单击按钮时显示 这个JPopupPanel有一个JPopupMenu,通过鼠标右键单击显示,显示不同的选项。 当按下左键在PopupMenu中选择其中一个选项时,PopupPanel会关闭,暂时不显示PopupMenu,当松开按钮时,PopupMenu也会按预期消失,但由于PopupPanel已关闭,因此无法在PopupPanel中看到该动作 在选择JPopupMenu的一个选项时,如何避免关闭JPopupPanel 谢谢对不起,我没有使用JPopupPanel的

我有一个JPopupPanel在单击按钮时显示

这个JPopupPanel有一个JPopupMenu,通过鼠标右键单击显示,显示不同的选项。 当按下左键在PopupMenu中选择其中一个选项时,PopupPanel会关闭,暂时不显示PopupMenu,当松开按钮时,PopupMenu也会按预期消失,但由于PopupPanel已关闭,因此无法在PopupPanel中看到该动作

在选择JPopupMenu的一个选项时,如何避免关闭JPopupPanel


谢谢

对不起,我没有使用JPopupPanel的经验。因此,我只能提供一个简单的技巧

我怀疑你可以做一些类似的事情,比如我在下面的例子中,我在选项选择上“忽略”隐藏弹出菜单

我的方法是在选项选择上重新显示弹出菜单。所以当面板隐藏时,你可以尝试重新显示它

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Point;
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;
import javax.swing.SwingUtilities;

public class JPopupMenuIgnoreOptionCloseOnClick extends JPanel
{
    private static final long serialVersionUID = 1L;
    private JPopupMenu popup = new JPopupMenu("Oi I am popup");
    private MouseListener mL = new MouseAdapter()   
    {
        @Override
        public void mousePressed(MouseEvent e)
        {
            System.out.println("mL mousePressed e.isP="+e.isPopupTrigger());
            super.mousePressed(e);
            showPopup(e);
        }

        @Override
        public void mouseReleased(MouseEvent e)
        {           
            System.out.println("mL mouseReleased e.isP="+e.isPopupTrigger());
            super.mouseReleased(e);
            showPopup(e);
        }

        private void showPopup(MouseEvent e)
        {
            if(e.isPopupTrigger())
            {
                prevLocation = e.getPoint();
                popup.show(e.getComponent(), e.getX(), e.getY());
            }
        }
    };
    private Point prevLocation = null;
    private MouseListener optionML = new MouseAdapter()
    {
        @Override
        public void mouseReleased(MouseEvent e)
        {
            System.out.println("optionML mouseReleased prevLocation="+prevLocation);
            e.consume();
            popup.show(JPopupMenuIgnoreOptionCloseOnClick.this, prevLocation.x,prevLocation.y);
        } 

    };

    public JPopupMenuIgnoreOptionCloseOnClick()
    {
        addMouseListener(mL);
        JMenuItem opt1 =new JMenuItem("Option 1");
        opt1.addMouseListener(optionML);
        popup.add(opt1);
        JMenuItem opt2 =new JMenuItem("Option 2");
        opt2.addMouseListener(optionML);
        popup.add(opt2);
        JMenuItem opt3 =new JMenuItem("Option 3");
        opt3.addMouseListener(optionML);
        popup.add(opt3);
    }

    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable() 
        {
            @Override
            public void run()
            {           
                JPopupMenuIgnoreOptionCloseOnClick p = new JPopupMenuIgnoreOptionCloseOnClick();
                p.setPreferredSize(new Dimension(400, 400));
                JPanel contentPane = new JPanel();
                contentPane.setBackground(Color.CYAN);
                contentPane.add(p);
                JFrame f = new JFrame();        
                f.setContentPane(contentPane);
                f.setSize(800, 600);
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.setVisible(true);
            }
        });
    }   
}

我自己在JCommandButton上安装自定义JPopupMenu时遇到了这个问题。 对于JCommandButton,我发现这有助于防止过早处理父弹出窗口:

this.putClientProperty(BasicCommandButtonUI.DONT_DISPOSE_POPUPS, true);
如果您正在寻找的是,在选择JPopupMenu JMenuItem时,父弹出面板将保持打开状态,您有几个选项。问题源于JPopupMenu在用户界面所依赖的祖先容器链中的断开链接。您需要返回getInvoker,而不是getParent

1: 在BasicPoupPaneLui.WindowTracker.eventDispatched中修改库源。或者更改SwingUtilities.getAncestorOfClass调用以使用SwingXUtilities.getAncestorOfClass,该类用于解释此特殊情况。或者自己实现逻辑

if(parent instanceof JPopupMenu)  parent = ((JPopupMenu)parent).getInvoker()
2:

是否将此代码添加到小部件CustomButton

 final JPopupMenu popper = new JPopupMenu(){  //hack
        @Override public Container getParent(){
            StackTraceElement ste = Thread.currentThread().getStackTrace()[2];
            if(ste.getClassName().equals(SwingUtilities.class.getName()))
                return CustomButton.this.getParent();
            return super.getParent();
        }
    };

我选择了2,因为我在修改第三方库时遇到了问题。

@Boro+1但是对于未来的读者来说,嗯,如何告诉你值得尊敬的、更好的。。。您完全忽略了main方法中的EDT,以及关于LayeredPane kille*d***的示例。请为容器的子对象设置首选大小,编辑该大小,并将图标+按钮首选大小+10放置在那里,以便出色地输出到GUI,如果您编辑该大小,则可以删除此注释:-@mKorbel谢谢您的评论。我在构建GUI时对EDT的无知是因为我在编写简单的解决方案/示例时懒惰。代码已编辑。从现在起,我将尝试在每个示例中添加SwingUtilities.invokeLater。顺便说一句,在一个简单的例子中,我从未见过忽略EDT的GUI构建会导致问题的问题。有关为什么我在滚动窗格中使用setPreferredSize的解释,请参见我答案下的注释2。PS:无需删除您的评论,它将用作提醒。顺便说一句,我从来没有看到过GUI构建忽略EDT 1/是的,直到/然后您将尝试应用一些原始L&F,也不是自定义的,2/一次我希望您使用的不是0.6T而是6T,然后任何新手都可以将此作为编码标准,3/这里的一些人不会像懒散@mKorbel那样接受setize。理解。带有滚动条的代码现在还包括在EDT上构建GUI。如果我在组件上使用setSize的原因是setPreferedSize不起作用。不太清楚为什么,可能是因为组件是分层窗格的子组件。@Boro:-现在如何摆脱它out:-对于EDT问题,只需打包+可见最终我很好,我得到了一些外部帮助,就像您建议的那样:重写SubstancePoupPaneLui类,这样在内部类WindowTracker2中,您可以通过检查SwingUtilities.getAncestorOfClass(来自Swingx)在eventDispatched方法中进行黑客攻击,谢谢