我想在弹出窗口中显示一个文本。当弹出完全在应用程序框架上时 (MediumWeightPopup) - 一切正常,但是当弹出的一部分在框架之外 (HeavyWeightPopup) 时,它无法聚焦。在这种情况下,插入符号是不可见的,并且无法输入文本。
这是我的代码:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
在窗口右边框附近右键单击,我得到一个不可聚焦的文本字段。我在弹出窗口中允许键控制的任何其他组件(例如 JTable)中遇到了同样的问题。
如何在 HeavyWeightPopup 中聚焦组件?
几年前我也曾为此苦苦挣扎。我不知道如何将初始焦点放在弹出窗口上的组件上。以下是我的一些问题/观察:
Popup 类是用来做什么的?
我一直认为 Popup 应该具有一些基本功能,例如 pupup 应该在以下情况下关闭:
a) 按下退出键 b) 弹出窗口失去焦点
弹出类不提供上述任何功能,实际上似乎需要一些晦涩的代码才能使键盘焦点正常工作。
使用 JWindow 似乎提供与 Popup 相同的功能。
JPopupMenu 似乎支持上述两个要求。
运行以下程序:
a) 单击每个按钮 b) 单击框架的空白部分
在我看来,每当您需要“弹出窗口”时,您都应该使用JPopupMenu.
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();
}
});
*/
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:
根据 Sergiy 的回答,这段代码已经接近工作了。该方法的不同之处popupPopup()在于,show()需要在窗口变得可聚焦之后调用该方法。更新了代码以反映此更改。