[英]Finding the restore bounds of a JFrame when it is in a maximized state
[英]Issue while closing JPopupMenu with the parent JFrame in maximized state
我有一个JFrame和一个按钮,它在点击事件上打开一个JPopupMenu。 这个JPopupMenu有一个带按钮的JPanel。 这个按钮应该处理JPopupMenu。 只要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
}
我想,你的意思是:
当JFrame最大化时,它会关闭JPopupMenu本身
JPopupMenu
菜单的状态分别与其祖先( JFrame
)或整个窗口系统紧密绑定。它将隐藏在焦点丢失,鼠标/按键上......虚拟地在任何窗口中的任何状态更改或输入事件上,就像人们从普通的弹出菜单中所期望的那样。 解决这个问题会迫使你重新打开菜单(难以捕获事件)。 但是,这会导致闪烁。 注意, JPopupMenu
可以依赖于反向平台窗口系统的固定基本机制,因此不能通过AWT / Swing改变其行为。
我最近想要类似的东西; 使用 JPopupMenu
切换JTable
的多个列的可见性。但随后,随着黑客攻击,我决定使用带有 JList
的模态JDialog
,其中包含条目。将悬停效果添加到 JList
(或JTable
)是一种可移植且可重复使用的效果,这比上面提到的任何黑客都要少: 在悬停时更改JList项目背景颜色
编辑:
SwingUtilities.getWindowAncestor(MyJPanel.this)
由于JPopupMenu不是Window
,因此getWindowAncestor()
找不到应该完全关闭的JpopupMenu
,如下所示:
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; } } //... }
这个按钮应该处理JPopupMenu。 只要JFrame没有最大化,它就会这样做。 但是,当JFrame最大化时,它会关闭Jframe本身。
当您使用弹出窗口并且弹出窗口扩展到框架的边界之外时,弹出窗口将放置在JWindow中,因为Swing组件必须在窗口中绘制。 这就是使用默认帧大小时它的工作原理。
但是,如果弹出窗口完全包含在框架的边界中,则弹出窗口可以添加到框架中并进行绘制。 你可以通过让你的框架变得更大(它不需要最大化)来轻松地证明这一点,你会看到差异。
解决方案基本上是Sam已经建议的,除非您不需要编写自己的代码。 只需使用:
JPopupMenu popup = (JPopupMenu)SwingUtilities.getAncestorOfClass(JPopupMenu.class, (Component)e.getSource();
if (popup != null)
popup.setVisible(false);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.