在(嵌入式)Ubuntu 12.04 系统上,我们有一个简单的 Java 程序,它在窗口上显示一些图形模式,大约每秒更新一次。我们用它来监控系统上运行的一些进程。问题在于,虽然它处于活动状态且未最小化,但它会在窗口更新时窃取焦点。这使得使用打开的终端窗口变得不可能。
运行应用程序表单命令行或从 Eclipse IDE 时,行为是相同的。
在 NetBeans IDE 下运行时,在 Windows 7 上不会出现同样的问题。
我们如何防止 Java 应用程序窃取 Ubuntu 机器上的焦点?
更新 1:发现这个问题似乎与同样的问题有困难: 如何停止/解决 Java 应用程序在 Linux 窗口管理器中窃取焦点。阅读它,我了解到问题在于使用 JFrame 作为容器,这就是我们使用的。他们的解决方案是使用 JWindow 容器而不是 JFrame 容器。然而,在寻找差异时,JWindow 是“裸露的”,不像“真正的”窗口,因为没有装饰。有没有办法在JFrame 中使用 JWindow,从而消除焦点窃取?
更新 2:尝试在 PC 上的 Ubuntu 虚拟机上运行此程序会产生相同的不当行为。这表明 Windows 7 和 Linux 的 Java 运行时存在差异,并且该问题并非特定于 Embedded linux。
更新 3:这是一个 SSCCE:
//package SSCCE;
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
public class MonitorSSCCE extends JFrame{
public static void main(String[] args)
{
// Set the frame
JFrame ecoreFrame = new JFrame("SSCCE");
ecoreFrame.setSize(120, 120);
ecoreFrame.setVisible(true);
// Refresh frame every 200 msec
while (true) {
GRFX grfx = new GRFX();
ecoreFrame.add(grfx);
ecoreFrame.setVisible(true);
grfx = null;
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
}
}
static int clr = 0;
public static class GRFX extends JPanel {
public void paintComponent(Graphics comp) {
Graphics2D comp2D = (Graphics2D) comp;
// Draw a changin color rectangle
comp2D.setColor(new Color(clr, 0, 0));
Rectangle2D.Double rect = new Rectangle2D.Double(10, 10, 100, 100);
comp2D.fill(rect);
clr = clr + 10;
if (clr > 255)
clr = 0;
}
}
}
更新 4:在准备 SSCCE 时,我阅读并了解了 JFrame 对象的大量窗口刷新方法。碰巧问题出在循环setVisible()
内的调用上。while
解决方案是用repaint()
方法替换它。