java - 透明 JFrame 重绘时不清晰

标签 java swing jframe

当我尝试重新绘制透明窗口并在其上绘制矩形时,之前的矩形将保留。目标是通过单击并移动鼠标来选择屏幕上的区域。 It'll look like this if you move your mouse for a while

通过删除透明度,效果很好。

我尝试了在 Stack Overflow 上能找到的有关此主题的所有内容,但无法使其在 Windows 和 Linux 上都运行。

主类

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;

public class Main {
    private JFrame frame;
    private boolean pressing = false;
    private boolean selected = false;
    private ScreenSelectPanel p;

    public Main() {
        Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
        frame = new JFrame("ScreenSelection");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setSize(dim);
        frame.setUndecorated(true);

        frame.setContentPane(p = new ScreenSelectPanel());
        registerListeners();

        frame.getContentPane().setBackground(new Color(255, 255, 255,    0));
        frame.setBackground(new Color(255, 255, 255, 0));
        frame.setLayout(new BorderLayout());

        frame.setAlwaysOnTop(true);
        frame.setVisible(true);
    }

    private void registerListeners() {
        p.setFocusable(true);
        p.requestFocusInWindow();

        p.addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseDragged(MouseEvent e) {
                if (selected)
                    return;
                setLoc(e);
                p.repaint();

            }

            @Override
            public void mouseMoved(MouseEvent e) {
                if (selected)
                    return;
                setLoc(e);
                if (!pressing)
                    setStartLoc(e);
                p.repaint();
            }
        });
        p.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                setLoc(e);
                setStartLoc(e);
                p.repaint();
            }

            @Override
            public void mouseEntered(MouseEvent e) {
                setLoc(e);
                setStartLoc(e);
                p.repaint();

            }
        });
    }

    public void setStartLoc(MouseEvent e) {
        p.mouseStartX = e.getX();
        p.mouseStartY = e.getY();
    }

    public void setLoc(MouseEvent e) {
        p.mouseX = e.getX();
        p.mouseY = e.getY();
    }

    public static void main(String[] args) {
        new Main();
    }
}

ScreenSelectPanel类

import javax.swing.*;
import java.awt.*;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;

public class ScreenSelectPanel extends JPanel {
    public int mouseX = 0;
    public int mouseY = 0;
    public int mouseStartX = 0;
    public int mouseStartY = 0;

    private Color borderColor;

    public ScreenSelectPanel() {
        setOpaque(false);
        borderColor = Color.BLACK;
    }

    public void setBorderColor(Color c) {
        this.borderColor = c;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        Graphics2D g2d = (Graphics2D) g;

        g2d.setColor(borderColor);
        Rectangle rect = new Rectangle();
        rect.setFrameFromDiagonal(new Point2D.Float(mouseStartX, mouseStartY), new Point2D.Float(mouseX, mouseY));
        Stroke dashed = new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[]{9}, 0);
        g2d.setStroke(dashed);
        g2d.drawRect(rect.x, rect.y, rect.width, rect.height);

        g2d.dispose();
    }

}

谢谢:)

最佳答案

您不能对 Swing 组件使用透明度。透明背景会导致这些类型的绘画问题。 Swing 组件要么是不透明的,要么是非透明的。

查看Backgrounds With Transparency有关此问题的更多信息。然而,在这种情况下,这不是问题,因为您正在尝试在 Swing 面板上使用完全透明。

When I try to repaint a transparent window, and draw a rectangle on it, the previous rectangle will stay.

您发布的代码可以执行任何操作(至少在 Windows 上)。当您将框架设置为完全透明时,MouseEvent 不再由 Swing 处理,而是由框架下方的应用程序处理。

我对您的代码进行了以下更改,它似乎对我有用:

//frame.getContentPane().setBackground(new Color(255, 255, 255,    0));
//frame.setBackground(new Color(255, 255, 255, 0));
frame.setBackground(new Color(255, 255, 255, 10));

关于java - 透明 JFrame 重绘时不清晰,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36943970/

相关文章:

java - 'this' 关键字的范围问题

Java:声明一个变量但说它不存在

java - xDoclet、Maven 和 Hibernate

java - Spring @Autowired 为空

java - 为什么jDateChooser的值又回到默认值了?

java - 如何使用 HATEOAS 通过 @JoinTable 获取信息

java - Gui 的按钮布局问题

java - JTable:如何使 JComboBox 单元格渲染器比渲染的单元格更大?

java - BFS 图遍历 - 将新节点追加到邻接矩阵

java - 如何查找 JFrame 中某个像素的颜色?