[英]Problems with swing components and awt events
我的java gui代码似乎有问题,我也不知道为什么它不起作用。
发生的事情是在面板或框架上单击鼠标时- 现在,我们只说面板。 因为这只是一个测试,最终将为另一个gui组件实现此代码,但我想首先使该代码起作用 - 弹出菜单需要变得可见,并且焦点需要设置在文本字段上 。 然后,当用户按Enter或失去对文本字段的关注时,则需要隐藏弹出菜单,并将文本重置为空白或我需要的任何内容。
这就是我写的:
public class Test {
private final JFrame frame = new JFrame();
private final JPanel panel = new JPanel();
private final JPopupMenu menu = new JPopupMenu();
private final JTextField field = new JTextField();
private final Obj obj;
//... constructor goes here
public void test(){
frame.setSize(new Dimension(200,200));
field.setColumns(10);
field.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
obj.method(field.getText());
menu.setVisible(false);
field.setText("");
}
});
field.addFocusListener(new FocusListener() {
public void focusLost(FocusEvent e) {
menu.setVisible(false);
field.setText("");
}
//... focus gained event goes here
});
panel.addMouseListener(new MouseListener() {
public void mouseClicked(MouseEvent e) {
menu.setLocation(e.getX(), e.getY());
menu.setVisible(true);
field.requestFocusInWindow();
}
//... other mouse events go here
});
menu.add(field);
frame.getContentPane().add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
单击此处后,使用此处编写的代码,菜单自动隐藏。 它只是在屏幕上短暂闪烁,然后在没有其他任何操作的情况下隐藏起来。
如果我更改代码以排除出现menu.setVisible(false)
任何情况,则文本字段将永远不会获得焦点。
这是由于误用了JPopupMenu吗? 我要去哪里错了?
另请注意,我省略了main或Obj。 它们在另一个文件中,并且很可能对该问题无关紧要。 Obj.method()不执行任何操作,并且main仅调用Test的构造函数和test()方法。
这段代码应该按照您希望的方式工作(希望您遵循匿名类的使用:
public class Test {
public static void main(String[] args) {
Test test = new Test();
test.test();
}
private JFrame frame;
private JPanel panel;
private JPopupMenu menu;
private JTextField field;
public Test() {
frame = new JFrame();
frame.setSize(new Dimension(200, 200));
frame.getContentPane().add(getPanel());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private JPanel getPanel() {
if (panel == null) {
panel = new JPanel();
panel.setComponentPopupMenu(getMenu());
panel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
menu.show(panel, e.getX(), e.getY());
}
});
}
return panel;
}
private JPopupMenu getMenu() {
if (menu == null) {
menu = new JPopupMenu() {
@Override
public void setVisible(boolean visible) {
super.setVisible(visible);
if (visible) {
getField().requestFocus();
}
}
};
menu.add(getField());
}
return menu;
}
private JTextField getField() {
if (field == null) {
field = new JTextField();
field.setColumns(10);
field.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
getMenu().setVisible(false);
}
});
}
return field;
}
public void test() {
frame.setVisible(true);
}
}
需要注意的关键是设置弹出菜单时:
panel.setComponentPopupMenu(getMenu());
panel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent event) {
getMenu().show(getPanel(), event.getX(), event.getY());
}
});
以及在弹出菜单可见时如何请求文本字段的焦点,这是通过请求焦点的文本字段来实现的,但不能在窗口中聚焦,因为它不在窗口中,而是仅在菜单中存在:
menu = new JPopupMenu() {
@Override
public void setVisible(boolean visible) {
super.setVisible(visible);
if (visible) {
getField().requestFocus();
}
}
};
最后是文本字段如何消除弹出菜单:
field.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
getMenu().setVisible(false);
}
});
您应该可以通过重写getComponentPopupMenu返回JPopupMenu来执行此操作。 这应该完全按照您想要的方式处理。 它将允许焦点等。
编辑:虽然确实允许更好的继承,但这不是严格必要的。
Public JPopupMenu getComponentPopupMenu() {
return getMenu();
}
哦,如果您希望它显示在任何鼠标单击上,请添加一个鼠标侦听器,然后在弹出菜单中调用show:
public void processMouseEvent(MouseEvent e) {
popup.show(this, e.getX(), e.getY());
}
只要单击鼠标,它就会显示出来。
或者,另一个选择是,如果您有一个鼠标侦听器(调用processMouseEvent),而您只想在右键单击上调用:
public void processMouseEvent(MouseEvent e) {
if (e.isPopupTrigger()) {
popup.show(this, e.getX(), e.getY());
}
}
鼠标侦听器如下所示:
panel.addMouseListener(new MouseAdapter() {
mouseClicked(MouseEvent e) {
processMouseEvent(e);
}
}
我想指出的是,我发现通过使用建议的方法, setComponentPopupMenu()
自动添加了一个MouseListener来显示给定的PopupMenu,然后使用右键事件。
因此, if(e.isPopupTrigger())
结构内部的任何内容都不会在右键单击上运行,因为事件已被消耗。
因此,从本质panel.setComponentPopupMenu(getMenu())
,我只需添加panel.setComponentPopupMenu(getMenu())
获得问题中指定的panel.setComponentPopupMenu(getMenu())
,但是它占用了我所有的右键单击事件,而不仅仅是mouseClicked,这一事实是极其有限的。
当您显示一个弹出窗口时,它应该具有焦点(并且可能抓住了焦点),其他任何事情实际上都没有多大意义。
所以可能发生的是:菜单显示并抓住焦点。
使用下一个命令,您可以将焦点移至文本字段。 由于弹出窗口没有焦点,而没有焦点的弹出窗口没有用,因此它将再次隐藏。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.