Java JTextField在重量级弹出窗口中没有焦点
我想在弹出窗口中显示一个文本文件。当弹出窗口完全覆盖在应用程序框架上时(MediumWeightPopup)-一切正常,但当弹出窗口的一部分位于框架外时(HeavweightPopup),它无法聚焦。在这种情况下,插入符号是不可见的,无法输入文本 这是我的密码:Java JTextField在重量级弹出窗口中没有焦点,java,swing,popup,Java,Swing,Popup,我想在弹出窗口中显示一个文本文件。当弹出窗口完全覆盖在应用程序框架上时(MediumWeightPopup)-一切正常,但当弹出窗口的一部分位于框架外时(HeavweightPopup),它无法聚焦。在这种情况下,插入符号是不可见的,无法输入文本 这是我的密码: import java.awt.BorderLayout; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swin
import java.awt.BorderLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.Popup;
import javax.swing.PopupFactory;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class PopupTest {
public static void main(String[] args) {
JFrame frm = new JFrame("Popup test");
JPanel p = new JPanel();
p.addMouseListener(new MouseAdapter() {
Popup pop;
@Override
public void mouseReleased(MouseEvent e) {
if (SwingUtilities.isRightMouseButton(e)) {
if (pop != null) {
pop.hide();
}
JPanel popupPanel = new JPanel(new BorderLayout());
JTextField field = new JTextField(20);
popupPanel.add(field);
pop = PopupFactory.getSharedInstance().getPopup(p, popupPanel, e.getXOnScreen(), e.getYOnScreen());
pop.show();
System.out.println("Popup type: " + pop.getClass().getName());
System.out.println("Can get focus? " + field.requestFocusInWindow());
}
}
});
frm.add(p);
frm.setSize(500, 300);
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.setLocationRelativeTo(null);
frm.setVisible(true);
}
}
在窗口右边框附近单击鼠标右键,我得到一个不可聚焦的文本字段。弹出窗口中允许键控制的任何其他组件(例如JTable)也存在同样的问题
如何在重量级人物中聚焦某个组件?几年前我也在努力解决这个问题。我不知道如何在弹出窗口中为组件提供初始焦点。以下是我的一些问题/意见: 弹出类的用途是什么 我一直认为弹出窗口应该具有一些基本功能,例如在以下情况下,弹出窗口应该关闭: a) 按下退出键 b) 弹出窗口失去焦点 popup类不提供上述任何功能,实际上似乎需要一些模糊的代码才能使键盘焦点正常工作 使用JWindow似乎提供了与弹出窗口相同的功能 JPOppMenu似乎支持上述两种需求 运行以下程序: a) 单击每个按钮 b) 单击框架的空白部分 在我看来,无论何时需要“弹出窗口”,都应该使用
jpopmpmenu
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;
public class PopupTest extends JFrame
{
String[] numbers = { "one", "two", "three", "four", "five" };
public PopupTest()
{
getContentPane().setLayout( new FlowLayout() );
getContentPane().setBackground(Color.YELLOW);
JButton popup = new JButton("Popup as Popup");
popup.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
popupPopup(e);
}
});
getContentPane().add(popup);
JButton window = new JButton("Window as Popup");
window.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
windowPopup(e);
}
});
getContentPane().add(window);
JButton menu = new JButton("PopupMenu as Popup");
menu.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
menuPopup(e);
}
});
getContentPane().add(menu);
}
private void popupPopup(ActionEvent e)
{
JList list = new JList(numbers);
list.setSelectedIndex(0);
PopupFactory factory = PopupFactory.getSharedInstance();
Popup popup = factory.getPopup(this, list, getLocation().x, getLocation().y+100);
//popup.show();
Window window = SwingUtilities.windowForComponent(list);
if (window != null)
{
window.setFocusableWindowState(true);
}
popup.show();
KeyboardFocusManager.getCurrentKeyboardFocusManager().focusNextComponent(list);
}
private void windowPopup(ActionEvent e)
{
JList list = new JList(numbers);
list.setSelectedIndex(0);
JWindow window = new JWindow(this);
window.getContentPane().add(list);
window.pack();
window.setVisible(true);
window.setLocation(getLocation().x + 200, getLocation().y+100);
window.addWindowListener( new WindowAdapter()
{
public void windowDeactivated(WindowEvent e)
{
System.out.println("deactivated");
}
});
}
private void menuPopup(ActionEvent e)
{
JList list = new JList(numbers);
list.setSelectedIndex(0);
JPopupMenu menu = new JPopupMenu();
menu.add( new JTextField(10) );
menu.add( list );
menu.show((Component)e.getSource(), 0, 100);
}
private static void createAndShowGUI()
{
JFrame frame = new PopupTest();
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setSize(500, 200);
frame.setLocationRelativeTo( null );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater( () -> createAndShowGUI() );
/*
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
*/
}
}
编辑:
根据Sergiy的回答,该代码几乎可以正常工作。
popuppop()
方法的区别在于,在使窗口成为焦点后,需要调用show()
方法。更新代码以反映此更改。源代码分析为我带来了另一个解决方案
pop = PopupFactory.getSharedInstance().getPopup(p, popupPanel, e.getXOnScreen(), e.getYOnScreen());
// some new stuff
Window win = SwingUtilities.windowForComponent(popupPanel);
if (win instanceof JWindow && win.getType() == Window.Type.POPUP) {
win.setFocusableWindowState(true);
}
// continue old stuff
pop.show();
因此,完整的示例如下所示
import java.awt.BorderLayout;
import java.awt.Window;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JWindow;
import javax.swing.Popup;
import javax.swing.PopupFactory;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class PopupTest {
public static void main(String[] args) {
JFrame frm = new JFrame("Popup test");
JPanel p = new JPanel();
p.addMouseListener(new MouseAdapter() {
Popup pop;
@Override
public void mouseReleased(MouseEvent e) {
if (SwingUtilities.isRightMouseButton(e)) {
if (pop != null) {
pop.hide();
}
JPanel popupPanel = new JPanel(new BorderLayout());
JTextField field = new JTextField(20);
popupPanel.add(field);
pop = PopupFactory.getSharedInstance().getPopup(p, popupPanel, e.getXOnScreen(), e.getYOnScreen());
Window win = SwingUtilities.windowForComponent(popupPanel);
if (win instanceof JWindow && win.getType() == Window.Type.POPUP) {
win.setFocusableWindowState(true);
}
pop.show();
System.out.println("Popup type: " + pop.getClass().getName());
System.out.println("Can get focus? " + field.requestFocusInWindow());
}
}
});
frm.add(p);
frm.setSize(500, 300);
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.setLocationRelativeTo(null);
frm.setVisible(true);
}
}
有趣的:调用字段。requestFocusInWindow()
仍然返回false,但字段仍然获得焦点
BTW:这个解决方案对我来说也更好,因为在我的真实代码中,我从一个
JComboBox
中获得弹出窗口(我的目标是创建JTableComboBox
,弹出窗口中有一个表格,表格顶部有一个可选的过滤器字段)。感谢这个解决方案(我的upvote+标记为已接受)。也许我会在别的地方用。但是我找到了另一个,在我的情况下更好。你能解释一下为什么Window.setFocusableWindowsState(true)解决了这个问题吗?如果在将GetFocusableWindowsState设置为true之前调用它,它也会返回true。不明白为什么。。。