当前位置: 首页 > 知识库问答 >
问题:

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

施慈
2023-03-14

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

任何有助于解决这一问题的帮助或建议都将不胜感激。

(我正在使用netbeans来开发这个。)

//Demo.Java

public class Demo extends javax.swing.JFrame {
    public JPopupMenu menu1;

    public Demo() {
        initComponents();
        menu1 = new JPopupMenu();
        menu1.add(new MyJPanel());    
    }

    @SuppressWarnings("unchecked")
    private void initComponents() {
        jButton1 = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

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

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(53, 53, 53)
                .addComponent(jButton1)
                .addContainerGap(224, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(85, 85, 85)
                .addComponent(jButton1)
                .addContainerGap(192, Short.MAX_VALUE))
        );

        pack();
    }

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        menu1.show(jButton1,0,0);
    }                                        

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Demo().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    private javax.swing.JButton jButton1;
    // End of variables declaration                   
}

下面是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                   


}

共有2个答案

蓬野
2023-03-14

这个按钮应该用来处理JPOppMenu。只要JFrame没有最大化,它就会这样做。但是,当JFrame最大化时,它会关闭JFrame本身。

当使用弹出窗口时,弹出窗口超出了框架的边界,弹出窗口被放置在一个窗口中,因为Swing组件必须在窗口中绘制。这就是为什么在使用默认帧大小时它会起作用。

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

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

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

if (popup != null)
    popup.setVisible(false);
楚骞尧
2023-03-14

我猜,你的意思是:

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

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

我最近也想要类似的东西;使用jpopmenu切换JTable的多个列的可见性。但是,随着黑客攻击的深入,我决定使用一个模态的JDialog和一个JList,其中包含条目。将悬停效果添加到JList(或JTable)是一种可移植且可重复使用的效果,其问题远小于上述任何攻击:在悬停时更改JList项的背景色

编辑:

SwingUtilities.getWindowAncestor(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;
            }
    }

    //...
}
 类似资料:
  • 问题内容: 我不知道如何使用此代码: 使用x按钮关闭程序。 问题答案: 你需要线 因为按下X按钮时JFrame的默认行为等效于 因此,几乎所有时候,创建JFrame时都需要手动添加该行 我目前指的是like 中的常量,而不是像先前那样直接声明的常量更能反映意图。

  • 我的程序在屏幕上显示一些窗口(jframe和jpanel)和一个主框架。当用户选择删除主框架中其中一个窗口的选项时,应关闭所选窗口。 我把那些窗户排成一排。当用户选择要关闭的窗口时,它将从数组中删除该jframe和它的jpanel,它应该关闭该jframe,但不会。没有显示任何错误,当我再次运行该程序时,一切都与预期一样:删除的帧不会显示。我的结论是,关闭jframe时,我没有正常工作,程序的其余

  • 我意识到在窗口中添加一个与“X”功能完全相同的按钮是毫无意义的,但我已经计算出了按钮在GUI上的位置,并发现拥有退出按钮除了占位符之外,还可以让事情变得更容易。我喜欢这种练习。 好吧,不管怎样,继续前进。 我有一个父JFrame(实际上是主类),我希望在程序运行的整个过程中保持开放运行。这不是我的问题。我的问题是在打开子JFrame时。我在主类中实例化了它(它添加了一个我创建的面板组件),但我只是

  • 问题内容: 从MDN for NodeList: 在某些情况下,NodeList是一个实时集合,这意味着DOM中的更改会反映在集合中。例如,Node.childNodes处于活动状态: 在其他情况下,NodeList是静态集合,这意味着DOM中的任何后续更改都不会影响集合的内容。document.querySelectorAll返回一个静态NodeList。 所以....有点烦!是否有任何关于哪些

  • 问题内容: 我在JPopupMenu中有一个JComboBox(以及其他组件)。事实证明,每当我打开组合框的弹出窗口(以选择一个项目)时,父级JPopupMenu都会关闭。我一直在尝试找到一种方法来覆盖此功能,但无济于事。 有没有人建议防止关闭父级JPopupMenu?谢谢! 问题答案: 这不可能直接实现,很难覆盖已知的错误,另一方面,Swing不允许同时使用两个lightwieght弹出组件 但

  • 我有一个包含编辑选项的帐户表。单击编辑选项时,将显示帐户编辑模式对话框。用户可以通过单击右上角的“X”或单击关闭按钮来关闭或取消编辑。当模式关闭时,我想清除一些状态属性,包括对话框属性和父组件属性。对话框属性更新没有任何问题,但我收到这个错误时,父属性试图更新: 无法在现有状态转换期间更新(例如在