gpt4 book ai didi

java - 半透明 JFrame 在编程调整大小后呈现不佳

转载 作者:行者123 更新时间:2023-11-30 09:02:01 27 4
gpt4 key购买 nike

(此问题发生在使用 Java 1.7.0_45 的 Mac OS X 10.10 上。在使用 Java 1.7.0_55 的 Windows 7 上我没有遇到此问题。)

我有一个半透明的“始终在最前面”的 JFrame,其中包含 JLabel 中的一些信息。当信息发生变化时,我再次通知 JFrame 进行 pack(),以使 JFrame 尽可能小。当 JFrame 在调整大小后重新布局并绘制 JFrame 时,会出现渲染故障。

这是一个 SSCCE:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class ScratchSpace {


public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {

final JLabel label = new JLabel("Test message that is long");
label.setOpaque(false);
label.setForeground(Color.WHITE);

JLabel iconLabel = new JLabel("Label 2");

JPanel contentPane = new JPanel();
contentPane.setOpaque(false);
contentPane.add(label);

contentPane.add(iconLabel);

final JFrame hudFrame = new JFrame();
hudFrame.setAlwaysOnTop(true);
hudFrame.setType(Window.Type.UTILITY);
hudFrame.setUndecorated(true);
hudFrame.setBackground(new Color(0, 0, 0, 50));

hudFrame.setContentPane(contentPane);
hudFrame.pack();
hudFrame.setLocationRelativeTo(null);
hudFrame.setVisible(true);

Timer timer = new Timer(2000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
label.setText("Shorter test message");
hudFrame.pack();
}
});
timer.setRepeats(false);
timer.start();
}
});
}
}

这是输出的放大屏幕截图,您可以在其中看到 JFrame 没有正确重新呈现。 JFrame之前的内容给人一种苍白的印象:

enter image description here

我该怎么做才能解决这个问题,同时保持每个像素的半透明度?

最佳答案

关于正在发生的事情的信息

您看到的“苍白印象”是 Mac OS X 窗口阴影。 WindowServer 将阴影计算为窗口内容的 alpha channel 的模糊。

但是,WindowServer 不会在窗口内容更改时重新计算阴影(因为这会非常昂贵),而是仅在请求时重新计算。因此,您在这里需要的是一种确保您的 Swing 窗口在内部发出该请求的方法。

可能的解决方法

不幸的是,我没有 10.10 可以测试,所以我不知道这是否有效,但有一种情况显然需要重新计算阴影:调整窗口大小时(因为即使是非透明窗口然后得到阴影)。在这种情况下,您正在使用 pack() 调整窗口大小,因此这里一定存在某种时间/事件排序问题。

那么,我的建议是在内容更新后稍微调整窗口大小。伪代码:

  1. 像现在一样更新内容和pack()
  2. JFrame 的大小更改为比一维的打包大小大一个像素。
  3. 启动一个定时器在 0 毫秒后执行:

      再次
    1. pack(),或者只是将大小更改为更小一个像素。

代码的直接丑陋修改:

            Timer timer = new Timer(2000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
label.setText("Shorter test message");
hudFrame.pack();
Dimension d = hudFrame.getSize();
d.width += 1;
hudFrame.setSize(d);
Timer timer = new Timer(0, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
hudFrame.pack();
}
});
timer.setRepeats(false);
timer.start();
}
});
timer.setRepeats(false);
timer.start();

关于java - 半透明 JFrame 在编程调整大小后呈现不佳,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26180434/

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