JPanel 使用透明 JFrame 不能很好地重新绘制

Posted

技术标签:

【中文标题】JPanel 使用透明 JFrame 不能很好地重新绘制【英文标题】:JPanel doesn't repaint well using transparent JFrame 【发布时间】:2019-10-12 15:51:55 【问题描述】:

我正在尝试在透明的 JFrame 上重绘 JPanel,但它会留下之前重绘的标记:

previous repaint keeps showing

我知道这是一个已知问题,并且已经发布了一个类似的问题,但答案仅解释了为什么它不起作用并且他们没有给出解决方案。

任何人都可以更改代码或添加一些代码,以达到预期的效果吗? (在透明背景上跟随鼠标的十字)

我不想把桌面拍下来画在JPanel里。

代码如下

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

final class Transparency extends JFrame
    private NewPanel np;

    Transparency()
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setUndecorated(true);
        setLocation(200,200);
        setBackground(new Color(0,0,0,0));

        np = new NewPanel();
        setContentPane(np);

        pack();
        setVisible(true);
    

    public static void main(String []args)
        Transparency li = new Transparency();
    


final class NewPanel extends JPanel
    private Point p = new Point(0,0);
    private final int length = 25;

    NewPanel()
        setPreferredSize(new Dimension(400,400));
        setOpaque(false);
        addMouseMotionListener(new MouseAdapter()
            public void mouseMoved(MouseEvent e)
                p = e.getPoint();
                repaint();
            
        );
    

    public void paintComponent(Graphics g)
        super.paintComponent(g);

        g.setColor(Color.GREEN);
        g.drawLine(p.x-length,p.y,p.x+length,p.y);
        g.drawLine(p.x,p.y-length,p.x,p.y+length);

        g.setColor(Color.WHITE);
        g.drawRect(0,0,399,399);
    

【问题讨论】:

您使用的是什么操作系统和 Java 版本?无法使用 Java 11 在 macOS 10.14.5 上复制它 @MadProgrammer 我在 Ubuntu 16.04 上使用了 Java 8.191。我了解 Java 9 或更高版本仅适用于 64 位计算机,而我的是 32 位计算机。可能是旧版本的 Java 造成了这种影响? “似乎”是 Linux 的问题???? 【参考方案1】:

由于没有重量级的***组件,你需要自己管理后台。

将此添加到您的paintComponent 方法中,就在super.paintComponent 之后:

g.clearRect(0, 0, getWidth(), getHeight());

【讨论】:

JFrame 延伸自 Frame,延伸自 WindowContainerComponentJPanel 延伸自 JComponentContainerComponent - 所以,大量的举重活动在那里进行。虽然“建议”可能有效,但它并不能解决问题的原因,因为我无法在我的系统上复制它 @MadProgrammer 很有趣。我能够使用 Java 11 在 Linux 中复制该问题。虽然每个窗口在技术上都是重量级的,但我认为透明窗口不能提供轻量级组件通常需要的重量级背景。 由于它似乎可以在 Windows 和 MacOS 上运行,这可能是与 Linux 无关的问题 - 如果这是 OPs 的情况,那么该解决方案可能是目前最好的选择 @VGR 不幸的是,这条线没有解决问题。正如 MadProgrammer 所说,这似乎是一个 Linux 问题。我使用 Java 8.111 在 WIndows 10 上测试了相同的代码,它产生了不同的不良效果,但我能够通过将非零 alpha 值设置为 JFrame 的背景颜色来解决它。

以上是关于JPanel 使用透明 JFrame 不能很好地重新绘制的主要内容,如果未能解决你的问题,请参考以下文章

过渡和不透明度不能很好地协同工作

JPanel与JFrame的区别

如何在jframe中的jpanel中设置单选按钮?

Java 的 setFocusableWindowState 和 setAccelerator 不能很好地发挥作用

JFrame / JPanel不会更新重绘或重新验证

为什么我不能在jpanel上创建一个形状?