【发布时间】:2018-11-18 16:19:12
【问题描述】:
如何让我的JPopupMenu 出现在任务栏上方?换句话说,我如何强制它遵守屏幕限制,使其不被覆盖?以 Android Studio 的弹出菜单为例:
正常位置:
当我将窗口拖到底部任务栏附近时,弹出“适应”并出现在其上方:
在任务栏附近(您可以看到,与 Android Studio 不同的是,部分弹出窗口消失在任务栏下方):
测试用例代码:
Test.java
public class Test extends javax.swing.JFrame {
public Test() {
initComponents();
}
public void initUI() {
}
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
btnMenu = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
btnMenu.setText("Click for Menu");
btnMenu.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnMenuActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap(291, Short.MAX_VALUE)
.addComponent(btnMenu)
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap(266, Short.MAX_VALUE)
.addComponent(btnMenu)
.addContainerGap())
);
pack();
setLocationRelativeTo(null);
}// </editor-fold>
private void btnMenuActionPerformed(java.awt.event.ActionEvent evt) {
JPopupMenu menu = new JPopupMenu();
menu.add(new PopBody());
menu.show(this, btnMenu.getLocation().x - 95, btnMenu.getLocation().y + 60);
}
public static void main(String args[]) {
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
}
java.awt.EventQueue.invokeLater(() -> new Test().setVisible(true));
}
// Variables declaration - do not modify
private javax.swing.JButton btnMenu;
// End of variables declaration
}
PopBody.java
public class PopBody extends javax.swing.JPanel {
public PopBody() {
initComponents();
}
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
lblBody = new javax.swing.JLabel();
btnOK = new javax.swing.JButton();
lblBody.setText("Panel body");
btnOK.setText("OK");
btnOK.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnOKActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(77, 77, 77)
.addComponent(lblBody)
.addContainerGap(92, Short.MAX_VALUE))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(btnOK)
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(73, 73, 73)
.addComponent(lblBody)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 56, Short.MAX_VALUE)
.addComponent(btnOK)
.addContainerGap())
);
}// </editor-fold>
private void btnOKActionPerformed(java.awt.event.ActionEvent evt) {
}
// Variables declaration - do not modify
private javax.swing.JButton btnOK;
private javax.swing.JLabel lblBody;
// End of variables declaration
}
【问题讨论】:
-
制作 JPopupMenu heavyweight.
-
@VGR 会实现什么?
-
几乎所有 Swing 组件默认都是轻量级的,这意味着它们不是原生屏幕分配;相反,Swing 将它们绘制在窗口内。重量级组件使用原生矩形区域,因此它可以与其他原生元素重叠。权衡是重量级组件使用了更多的系统资源,尽管这可能不像 20 年前那么令人担忧。
-
我刚刚在 JPopup 上调用了
menu.setLightWeightPopupEnabled(false);,它的行为方式相同。
标签: java swing jpopupmenu