gpt4 book ai didi

java - 如何防止 Java 图形程序在更新窗口时窃取焦点?

转载 作者:搜寻专家 更新时间:2023-10-31 20:28:53 25 4
gpt4 key购买 nike

在(嵌入式)Ubuntu 12.04 系统上,我们有一个简单的 Java 程序,可以在窗口上显示一些图形模式,大约每秒更新一次。我们用它来监控系统上运行的一些进程。问题在于,虽然它处于 Activity 状态且未最小化,但每当更新窗口时它都会窃取焦点。这使得无法使用打开的终端窗口。

运行应用程序表单命令行或从 Eclipse IDE 时的行为是相同的。

在 Windows 7 下运行 NetBeans IDE 时不会出现同样的问题。

我们如何防止 Java 应用程序窃取 Ubuntu 机器上的焦点?


更新 1: 发现这个问题似乎与同样的问题作斗争: How do I stop/workaround Java apps stealing focus in Linux window managers .阅读它,我了解到问题在于使用 JFrame 作为容器,这就是我们使用的容器。他们的解决方案是使用 JWindow 容器而不是 JFrame 容器。然而,寻找差异,JWindow 是“裸”的,并且表现得不像“真正的”窗口,因为没有装饰。有没有办法在 JFrame 中使用 JWindow,从而消除焦点窃取?


更新 2:尝试在 PC 上的 Ubuntu 虚拟机上运行此程序会产生相同的错误行为。这表明 Windows 7 和 Linux 的 Java 运行时存在差异,并且问题并非特定于嵌入式 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 对象的大量窗口刷新方法。碰巧问题是 while 循环内的 setVisible() 调用。解决方案是将其替换为 repaint() 方法。

最佳答案

在带有 Unity 窗口管理器的 Ubuntu 12.04.2 上,这个 example在后台以 1 Hz 的频率在桌面上正常运行,同时终端和软件更新也在运行。几个可供比较的引用点:

附录:我在下面重构了您的示例以说明一些额外的要点:

image

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Rectangle2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

/**
* @see https://stackoverflow.com/a/18455006/230513
*/
public class TestGRFX {

private static class GRFX extends JPanel {

private static final int N = 256;
private float clr = 0;
private Rectangle2D.Double rect = new Rectangle2D.Double(0, 0, N, N);
private Timer t = new Timer(100, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
GRFX.this.repaint();
}
});

public void start() {
t.start();
}

@Override
public void paintComponent(Graphics g) {
Graphics2D g2D = (Graphics2D) g;
g2D.setColor(new Color(Color.HSBtoRGB(clr, 1, 1)));
g2D.fill(rect);
clr += .01;
}

@Override
public Dimension getPreferredSize() {
return new Dimension(N, N);
}
}

private void display() {
JFrame f = new JFrame("TestGRFX");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GRFX g = new GRFX();
f.add(g);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
g.start();
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new TestGRFX().display();
}
});
}
}

关于java - 如何防止 Java 图形程序在更新窗口时窃取焦点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18452446/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com