在JPanel上绘制而不重绘背景图像

时间:2015-03-04 18:10:37

标签: java image swing jpanel paint

我正在尝试制作一个截图工具,以全屏模式向用户显示截图。然后用户将使用一些工具对其进行编辑。 在创建它时,我遇到了一些可视化效果的问题。 我想使用选择矩形(不知道确切的术语名称)创建所选区域的可视化表示,用于在桌面或文件资源管理器上选择多个文件。 example image link

我尝试在背景图片上绘制矩形,但是当我试图移动光标时,图像令人耳目一新。 然后我尝试使用setOpaque(false);setBackground(new Color(0,0,0,0));进行透明面板,而不是在此面板上固定鼠标侦听器。 它成功绘制矩形,但面板的背景立即填充默认的灰色。 如何在不重新绘制背景图像的情况下使前景面板透明并在其上绘制内容? 这是我的Glass课程:

private static final int WIDE = 1920;
private static final int HIGH = 1080;
private final Color clean = new Color(0,0,0,0);
private Point mousePt = new Point(WIDE / 2, HIGH / 2);
private Rectangle mouseRect = new Rectangle();


Glass(){
    this.setOpaque(false);
    this.setBackground(clean);
    this.addMouseListener(new MouseHandler());
    this.addMouseMotionListener(new MouseMotionHandler());
}
public void paintComponent(Graphics g) {  
    g.setColor(clean);
    g.fillRect(0, 0, 1920, 1080 );
    g.setColor(Color.darkGray);
    g.drawRect(mouseRect.x, mouseRect.y, mouseRect.width, mouseRect.height);
}
private class MouseHandler extends MouseAdapter {

    public void mouseReleased(MouseEvent e) {
        System.out.println("released");
        mouseRect.setBounds(0, 0, 0, 0);
        e.getComponent().repaint();
    }

    public void mousePressed(MouseEvent e) {
        mousePt = e.getPoint();
        System.out.println("pressed");
        e.getComponent().repaint();
    }
}
private class MouseMotionHandler extends MouseMotionAdapter {
    public void mouseDragged(MouseEvent e){
         mouseRect.setBounds(
              Math.min(mousePt.x, e.getX()),
              Math.min(mousePt.y, e.getY()),
              Math.abs(mousePt.x - e.getX()),
              Math.abs(mousePt.y - e.getY())); 
        e.getComponent().repaint();
    }
} 

1 个答案:

答案 0 :(得分:1)

您是否已尝试将super.paintComponent(g)添加到paintComponent方法的开头,如下所示:

public void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.setColor(clean);
    g.fillRect(0, 0, 1920, 1080 );
    g.setColor(Color.darkGray);
    g.drawRect(mouseRect.x, mouseRect.y, mouseRect.width, mouseRect.height);
}

另一种可能性是对所有绘图使用JPanel,并且只在paintComponent方法中绘制背景图像:

class DrawPanel extends JPanel{
    public DrawPanel(){
        //...
    }

    @Override
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        //Draw background
        g.drawImage(yourImage, 0, 0);

        //Your drawing
        g.setColor(Color.darkGray);
        g.drawRect(mouseRect.x, mouseRect.y, mouseRect.width, mouseRect.height);
    }
}

使用JPanel而不是java.awt.Panel将使用双缓冲并避免在绘制时出现任何闪烁。

您的父容器代码可能如下所示:

public MainFrame(){
    //...

    //Your old code
    //background image...
    //getContentPane().add(glass);

    getContentPane().add(drawPanel);
}