关于Java swing组件焦点的问题(我猜可能是焦点的问题) 高分求全面
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于Java swing组件焦点的问题(我猜可能是焦点的问题) 高分求全面相关的知识,希望对你有一定的参考价值。
超级菜鸟 不懂 求指点
如图所示,焦点是在JTextField上 还是在JButton“确定”上?
这种效果是怎么实现的?
即当焦点在JTextfield时 确定按钮变蓝 按回车后 "确定"按钮被按下。
----------------------------------------------------------------------------------------
1.这个对话框是直接调用的我知道。我只是说其中效果。
2.我曾经用在JTextField中KeyListener,if(e.getKeyCode()==KeyEvent.VK_ENTER) button.doClick();可以实现类似功能,但效果不同(按钮不蓝)
3.还有为什么我每次JButton用requestFocus(),requestFocusInWindow()什么的都没用。
------------------------------------------------------------------------------------------------------------------
菜鸟发帖若提问有不妥之处,请多指教,勿拍。
对于发的截图,我估计是对方使得鼠标在输入框时将焦点变位“确定”按钮,或者整个window组件只有“确定”按钮设置焦点选中,这样enter键会按下确定,这样是不符合逻辑的,应该鼠标在哪个组件哪个组件为当前组件(即选中),估计是对方并不知道button的doClick方法(或者直接调用“确定”按钮的事件)或者习惯性那样不合理的用法。 参考技术A 按钮不蓝?你只要把“确定”按钮的背景色,设置成蓝色,就行了啊。
也就是说,你在生成那个“确定”时,把它的背景色设置成蓝色,之后用你问题中说的那个第二步,就完成了你的要求! 参考技术B 焦点这一块,使用:requestFocus();
至于按回车,激活确定按钮,只需使用:setDefaultButton(JButton button) 方法,将确定按钮设为默认按钮。本回答被提问者采纳 参考技术C JButton.setFoceable(true),然后再获取焦点
Java Swing如何让JFrame获得焦点
【中文标题】Java Swing如何让JFrame获得焦点【英文标题】:Java Swing how to let the JFrame gain focus 【发布时间】:2020-10-01 15:09:44 【问题描述】:我正在开发一个 java swing 应用程序。我希望达到这样的结果:按下快捷方式让应用程序窗口出现。再次按下快捷键或点击其他地方让应用隐藏。
我使用jkeymaster注册监听全局快捷键事件,效果很好。 但是当用户关注其他一些窗口时,比如 chrome、office ......焦点窗口将是其他应用程序。然后如果用户使用快捷方式。我的应用程序窗口仍会显示,但无法获得焦点。谁能帮我解决它。这是我的代码 sn-p。
Provider provider = Provider.getCurrentProvider(true);
// bind shortcut
provider.register(KeyStroke.getKeyStroke(KeyEvent.VK_PLUS, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()), x ->
homePage.setVisible(!homePage.isVisible());
if(homePage.isVisible())
// TODO: 2020/10/1 request focus here
homePage.requestFocusInWindow();
homePage.requestFocus();
KeyboardFocusManager focusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
focusManager.clearGlobalFocusOwner();
log.info("hasFocus? " + homePage.hasFocus());
log.info("isActive? " + homePage.isActive());
);
我尝试过的:
-
requestFocus 和 requestFocusInWindow,不起作用
我阅读了requestFocus的源代码。它说
* This method cannot be used to set the focus owner to no Component at
* all. Use <code>KeyboardFocusManager.clearGlobalFocusOwner()</code>
* instead.
所以我尝试了 focusManager.clearGlobalFocusOwner() 但它仍然不起作用。
【问题讨论】:
也许grabFocus()
会起作用?
@camickr 感谢您的建议,但 JFrame 有 grabFocus 方法。我尝试了 homePage.getRootPane().grabFocus() 但仍然无效。
【参考方案1】:
通常,当您想在父容器中获得焦点时(例如 JPanel
、JFrame
等),您可以通过将 requestFocusInWindow()
方法调用到它的其中一个子容器中来请求焦点。
我建议你不要在JFrame
中要求焦点。在其中一个组件中调用requestFocusInWindow()
。
现在就 UX 而言,我会将焦点放回最后关注的组件。为了获得JFrame
的焦点组件,我们调用jframe.getFocusOwner()
。但是,如果JFrame
处于状态MINIMIZED
或在后台,由于它没有焦点,getFocusOwner
返回null
。
因此,为了在调用全局键侦听器之前找到最后一个获得焦点的组件,您也可以为焦点事件注册一个全局 AWT 侦听器:
Toolkit.getDefaultToolkit().addAWTEventListener(e ->
if (e.getID() == FocusEvent.FOCUS_LOST)
if (e.getSource() instanceof Component)
lastFocusedComponent = (Component) e.getSource();
, FocusEvent.FOCUS_EVENT_MASK);
每次焦点改变时都会触发监听器。因此,您可以安全地获得具有焦点的实际最后一个组件,从而消除成为 null
的机会,因为它是触发事件的组件。
之后你所要做的就是给它打电话requestFocusInWindow
:
provider.register(KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD0, 0), e ->
frame.setVisible(!frame.isVisible());
if (frame.isVisible())
SwingUtilities.invokeLater(lastFocusedComponent::requestFocusInWindow);
);
一个有效的完整示例(您可以自己确认焦点已恢复):
public class FocusExample
private static Component lastFocusedComponent;
public static void main(String[] args)
SwingUtilities.invokeLater(() ->
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTextField leftField = new JTextField(10);
JTextField rightField = new JTextField(10);
frame.setLayout(new FlowLayout());
frame.add(leftField);
frame.add(rightField);
Toolkit.getDefaultToolkit().addAWTEventListener(e ->
if (e.getID() == FocusEvent.FOCUS_LOST)
if (e.getSource() instanceof Component)
lastFocusedComponent = (Component) e.getSource();
, FocusEvent.FOCUS_EVENT_MASK);
Provider provider = Provider.getCurrentProvider(true);
provider.register(KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD0, 0), e ->
frame.setVisible(!frame.isVisible());
if (frame.isVisible())
SwingUtilities.invokeLater(lastFocusedComponent::requestFocusInWindow);
);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
);
【讨论】:
感谢您的建议。它确实达到了您实际所说的结果,但这不是我想要的。我希望 JFrame 可以抓住焦点,因为另一个需要是“当 JFrame 失去焦点时 JFrame 应该自动隐藏”。如果 JFrame 出现时无法获得焦点,我无法监控它的 focuslost 事件。我认为不同平台上的实现是不同的。你能给我一些进一步的建议吗?【参考方案2】:我尝试了一个丑陋的解决方案,使用机器人来模拟用户点击以获得焦点。调用 click 方法时,光标会消失一会儿。但它确实有效(成功获得焦点)
我所做的是:
1.
RobotTool.click((int)windowLocation.getX(), (int)windowLocation.getY());
public class RobotTool
private static Robot robot = Singleton.get(Robot.class);
public static void click(int x, int y)
Point mouseInitPosition = MouseInfo.getPointerInfo().getLocation();
int mask = InputEvent.BUTTON1_MASK;
robot.mouseMove(x, y);
try
// wait 100ms to avoid the robot action out of order
Thread.sleep(100);
catch (InterruptedException e)
e.printStackTrace();
robot.mousePress(mask);
robot.mouseRelease(mask);
robot.mouseMove((int)mouseInitPosition.getX(), (int)mouseInitPosition.getY());
【讨论】:
RobotTool
是 java 类吗?我不熟悉它。
@Abra 抱歉,这是我的自定义工具。我刚刚更新了代码。以上是关于关于Java swing组件焦点的问题(我猜可能是焦点的问题) 高分求全面的主要内容,如果未能解决你的问题,请参考以下文章
java swing中如何自行丢失焦点?已知怎样获取没找到如何丢失!