如何用 JDialog 模仿 JPopupMenu 的行为?
Posted
技术标签:
【中文标题】如何用 JDialog 模仿 JPopupMenu 的行为?【英文标题】:How to mimic the behavior of JPopupMenu with JDialog? 【发布时间】:2022-01-23 05:34:59 【问题描述】:我正在使用 Swing 实现“应用内”搜索引擎,我希望它的行为与 Windows 10 的搜索框完全相同。
搜索框应该:
在搜索按钮的上方和右侧打开,触摸按钮的边缘。 打开时有焦点。 按下搜索按钮即可关闭(如果打开)。 在搜索框外的任意位置用鼠标按下时关闭(如果打开)。如果 JPopUpMenu 可以将 JDialog 作为它的子级,那就太完美了,但是因为我不需要从头开始实现这些行为(或者我需要吗?)。
这是我第一次使用 Swing,我很难自己实现所有内容。 我尝试在网上寻找示例,但找不到太多有用的信息。
对于 JPopUpMenu 无法托管 JDialog,是否有解决方法? 是否有实施我描述的行为的示例?
谢谢
================================编辑=============== ============== 感谢到目前为止的cmets。除了一个问题之外,我已经设法获得了我想要的行为。
以下代码创建一个带有按钮的框架:
public static void main(String[] args)
JFrame mainWindow = new JFrame();
mainWindow.setSize(420,420);
mainWindow.setVisible(true);
JFrame popUp = new JFrame();
popUp.setSize(210, 210);
JButton button = new JButton("button");
mainWindow.add(button);
button.addActionListener(new ActionListener()
@Override
public void actionPerformed(ActionEvent e)
if(!button.isSelected())
button.setSelected(true);
popUp.setVisible(true);
else
button.setSelected(false);
popUp.setVisible(false);
);
popUp.addWindowFocusListener(new WindowAdapter()
@Override
public void windowLostFocus(WindowEvent e)
popUp.setVisible(false);
);
当我点击按钮时,会出现一个弹出窗口,如果我点击主窗口外,弹出窗口会消失,但是当我想重新打开弹出窗口时,我需要按两次按钮。
当弹出窗口因失去焦点而关闭时,如何让按钮正常操作?
【问题讨论】:
您不能将 JDialog 添加到任何内容,因为它与操作系统本机对等窗口相关联。您可能想考虑使用 JWindow 来完成您想要完成的工作 不确定您的问题是什么。您可以轻松地使用所需的任何组件创建 JDialog。您向按钮添加逻辑以检查对话框是否可见,然后进行适当的处理。您将对话框设置为非模态对话框,以便在对话框可见时将焦点集中到对话框上的任何组件。您可以将 WindowListener 添加到对话框并处理 windowDeactivated 事件以关闭对话框。如果您需要更多帮助,请发帖 minimal reproducible example 展示您所做的工作,并一次提出一个具体问题。JPopupMenu#setInvoker
?
如果您想要 JDialogue 行为然后使用 JDialogue 并将其简单地定位在屏幕上 relative to your menu,或者如果您可以使用 yourPopup.insert(component, index);
将按钮或类似内容插入到您的 JPopupMenu 中并让按钮执行相关行动。
【参考方案1】:
您的“解决方案”非常脆弱。在左键单击JButton
之前尝试移动主JFrame
。
Oracle 有一个有用的教程,Creating a GUI With Swing。跳过 Netbeans 部分。学习本教程的其余部分。
我创建了一个主要的JFrame
,它会弹出一个JDialog
。我把关闭的JButton
放在JDialog
上。 JDialog
是模态的,这意味着当 JDialog
可见时,您无法访问主 JFrame
。
您可以将JDialog
放置在屏幕上您希望的任何位置。通常,您有一个JDialog
出现在父JFrame
的中心。这就是用户期望出现对话框的地方。我将JDialog
放在左上角,只是为了向您展示它是如何完成的。
这是完整的可运行代码。
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class PopupExample
public static void main(String[] args)
SwingUtilities.invokeLater(() -> new PopupExample().createAndShowGUI());
private JFrame mainWindow;
public void createAndShowGUI()
mainWindow = new JFrame("Main Window");
mainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainWindow.add(createMainPanel(), BorderLayout.CENTER);
mainWindow.pack();
mainWindow.setLocationByPlatform(true);
mainWindow.setVisible(true);
private JPanel createMainPanel()
JPanel panel = new JPanel(new FlowLayout());
panel.setBorder(BorderFactory.createEmptyBorder(200, 200, 200, 200));
JButton button = new JButton("button");
panel.add(button);
button.addActionListener(new ActionListener()
@Override
public void actionPerformed(ActionEvent e)
createAndShowDialog(mainWindow);
);
return panel;
private void createAndShowDialog(JFrame frame)
JDialog dialog = new JDialog(frame, "Dialog", true);
dialog.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
dialog.add(createDialogPanel(dialog), BorderLayout.CENTER);
dialog.pack();
// Here's where you set the location of the JDialog relative
// to the main JFrame
Point origin = frame.getLocation();
dialog.setLocation(new Point(origin.x + 30, origin.y + 30));
dialog.setVisible(true);
private JPanel createDialogPanel(JDialog dialog)
JPanel panel = new JPanel(new FlowLayout());
panel.setBorder(BorderFactory.createEmptyBorder(100, 100, 100, 100));
JButton button = new JButton("Close");
panel.add(button);
button.addActionListener(new ActionListener()
@Override
public void actionPerformed(ActionEvent e)
dialog.dispose();
);
return panel;
【讨论】:
感谢您的回答,但我觉得我的问题没有被理解。我的问题(编辑后)是“如何创建一个在按下按钮时打开和关闭并在失去焦点时关闭的 JFrame?”以上是关于如何用 JDialog 模仿 JPopupMenu 的行为?的主要内容,如果未能解决你的问题,请参考以下文章