JFrame - only part transparent

I want to make a part of a transparent JFrame. It should look just like OneNote Screen Clipper. I basically have a fullscreen overlay of a partially transparent JFrame, and then inside that JFrame. I want to make some rectangles by dragging the mouse and making these rectangles completely transparent, for example:

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

How can I do it? I currently 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 does not work correctly, because it redraws the background many times, and therefore it becomes darker / less transparent, and also slow, like hell ... relayings take a lot of time and are very noticeable.

+6
source share
2 answers

I finally figured this out:

 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's what it does here).

0
source

As a quick fix, call

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

instead of repaint() .

However, this is not the best way to do this.

0
source

All Articles