有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

JLabel上的java显示交互式循环覆盖

我有一个JFrame,其中包含一个显示BuffereImage的JLabel。 当我将鼠标悬停在这张图片上时,我需要在包含另一张图片的鼠标上显示一个圆形覆盖

到目前为止,我的代码是:

JFrame frame = new JFrame();
GridBagLayout layout = new GridBagLayout();
frame.getContentPane().setLayout(gLayout);
JLabel myLabel= new JLabel(new ImageIcon(baseImage));
GridBagConstraints constraints = new GridBagConstraints();
...
frame.getContentPane().add(myLabel, constraints);

现在我需要在显示另一个BuffereImage的鼠标位置显示一个圆形覆盖

所以我需要这样的东西:

myLabel.onMouseHover(event -> {
    Pane p = new Pane();
    x = event.x;
    y = event.y;
    p.setImage(newImage);
    // draw this pane on the label but with an offset for it to be at the center
    myLabel.draw(pane, x - offset, y - offset);
})

共 (1) 个答案

  1. # 1 楼答案

    如果我理解正确的话,那么你需要一种“透明”的风格效果。事件如果您不这样做,并且希望在鼠标点处显示静态图像,“基本”想法将起作用,您只需将覆盖图像重新定位到正确的位置即可

    本例采用两个大小相同的图像,当您移动鼠标时,它将使其看起来好像您正在“看穿”主图像。这是幻觉,但大多数像这样的效果都是幻觉

    Simple

    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Point;
    import java.awt.RenderingHints;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.geom.Ellipse2D;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import javax.imageio.ImageIO;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    
    public class Test {
    
        public static void main(String[] args) {
            new Test();
        }
    
        public Test() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    JFrame frame = new JFrame();
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            private Point mousePoint;
    
            private BufferedImage background;
            private BufferedImage seeThrough;
    
            public TestPane() {
    
                try {
                    background = ImageIO.read(BYO your own image));
                    seeThrough = ImageIO.read(BYO your own image));
                } catch (IOException ex) {
                    ex.printStackTrace();;
                }
    
                MouseAdapter ma = new MouseAdapter() {
                    @Override
                    public void mouseMoved(MouseEvent e) {
                        mousePoint = e.getPoint();
                        repaint();
                    }
    
                    @Override
                    public void mouseExited(MouseEvent e) {
                        mousePoint = null;
                        repaint();
                    }
    
                };
    
                addMouseMotionListener(ma);
                addMouseListener(ma);
            }
    
            @Override
            public Dimension getPreferredSize() {
                if (background != null) {
                    return new Dimension(background.getWidth(), background.getHeight());
                }
    
                return new Dimension(200, 200);
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g.create();
    
                g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
                g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
    
                if (background != null) {
                    g2d.drawImage(background, 0, 0, this);
                }
    
                if (seeThrough != null && mousePoint != null) {
                    double radius = 45;
                    Ellipse2D.Double clip = new Ellipse2D.Double(mousePoint.x - radius, mousePoint.y - radius, radius * 2, radius * 2);
                    g2d.setClip(clip);
                    g2d.drawImage(seeThrough, 0, 0, this);
                }
    
                g2d.dispose();
            }
    
        }
    }
    

    But this doesn't use a JLabel

    不,没有。JLabel是一种痛苦的。。。密码没有办法确定图像的位置,假设这对你很重要,但在大多数情况下,我更喜欢控制。你可以用JLabel做类似的事情,从概念上讲,这是相同的想法

    另一种解决方案可能是直接在目标组件顶部使用一种类型的“覆盖”面板,例如

    Pointy

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.Point;
    import java.awt.RenderingHints;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.geom.Ellipse2D;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import javax.imageio.ImageIO;
    import javax.swing.ImageIcon;
    import javax.swing.JComponent;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    
    public class Test {
    
        public static void main(String[] args) {
            new Test();
        }
    
        public Test() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    JFrame frame = new JFrame();
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            public TestPane() {
                setLayout(new BorderLayout());
                JLabel label = new JLabel();
                OverlayPane overlayPane = new OverlayPane(label);
                try {
                    label.setIcon(new ImageIcon(ImageIO.read(BYO your own image))));
                } catch (IOException ex) {
                    ex.printStackTrace();;
                }
    
                add(overlayPane);
            }
    
        }
    
        public class OverlayPane extends JPanel {
    
            public OverlayPane(JComponent child) {
                setLayout(new GridBagLayout());
                GridBagConstraints gbc = new GridBagConstraints();
                gbc.gridx = 0;
                gbc.gridy = 0;
                gbc.fill = GridBagConstraints.BOTH;
    
                add(new GlassPane(), gbc);
                add(child, gbc);
            }
    
            protected class GlassPane extends JPanel {
    
                private Point mousePoint;
                private BufferedImage pointer;
    
                public GlassPane() {
                    try {
                        pointer = ImageIO.read(BYO your own image));
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
    
                    MouseAdapter ma = new MouseAdapter() {
                        @Override
                        public void mouseMoved(MouseEvent e) {
                            mousePoint = e.getPoint();
                            repaint();
                        }
    
                        @Override
                        public void mouseExited(MouseEvent e) {
                            mousePoint = null;
                            repaint();
                        }
    
                    };
    
                    addMouseMotionListener(ma);
                    addMouseListener(ma);
    
                    setOpaque(false);
                }
    
                @Override
                protected void paintComponent(Graphics g) {
                    super.paintComponent(g);
                    Graphics2D g2d = (Graphics2D) g.create();
    
                    g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
                    g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
    
                    if (pointer != null && mousePoint != null) {
                        double radius = Math.max(pointer.getWidth() + 10, pointer.getHeight() + 10) / 2;
                        g2d.setColor(Color.WHITE);
                        Ellipse2D.Double clip = new Ellipse2D.Double(mousePoint.x - radius, mousePoint.y - radius, radius * 2, radius * 2);
                        g2d.fill(clip);
                        int x = (int) (mousePoint.x - radius) + 5;
                        int y = (int) (mousePoint.y - radius) + 5;
                        g2d.drawImage(pointer, x, y, this);
                    }
    
                    g2d.dispose();
                }
            }
    
        }
    }
    

    或者,您可以直接使用帧的glassPane,但需要驱动器

    AnnndJLayer style concept-当然,它允许您绘制点,但它应该提供使图像在顶部移动所需的内容