【问题标题】:JFrame - only a part transparentJFrame - 只有一部分透明
【发布时间】:2014-06-25 19:55:55
【问题描述】:

我想让 JFrame 的一部分透明。 它应该看起来像 OneNote 屏幕剪辑器。我基本上有一个部分透明的 JFrame 的全屏覆盖,然后在这个 JFrame 内我想通过拖动鼠标制作一些矩形并使这些矩形完全透明,如下所示:

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

我该怎么做?目前我有这个:

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();
    }
}

但这不能正常工作,因为它会多次重绘背景,因此它会变得更暗/不那么透明,而且速度很慢......重绘需要很多时间并且非常明显。

【问题讨论】:

  • 不要覆盖paint,而是覆盖paintComponent()。此外,如果您没有实现所有方法,请使用适配器而不是侦听器。
  • 你的意思是paintComponents()吗? JFrame 中没有paintComponent()。如果我这样做,它不再绘制任何东西,只显示 JFrame :/

标签: java swing user-interface awt


【解决方案1】:

作为一个快速修复,调用

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

而不是repaint()

不过,这不是最好的方法。

【讨论】:

    【解决方案2】:

    我自己终于想通了:

    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();
            }
        }
    }
    

    我们可以只使用 te AlphaComposite.CLEAR 它将从背景中移除不透明度(至少这是它在这里所做的)。

    【讨论】:

    • 并用适配器替换监听器。
    • 顺便说一句,您的代码使您只能向下和向右拖动矩形。您不想让原点成为右下角吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-15
    • 1970-01-01
    • 2015-02-17
    • 2011-02-01
    • 1970-01-01
    • 2019-04-01
    • 1970-01-01
    相关资源
    最近更新 更多