Java 在父JFrame处于最大化状态时关闭JPopupMenu时出现问题

Java 在父JFrame处于最大化状态时关闭JPopupMenu时出现问题,java,swing,popupmenu,maximize,Java,Swing,Popupmenu,Maximize,我有JFrame和一个按钮,可以在单击事件时打开一个JPopupMenu。 这个JPOppMenu有一个带有按钮的JPanel。此按钮应用于处理JPOppMenu。只要JFrame没有最大化,它就会这样做。但是,当JFrame最大化时,它会关闭JFrame本身 如果您能提供任何帮助或建议来解决此问题,我们将不胜感激 (我正在使用netbeans来开发此功能。) 下面是MyJpanel的代码 // MyJPanel.java package demo; import java.awt.Windo

我有JFrame和一个按钮,可以在单击事件时打开一个JPopupMenu。 这个JPOppMenu有一个带有按钮的JPanel。此按钮应用于处理JPOppMenu。只要JFrame没有最大化,它就会这样做。但是,当JFrame最大化时,它会关闭JFrame本身

如果您能提供任何帮助或建议来解决此问题,我们将不胜感激

(我正在使用netbeans来开发此功能。)

下面是MyJpanel的代码

// MyJPanel.java
package demo;

import java.awt.Window;
import javax.swing.SwingUtilities;

public class MyJPanel extends javax.swing.JPanel {
    public MyJPanel() {
        initComponents();
    }
    @SuppressWarnings("unchecked")
    private void initComponents() {

        jTabbedPane1 = new javax.swing.JTabbedPane();
        jPanel1 = new javax.swing.JPanel();
        jButton1 = new javax.swing.JButton();
        jPanel2 = new javax.swing.JPanel();

        jButton1.setText("Close jPopupMenu");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addGap(82, 82, 82)
                .addComponent(jButton1)
                .addContainerGap(192, Short.MAX_VALUE))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addGap(122, 122, 122)
                .addComponent(jButton1)
                .addContainerGap(127, Short.MAX_VALUE))
        );

        jButton1.getAccessibleContext().setAccessibleName("closeParent");

        jTabbedPane1.addTab("tab1", jPanel1);

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 395, Short.MAX_VALUE)
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 272, Short.MAX_VALUE)
        );

        jTabbedPane1.addTab("tab2", jPanel2);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jTabbedPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jTabbedPane1)
        );
    }

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        Window w = SwingUtilities.getWindowAncestor(MyJPanel.this);
        w.dispose();
    }                                        

    // Variables declaration - do not modify                     
    private javax.swing.JButton jButton1;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JTabbedPane jTabbedPane1;
    // End of variables declaration                   


}

我猜,你的意思是:

当JFrame最大化时,它关闭jpopmpmenu本身

jpopmenu
菜单的状态分别与它的祖先(
JFrame
)或整个窗口系统紧密绑定。它将在焦点丢失时隐藏,鼠标/按键。。。事实上,任何窗口中的任何状态更改或输入事件,就像普通弹出菜单中所期望的那样。解决这个问题将迫使您重新打开菜单(捕获事件很难做到)。但是,这将导致闪烁。请注意,
jpopmpmenu
可能依赖于非远程平台窗口系统的固定基本机制,因此无法通过AWT/Swing更改其行为

我最近想要类似的东西;使用
jpopmenu
切换
JTable
多列的可见性。 但是,随着黑客的攻击越来越激烈,我决定使用模态的
JDialog
JList
,其中包含条目。将悬停效果添加到
JList
(或
JTable
)是一种可移植且可重复使用的效果,与上述任何黑客相比问题要小得多:

编辑:

SwingUtilities.getWindow祖先(MyJPanel.this)

由于JPOPUPMENUS不是一个
窗口
GetWindowSenentor()
无法找到应完全关闭的
JPOPUPMENUS
,如下所示:

public class MyJPanel extends javax.swing.JPanel {
    //...

    /**
     * Try to find and hide the first enclosing JPopupMenu by traversing the
     * parent components
     */
    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
        for (Component parent = this.getParent(); parent != null; parent = parent.getParent())
            if (parent instanceof JPopupMenu) {
                ((JPopupMenu) parent).setVisible(false);
                break;
            }
    }

    //...
}
此按钮应用于处理JPOppMenu。只要JFrame没有最大化,它就会这样做。但是,当JFrame最大化时,它会关闭JFrame本身

当您使用弹出窗口并且弹出窗口扩展到框架的边界之外时,弹出窗口被放置在JWindow中,因为Swing组件必须在窗口中绘制。这就是为什么在使用默认帧大小时它可以工作的原因

但是,如果弹出窗口完全包含在框架的边界中,则可以将弹出窗口添加到框架中并进行绘制。你可以很容易地证明这一点,只要把你的帧放大一点(它不需要最大化),你就会看到不同

解决方案基本上是Sam已经建议的,只是您不需要编写自己的代码。只需使用:

JPopupMenu popup = (JPopupMenu)SwingUtilities.getAncestorOfClass(JPopupMenu.class, (Component)e.getSource();

if (popup != null)
    popup.setVisible(false);

谢谢你的快速回复。不,我的意思是它关闭了“JFrame”,这是本例中的超级父级。摘自MyJPanel.java(我的实际帖子中的工作代码)。。。private void jButton1ActionPerformed(java.awt.event.ActionEvent evt){Window w=SwingUtilities.getWindow祖先(MyJPanel.this);w.dispose();}以上两行应关闭JPopupMenu(实际上是父级)。当超级parent(JFrame)未最大化时,它可以正常工作。当JFrame最大化时,我的期望值就不高了。现在,我已经在我的Linux机器上运行了它,我可以真正理解并再现你所说的。问题是,祖先的变化最大化(我认为这是一个错误或副作用,使用JPOPUPPONE以一种非常不寻常的方式)。请参见编辑以获取解决方案谢谢Sam。这很有帮助:)@TeenaJain,该解决方案是合理的(+1),但对问题原因的解释实际上没有意义。请参阅我的答案。交叉张贴:。退出交叉发布。你至少可以回复所有论坛,这样人们就不会浪费时间回答已经回答过的问题。
JPopupMenu popup = (JPopupMenu)SwingUtilities.getAncestorOfClass(JPopupMenu.class, (Component)e.getSource();

if (popup != null)
    popup.setVisible(false);