Blu*_*lub 6 java user-interface swing awt
我想让JFrame的一部分透明化.它应该看起来像OneNote Screen Clipper.我基本上有一个部分透明的JFrame的全屏叠加,然后在这个JFrame中我想通过拖动鼠标制作一些矩形并使这些矩形完全透明,如下所示:
---------------------------------------
| partially transparent |
| |
| ----------- |
| | fully | |
| | transp. | |
| ----------- |
----------------------------------------
Run Code Online (Sandbox Code Playgroud)
我该怎么办?目前我有这个:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
但这不能正常工作,因为它重复背景很多次,因此它会变得更暗/更不透明,而且它也很慢......因为重新绘制需要花费很多时间并且非常明显.
我自己终于弄清楚了:
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我们可以使用 te AlphaComposite.CLEAR 来消除背景的不透明度(至少这是它在这里所做的)。