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