简体   繁体   中英

JFrame - only a part transparent

I want to make a part of a JFrame transparent. It should look similar like OneNote Screen Clipper. I basically have a fullscreen overlay of a partially transparent JFrame and then inside this JFrame I want to make some rectangles by dragging the mouse and make those rectangles fully transparent, like so:

---------------------------------------
|        partially transparent         |
|                                      |
|      -----------                     |
|      | fully   |                     |
|      | transp. |                     |
|      -----------                     |
----------------------------------------

How would I do that? Currently I have this:

public class Overlay extends JFrame implements MouseMotionListener, MouseListener {

    private Rectangle2D.Double selection;
        private Point start;
        private Point end;

    public Overlay() {
        addMouseMotionListener(this);
        addMouseListener(this);
        setSize(Toolkit.getDefaultToolkit().getScreenSize());
        setAlwaysOnTop(true);
        setUndecorated(true);
        setOpacity(0.2f);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    @Override
    public void paint(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        g2d.clearRect(0, 0, getWidth(), getHeight());

        if (selection != null) {

            Area outside = new Area(new Rectangle2D.Double(0, 0, getWidth(), getHeight()));
            outside.subtract(new Area(selection));


            g2d.setClip(outside);               
            g2d.setColor(new Color(0.5f,0.5f,0.5f, 0.5f));
            g2d.fillRect(0, 0, getWidth(), getHeight());
        }

    @Override
    public void mousePressed(MouseEvent e) {

        start = e.getLocationOnScreen();
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        end = e.getLocationOnScreen();
        selection =  new Rectangle2D.Double(start.x, start.y, end.x - start.x, end.y - start.y);
        repaint();
    }
}

But this doesn't work correctly as it repaints the background many times, and therefore it becomes darker/less transparent and also it is slow as hell.... the repaints take a lot of time and are very visible.

As a quickfix, call

repaint((int) selection.x,(int) selection.y,(int) selection.width,(int) selection.height);

instead of repaint() .

Still, this is not the best way of doing it.

I figured it out myself finally:

public class Overlay extends JFrame {
    private Point start = new Point();
    private Point end = new Point();

    public Overlay() {
        OverlayMouseAdapter listener = new OverlayMouseAdapter();
        addMouseMotionListener(listener);
        addMouseListener(listener);
        setSize(Toolkit.getDefaultToolkit().getScreenSize());
        setAlwaysOnTop(true);
        setUndecorated(true);
        setBackground(new Color(255, 255, 255, 180));
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        Graphics2D g2d = (Graphics2D) g;


        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR,
                    0.1f));
        g2d.setColor(new Color(0, 0, 0, 255));
        g2d.fillRect(start.x, start.y, end.x -start.x, end.y-start.y);

        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC));
        g2d.setColor(Color.BLACK);
        g2d.drawRect(start.x-1, start.y-1, end.x -start.x + 1, end.y-start.y+1);
    }

    private class OverlayMouseAdapter extends MouseAdapter {
        @Override
        public void mousePressed(MouseEvent e) {
            start = e.getLocationOnScreen();
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            end = e.getLocationOnScreen();
            repaint();
        }
    }
}

We can just use te AlphaComposite.CLEAR which will remove the opacity from the background (at least that is what it is doing here).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM