Java 创建一个正在消失的JPanel?

Java 创建一个正在消失的JPanel?,java,swing,jpanel,paintcomponent,Java,Swing,Jpanel,Paintcomponent,我正在尝试创建一个扩展的JPanel,作为突出显示屏幕某个区域的方式。我从中获取了一些代码,但希望进一步扩展它,尽管我不知道如何继续 我希望我的JPanel(MatchAreaPanel)在达到给定超时后消失。也就是说,JPanel将其visible属性设置为false,然后自行处理 这样做的最佳方式是什么 import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics; import java.awt.G

我正在尝试创建一个扩展的
JPanel
,作为突出显示屏幕某个区域的方式。我从中获取了一些代码,但希望进一步扩展它,尽管我不知道如何继续

我希望我的
JPanel
MatchAreaPanel
)在达到给定超时后消失。也就是说,
JPanel
将其visible属性设置为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
计时器
简单地在给定延迟后安排回调,并根据需要关闭相关窗口或隐藏组件,例如

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

}
有关更多详细信息,请参阅

已更新…

现在,简单地“隐藏”面板是很无聊的,用户也可能错过面板,因为突然出现并不能保证用户会看到它,因此,您可以添加淡出效果

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

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

}

您可以使用Swing
计时器
简单地在给定延迟后安排回调,并根据需要关闭相关窗口或隐藏组件,例如

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

}
有关更多详细信息,请参阅

已更新…

现在,简单地“隐藏”面板是很无聊的,用户也可能错过面板,因为突然出现并不能保证用户会看到它,因此,您可以添加淡出效果

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

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

}

您可能会想使用Swing
计时器
这是我的想法,但是我可以从它的勾选方法访问UI组件吗?这就是Swing
计时器
的用途,从EDT的上下文中通知
ActionListener
您可能会想使用Swing
计时器
这是我的想法,但是我可以通过勾选的方法访问UI组件吗?这就是Swing
计时器的作用,在EDT的上下文中会通知
ActionListener
,如果单击它,您在构造函数中添加的
鼠标侦听器将关闭面板?它没有以任何方式连接到计时器,对吗?不,它在那里只是为了让我可以在测试时关闭窗口,您不需要,但它可能为用户提供了一种很好的方式来清除窗口我认为您在构造函数中添加的
MouseListener
如果单击它,将关闭面板?它没有以任何方式连接到计时器,对吗?不,它就在那里,这样我可以在测试时关闭窗口,您不需要,但它可能为用户提供了一种很好的清除窗口的方法