【问题标题】:JTextField in JFrame uneditable when using JCEF in JInternalFrame until JFrame loses focus在 JInternalFrame 中使用 JCEF 时,JFrame 中的 JTextField 不可编辑,直到 JFrame 失去焦点
【发布时间】:2020-10-31 14:26:34
【问题描述】:

我已经开始在我的一个项目中实现JCEF,我正在JFrame 内部的JInternalFrame 中初始化嵌入式浏览器,以及JPanel 旁边的一系列表单字段@ 旁边987654325@。直到JFrame 真正可见,浏览器组件才会完全初始化,我发现我的JTextFields 是不可编辑的,除非JFrame 失去并重新获得焦点。

对可能发生的事情以及如何解决它有任何想法吗?只有在将 JInternalFrame 与 JCEF 组件一起使用时才会发生这种情况...

每次我调用loadURL 在浏览器中加载新页面时也会发生这种情况:JTextFields 再次变得不可编辑,直到我失去/获得JFrame 的焦点。


更新: 我发现了一个 hack,它允许 JTextFields 再次变得可编辑,但我不会称它为解决方案,因为它不是很优雅。我在 onLoadingStateChange 方法上使用 @Ovveride 向 CefClient 实例 ( client.addLoadHandler(new CefLoadHandlerAdapter()) ) 添加了一个负载处理程序,这反过来又提供了对当前浏览器组件的访问权限。从那里我可以检测到何时在浏览器中加载完成,并使用 SwingUtilities 获取浏览器组件所在的窗口。然后我在该窗口上 setVisible(false)setVisible(true)。我说这不是一个解决方案,因为每次浏览器完成加载时,窗口都会消失并重新出现。即使JTextFields 可以再次编辑,看到窗口闪烁还是很丑陋的。我尝试了各种revalidate()repaint() 方法都无济于事,除非我没有正确调用它们...

client.addLoadHandler(new CefLoadHandlerAdapter() {
    @Override
    public void onLoadingStateChange(CefBrowser browser, boolean isLoading,
                                boolean canGoBack, boolean canGoForward) {
      if (!isLoading) {
            //browser_ready = true;
            System.out.println("Browser has finished loading!");
            SwingUtilities.windowForComponent( browser.getUIComponent() ).setVisible(false);
            SwingUtilities.windowForComponent( browser.getUIComponent() ).setVisible(true);
      }
    }
});

如果有人可以提出更好的解决方案,请提出!

【问题讨论】:

  • 看起来您正在 Swing EDT(事件调度线程)上运行一个长时间运行的进程,这可能会阻止同一线程运行。如果是这样,那么考虑使用 SwingWorker 在后台线程中执行长时间运行的任务。
  • 我有同样的预感,所以我刚刚尝试实现一个 SwingWorker 至少来处理随后的 browser.loadURL() 调用(我不确定如何控制窗口打开时的第一个渲染)。但是即使将loadURL() 进程委托给 SwingWorker,JTextFields 仍然无法编辑。没有其他组件变得不可编辑或无响应,只有 JTextFields。我尝试在 SwingWorkers 后台工作结束时致电jTextField1.revalidate(),但这并没有帮助;我试过jTextField1.setEditable(false); jTextField1.setEditable(true);,但没有帮助......
  • 澄清一下,“可编辑”属性仍设置为 true,并且悬停和焦点工作正常。 JTextField 实际上是不可编辑的,即使 "editable" 仍然设置为 true...

标签: java swing focus chromium-embedded


【解决方案1】:

通过更好地研究示例 JCEF 应用程序,我发现了问题所在。我需要实现一个 FocusHandler 以释放嵌入式浏览器对键盘输入的保留:

private boolean browserFocus_ = true;
---
jTextField1.addFocusListener(new FocusAdapter() {
    @Override
    public void focusGained(FocusEvent e) {
      if (!browserFocus_) return;
      browserFocus_ = false;
      KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
      jTextField1.requestFocus();
    }
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-11
    • 2013-02-22
    相关资源
    最近更新 更多