创建一个消失的 JPanel?

Create a disappearing JPanel?

我正在尝试创建一个扩展的 JPanel,作为一种突出显示屏幕某些区域的方法。我从 this SO answer 中获取了一些代码,但我想进一步扩展它,尽管我不确定如何去做。

我希望能够让我的 JPanel(下面的 MatchAreaPanel)在达到给定的超时后消失。那就是 JPanel 将其可见的 属性 设置为 false 并随后自行处理。

执行此操作的最佳方法是什么?

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;

public class MatchAreaPanel extends JPanel
{
    public MatchAreaPanel()
    {

    }

    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g.create();
        g2d.setColor(new Color(128, 128, 128, 64));
        g2d.fillRect(0, 0, getWidth(), getHeight());

        float dash1[] = {10.0f};
        BasicStroke dashed = new BasicStroke(3.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash1, 0.0f);
        g2d.setColor(Color.BLACK);
        g2d.setStroke(dashed);
        g2d.drawRect(0, 0, getWidth() - 3, getHeight() - 3);
        g2d.dispose();
    }
}

您可以使用 Swing Timer 在给定延迟后简单地安排回调并关闭关联 window 或根据您的需要隐藏组件,例如...

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Random;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                Rectangle bounds = getVirtualBounds();
                Random rnd = new Random();
                int x = bounds.x + (rnd.nextInt(bounds.width) - 100);
                int y = bounds.y + (rnd.nextInt(bounds.height) - 100);

                MatchAreaPanel pane = new MatchAreaPanel();
                JWindow frame = new JWindow();
                frame.setBackground(new Color(0, 0, 0, 0));
                frame.add(pane);
                frame.setBounds(x, y, 100, 100);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
                pane.start();
            }
        });
    }

    public static Rectangle getVirtualBounds() {

        Rectangle bounds = new Rectangle(0, 0, 0, 0);

        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice gd = ge.getDefaultScreenDevice();
        bounds.add(gd.getDefaultConfiguration().getBounds());

        return bounds;

    }

    public class MatchAreaPanel extends JPanel {

        public MatchAreaPanel() {
            setOpaque(false);
            addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    SwingUtilities.windowForComponent(MatchAreaPanel.this).dispose();
                }
            });
        }

        public void start() {
            Timer timer = new Timer(5000, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    SwingUtilities.windowForComponent(MatchAreaPanel.this).dispose();
                }
            });
            timer.start();
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setColor(new Color(128, 128, 128, 64));
            g2d.fillRect(0, 0, getWidth(), getHeight());

            float dash1[] = {10.0f};
            BasicStroke dashed = new BasicStroke(3.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash1, 0.0f);
            g2d.setColor(Color.BLACK);
            g2d.setStroke(dashed);
            g2d.drawRect(0, 0, getWidth() - 3, getHeight() - 3);
            g2d.dispose();
        }
    }

}

有关详细信息,请参阅 How to use Swing Timers

已更新...

现在,只是 "hiding" 面板很无聊,用户也有可能错过面板,因为突然出现并不能保证用户会看到它,因此您可以添加淡出效果。

在此示例中,您可以通过单击面板淡出它(但我这样做是作为测试的一部分,所以您不需要它)或在指定的时间结束后...

import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Random;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                Rectangle bounds = getVirtualBounds();
                Random rnd = new Random();
                int x = bounds.x + (rnd.nextInt(bounds.width) - 100);
                int y = bounds.y + (rnd.nextInt(bounds.height) - 100);

                MatchAreaPanel pane = new MatchAreaPanel();
                JWindow frame = new JWindow();
                frame.setBackground(new Color(0, 0, 0, 0));
                frame.add(pane);
                frame.setBounds(x, y, 100, 100);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
                pane.start();
            }
        });
    }

    public static Rectangle getVirtualBounds() {

        Rectangle bounds = new Rectangle(0, 0, 0, 0);

        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice gd = ge.getDefaultScreenDevice();
        bounds.add(gd.getDefaultConfiguration().getBounds());

        return bounds;

    }

    public static class MatchAreaPanel extends JPanel {

        protected static final long FADE_OUT_TIME = 2500;

        private float alpha = 1f;
        private long fadeStartAt;
        private Timer fadeTimer;
        private Timer waitTimer;

        public MatchAreaPanel() {
            setOpaque(false);
            addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    fadeOut();
                }
            });
            fadeTimer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    long runTime = System.currentTimeMillis() - fadeStartAt;
                    float progress = 0f;
                    if (runTime >= FADE_OUT_TIME) {
                        progress = 1f;
                    } else {
                        progress = (float) runTime / (float) FADE_OUT_TIME;
                        if (progress > 1f) {
                            progress = 1f;
                        }
                    }
                    alpha = 1f - progress;

                    if (progress >= 1f) {
                        ((Timer) e.getSource()).stop();
                        SwingUtilities.windowForComponent(MatchAreaPanel.this).dispose();
                    }
                    repaint();
                }
            });
            waitTimer = new Timer(5000, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    ((Timer) e.getSource()).stop();
                    fadeOut();
                }
            });
        }

        protected void fadeOut() {
            waitTimer.stop();
            fadeStartAt = System.currentTimeMillis();
            fadeTimer.start();
        }

        public void start() {
            if (!waitTimer.isRunning() && !fadeTimer.isRunning()) {
                waitTimer.start();
            }
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setComposite(AlphaComposite.SrcOver.derive(alpha));
            g2d.setColor(new Color(128, 128, 128, 64));
            g2d.fillRect(0, 0, getWidth(), getHeight());

            float dash1[] = {10.0f};
            BasicStroke dashed = new BasicStroke(3.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash1, 0.0f);
            g2d.setColor(Color.BLACK);
            g2d.setStroke(dashed);
            g2d.drawRect(0, 0, getWidth() - 3, getHeight() - 3);
            g2d.dispose();
        }
    }

}