简体   繁体   English

在圆形JLabel图像周围创建一个可单击区域

[英]Create a clickable area around round JLabel image

I am trying to create a JLabel with a oval shaped image, like this. 我试图用这样的椭圆形图像创建一个JLabel。

在此处输入图片说明

My code is the following: 我的代码如下:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;

public final class RoundedButtonDemo {
    private static Image bi;

    public static void main(String[] args) {
        try {
            loadImage();

            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    createAndShowGUI();
                }
            });
        } catch (IOException e) {
            // handle exception
        }
    }

    private static void loadImage() throws IOException {
        int newWidth = 80;
        int newHeight = 40;
        bi = ImageIO.read(RoundedButtonDemo.class.getResource("/resources/login.png"));
        bi = bi.getScaledInstance(newWidth, newHeight, Image.SCALE_DEFAULT);

    }

    private static void createAndShowGUI() {
        final JFrame frame = new JFrame();
        frame.setSize(400, 400);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        final JLabel label = new JLabel();
        label.setSize(new Dimension(5, 5));
        label.setIcon(new ImageIcon(bi));
        label.setText("Hello World");
        label.setHorizontalTextPosition(JLabel.CENTER);
        // label.setBorder(BorderFactory.createLineBorder(Color.BLACK));

        label.addMouseListener(new MouseListener() {

            private int count = 0;

            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getSource() == label) {
                    if (count % 2 == 0) {
                        label.setText("Bye");
                    } else {
                        label.setText("Hello World");
                    }

                    count++;
                }
            }

            @Override
            public void mouseEntered(MouseEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void mouseExited(MouseEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void mousePressed(MouseEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void mouseReleased(MouseEvent e) {
                // TODO Auto-generated method stub

            }
        });

        frame.add(label);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

This code creates a JLabel containing the above image. 此代码创建一个包含以上图像的JLabel The text of the JLabel should alternate every time the button is clicked, based on a MouseListener added to the JLabel . 每次单击按钮时,基于添加到JLabelMouseListenerJLabel的文本应交替显示。

The problem I'm facing is that even when I click outside the image (also outside the JLabel ), the MouseListener is triggered, and the text alternates. 我面临的问题是,即使我在图像外部(也在JLabel外部)单击,也会触发MouseListener ,并且文本会交替显示。

The big picture of what I want to achieve is : A rounded button which responds to a MouseListener , whenever it is clicked anywhere on its surface. 我要实现的目标是:圆形按钮,只要单击MouseListener表面上的任意位置,它就会响应MouseListener

I tried your code. 我尝试了您的代码。 You are getting this behavior because your JLabel is actually filling the entire frame. 之所以会出现这种现象,是因为您的JLabel实际上填满了整个框架。 You need to set a layout for your frame; 您需要为框架设置布局; something like this: 像这样的东西:

// ...
frame.setSize(400, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());             // <-- you need this

final JLabel label = new JLabel();
label.setPreferredSize(new Dimension(80, 40)); // <-- also this
label.setIcon(new ImageIcon(bi));
label.setText("Hello World");
// ...

FlowLayout is one of the simplest layout managers, of which there are many. FlowLayout是最简单的布局管理器之一,其中有很多。 You can read about them here: https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html 您可以在这里阅读有关它们的信息: https : //docs.oracle.com/javase/tutorial/uiswing/layout/visual.html

Hope this helps. 希望这可以帮助。

PS: you had a good idea trying to debug this problem, adding a border like this: PS:您最好尝试调试此问题,并添加如下所示的边框:

// label.setBorder(BorderFactory.createLineBorder(Color.BLACK));

Not sure why you commented it out. 不知道为什么要注释掉。 Maybe you didn't notice that there was a black border around the whole frame area. 也许您没有注意到整个框架区域周围都有黑色边框。 Try setting to color to Color.RED or something more noticeable. 尝试将颜色设置为Color.RED或更明显。

As yoshi pointed out, the JLabel fills the entire content pane, so clicking anywhere in the content pane results in mouse events for the label. 正如yoshi指出的那样, JLabel填充整个内容窗格,因此单击内容窗格中的任何位置都会导致标签发生鼠标事件。

Some words: 一些单词:

1) You could also use GridBagLayout , instead of FlowLayout , in case you want the JLabel centered in its parent component (both vertically and horizontally). 1)如果您希望JLabel在其父组件(垂直和水平)中居中,也可以使用GridBagLayout而不是FlowLayout This solution is here . 这个解决方案在这里

Like so: 像这样:

final JPanel singleCenteredComponentJPanel = new JPanel(new GridBagLayout());
singleCenteredComponentJPanel.add(label);
frame.add(singleCenteredComponentJPanel);

2) If, furthermore, you want to ignore mouse clicks on any transparent pixels of the label icon (if any) you can do the following: 2)此外,如果您想忽略鼠标在标签图标的任何透明像素上的单击(如果有),可以执行以下操作:

Use the BufferedImage.getRGB(int x, int y) , BufferedImage.getColorModel() and ColorModel.getAlpha(int pixel) methods to determine the alpha value of the clicked pixel for each mouse event. 使用BufferedImage.getRGB(int x, int y)BufferedImage.getColorModel()ColorModel.getAlpha(int pixel)方法来确定每个鼠标事件的单击像素的alpha值。 If the alpha value is equal to 0, then the pixel is completely transparent, otherwise the alpha value is between 1 and 255 (both inclusive) which in turn means the pixel is not completely transparent. 如果Alpha值等于0,则该像素是完全透明的,否则Alpha值在1到255之间(包括两者),这又意味着该像素不是完全透明的。 Example code follows below. 示例代码如下。

And instead of Image.getScaledInstance(...) to scale the image (which returns Image , but we need BufferedImage ), use the solution provided here . 而不是Image.getScaledInstance(...)来缩放图像(返回Image ,但是我们需要BufferedImage ),请使用此处提供的解决方案。

Like so: 像这样:

private static void loadImage() throws IOException {
    int newWidth = 80;
    int newHeight = 40;
    bi = ImageIO.read(RoundedButtonDemo.class.getResource("/resources/login.png"));
    bi = getScaledBufferedImage(bi, newWidth, newHeight);

}

public static BufferedImage getScaledBufferedImage(final Image img,
                                                   final int newWidth,
                                                   final int newHeight) {
    final GraphicsEnvironment genv = GraphicsEnvironment.getLocalGraphicsEnvironment();
    final GraphicsDevice gdev = genv.getDefaultScreenDevice();
    final GraphicsConfiguration gcnf = gdev.getDefaultConfiguration();
    final BufferedImage simg = gcnf.createCompatibleImage(newWidth, newHeight, Transparency.TRANSLUCENT);

    //Painting input image to output image:
    final Graphics2D g2d = simg.createGraphics();
    g2d.drawImage(img, 0, 0, newWidth, newHeight, null); //@Docs "...is scaled if necessary.".
    g2d.dispose();

    return simg;
}  

Also change the reference bi from Image to BufferedImage . 还将引用biImage更改为BufferedImage

And then the MouseListener of the label: 然后是标签的MouseListener

private int count = 0;

@Override
public void mouseClicked(MouseEvent e) {
    if (e.getSource() == label) {

        //Get the mouse click position (in pixels),
        //relative to the top-left corner of label:
        final Point relativeClickPoint = e.getPoint();

        //Obtain alpha value from the TYPE_INT_ARGB pixel:
        final int pixel = bi.getRGB(relativeClickPoint.x, relativeClickPoint.y);
        final int alpha = bi.getColorModel().getAlpha(pixel);

        if (alpha > 0) { //Check if the pixel is not transparent.
            if (count % 2 == 0) {
                label.setText("Bye");
            } else {
                label.setText("Hello World");
            }
            count++;
        }
    }
}

Be aware for the above implementation: All transparent pixels of the image will be ignored (including transparent pixels "inside" the shape, if any). 请注意上述实现:图像的所有透明像素都将被忽略(包括形状“内部”的透明像素,如果有的话)。 Which means the user could click in the center of the image and nothing would happen if the clicked pixel was completely transparent. 这意味着用户可以单击图像的中心,如果单击的像素完全透明,则不会发生任何事情。 So I made the assumption that this is not the case with your image here. 因此,我假设您的图片并非如此。

3) For the scaling of the Image , you can determine the new size with the method collapseInside(...) : 3)对于Image的缩放,可以使用collapseInside(...)方法确定新的大小:

/**
 * @param resultDim Output dimension (same aspect ratio as the original dimension, and inside containerDim).
 * @param originalDim Original dimension.
 * @param containerDim Dimension with the maximum width and maximum height.
 */
public static void collapseInside(final Dimension resultDim,
                                  final Dimension originalDim,
                                  final Dimension containerDim) {
    resultDim.setSize(originalDim);
    if (resultDim.width > containerDim.width) {
        //Adjusting height for max width:
        resultDim.height = ( resultDim.height * containerDim.width ) / resultDim.width;
        resultDim.width = containerDim.width;
    }
    if (resultDim.height > containerDim.height) {
        //Adjusting width for max height:
        resultDim.width = ( resultDim.width * containerDim.height ) / resultDim.height;
        resultDim.height = containerDim.height;
    }
}

With this method: 使用此方法:
a) Scaled Image 's width will be less than or equal to container's size width ( resultDim.width <= containerDim.width ). a)缩放Image的宽度将小于或等于容器的大小宽度( resultDim.width <= containerDim.width )。
b) Same for height ( resultDim.height <= containerDim.height ). b)高度相同( resultDim.height <= containerDim.height )。
c) Aspect ratio of the original Image size will be preserved in the new Image size (resultDim.width / resultDim.height == originalDim.width / originalDim.height). c)原始Image尺寸的长宽比将保留在新Image尺寸中(resultDim.width / resultDim.height == originalDim.width / originalDim.height)。
With Image.getScaledInstance(...) and the previous getScaledBufferedImage(...) the aspect ratio of the Image could change. 使用Image.getScaledInstance(...)和先前的getScaledBufferedImage(...) ,可以更改Image的纵横比。
So I edit the getScaledBufferedImage(...) to use collapseInside(...) : 所以我编辑getScaledBufferedImage(...)以使用getScaledBufferedImage(...) collapseInside(...)

public static BufferedImage getScaledBufferedImage(final Image img,
                                                   final int newWidth,
                                                   final int newHeight) {
    final Dimension originalDim = new Dimension(img.getWidth(null), img.getHeight(null)),
                    containerDim = new Dimension(newWidth, newHeight),
                    resultDim = new Dimension();
    collapseInside(resultDim, originalDim, containerDim);

    final GraphicsEnvironment genv = GraphicsEnvironment.getLocalGraphicsEnvironment();
    final GraphicsDevice gdev = genv.getDefaultScreenDevice();
    final GraphicsConfiguration gcnf = gdev.getDefaultConfiguration();
    final BufferedImage simg = gcnf.createCompatibleImage(resultDim.width, resultDim.height, Transparency.TRANSLUCENT);

    //Painting input image to output image:
    final Graphics2D g2d = simg.createGraphics();
    g2d.drawImage(img, 0, 0, resultDim.width, resultDim.height, null); //@Docs "...is scaled if necessary.".
    g2d.dispose();

    return simg;
}

Complete code for all three above: 以上所有三个的完整代码:

import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Point;
import java.awt.Transparency;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public final class RoundedButtonDemo {
    private static BufferedImage bi;

    public static void main(String[] args) {
        try {
            loadImage();

            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    createAndShowGUI();
                }
            });
        } catch (IOException e) {
            // handle exception
        }
    }

    private static void loadImage() throws IOException {
        int newWidth = 80;
        int newHeight = 40;
        bi = ImageIO.read(RoundedButtonDemo.class.getResource("/resources/login.png"));
        bi = getScaledBufferedImage(bi, newWidth, newHeight);

    }

    public static BufferedImage getScaledBufferedImage(final Image img,
                                                       final int newWidth,
                                                       final int newHeight) {
        final Dimension originalDim = new Dimension(img.getWidth(null), img.getHeight(null)),
                        containerDim = new Dimension(newWidth, newHeight),
                        resultDim = new Dimension();
        collapseInside(resultDim, originalDim, containerDim);

        final GraphicsEnvironment genv = GraphicsEnvironment.getLocalGraphicsEnvironment();
        final GraphicsDevice gdev = genv.getDefaultScreenDevice();
        final GraphicsConfiguration gcnf = gdev.getDefaultConfiguration();
        final BufferedImage simg = gcnf.createCompatibleImage(resultDim.width, resultDim.height, Transparency.TRANSLUCENT);

        //Painting input image to output image:
        final Graphics2D g2d = simg.createGraphics();
        g2d.drawImage(img, 0, 0, resultDim.width, resultDim.height, null); //@Docs "...is scaled if necessary.".
        g2d.dispose();

        return simg;
    }

    /**
     * @param resultDim Output dimension (same aspect ratio as the original dimension, and inside containerDim).
     * @param originalDim Original dimension.
     * @param containerDim Dimension with the maximum width and maximum height.
     */
    public static void collapseInside(final Dimension resultDim,
                                      final Dimension originalDim,
                                      final Dimension containerDim) {
        resultDim.setSize(originalDim);
        if (resultDim.width > containerDim.width) {
            //Adjusting height for max width:
            resultDim.height = ( resultDim.height * containerDim.width ) / resultDim.width;
            resultDim.width = containerDim.width;
        }
        if (resultDim.height > containerDim.height) {
            //Adjusting width for max height:
            resultDim.width = ( resultDim.width * containerDim.height ) / resultDim.height;
            resultDim.height = containerDim.height;
        }
    }

    private static void createAndShowGUI() {
        final JFrame frame = new JFrame();
        frame.setSize(400, 400);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        final JLabel label = new JLabel();
        label.setSize(new Dimension(5, 5));
        label.setIcon(new ImageIcon(bi));
        label.setText("Hello World");
        label.setHorizontalTextPosition(JLabel.CENTER);
        // label.setBorder(BorderFactory.createLineBorder(Color.BLACK));

        label.addMouseListener(new MouseListener() {

            private int count = 0;

            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getSource() == label) {

                    //Get the mouse click position (in pixels),
                    //relative to the top-left corner of label:
                    final Point relativeClickPoint = e.getPoint();

                    //Obtain alpha value from the TYPE_INT_ARGB pixel:
                    final int pixel = bi.getRGB(relativeClickPoint.x, relativeClickPoint.y);
                    final int alpha = bi.getColorModel().getAlpha(pixel);

                    if (alpha > 0) { //Check if the pixel is not transparent.
                        if (count % 2 == 0) {
                            label.setText("Bye");
                        } else {
                            label.setText("Hello World");
                        }
                        count++;
                    }
                }
            }

            @Override
            public void mouseEntered(MouseEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void mouseExited(MouseEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void mousePressed(MouseEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void mouseReleased(MouseEvent e) {
                // TODO Auto-generated method stub

            }
        });

        final JPanel singleCenteredComponentJPanel = new JPanel(new GridBagLayout());
        singleCenteredComponentJPanel.add(label);
        frame.add(singleCenteredComponentJPanel);

        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

Alternatively, you may also override the paintComponent(...) of JPanel and use Graphics.drawImage(...) to paint the Image bi to the JPanel like so: 另外,您也可以重写paintComponent(...)JPanel ,并使用Graphics.drawImage(...)来绘制Image biJPanel ,像这样:

@Override
protected void paintComponent(final Graphics g) {
    super.paintComponent(g);

    //Drawing the image:
    g.drawImage(img, 0, 0, null);

    //Drawing the text:
    //For centering the text, I used code from:
    //https://stackoverflow.com/questions/27706197/how-can-i-center-graphics-drawstring-in-java
    final FontMetrics metrics = g.getFontMetrics(g.getFont());
    final int x = (img.getWidth(null) - metrics.stringWidth(text)) / 2;
    final int y = (img.getHeight(null) - metrics.getHeight()) / 2 + metrics.getAscent();
    g.drawString(text, x, y);
}

Where img is bi and text is the text of the button (ie "Hello World" and "Bye"). 其中imgbitext是按钮的文本(即“ Hello World”和“ Bye”)。
Then add the MouseListener to the JPanel as is. 然后按原样将MouseListener添加到JPanel

Complete code for this (as " RoundedButtonDemo1 " class, in the same package): 完整的代码(作为“ RoundedButtonDemo1 ”类,在同一包中):

import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Point;
import java.awt.Transparency;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public final class RoundedButtonDemo1 {
    private static BufferedImage bi;

    public static void main(String[] args) {
        try {
            loadImage();

            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    createAndShowGUI();
                }
            });
        } catch (IOException e) {
            // handle exception
        }
    }

    private static void loadImage() throws IOException {
        int newWidth = 80;
        int newHeight = 40;
        bi = ImageIO.read(RoundedButtonDemo1.class.getResource("/resources/login.png"));
        bi = getScaledBufferedImage(bi, newWidth, newHeight);

    }

    public static BufferedImage getScaledBufferedImage(final Image img,
                                                       final int newWidth,
                                                       final int newHeight) {
        final Dimension originalDim = new Dimension(img.getWidth(null), img.getHeight(null)),
                        containerDim = new Dimension(newWidth, newHeight),
                        resultDim = new Dimension();
        collapseInside(resultDim, originalDim, containerDim);

        final GraphicsEnvironment genv = GraphicsEnvironment.getLocalGraphicsEnvironment();
        final GraphicsDevice gdev = genv.getDefaultScreenDevice();
        final GraphicsConfiguration gcnf = gdev.getDefaultConfiguration();
        final BufferedImage simg = gcnf.createCompatibleImage(resultDim.width, resultDim.height, Transparency.TRANSLUCENT);

        //Painting input image to output image:
        final Graphics2D g2d = simg.createGraphics();
        g2d.drawImage(img, 0, 0, resultDim.width, resultDim.height, null); //@Docs "...is scaled if necessary.".
        g2d.dispose();

        return simg;
    }

    /**
     * @param resultDim Output dimension (same aspect ratio as the original dimension, and inside containerDim).
     * @param originalDim Original dimension.
     * @param containerDim Dimension with the maximum width and maximum height.
     */
    public static void collapseInside(final Dimension resultDim,
                                      final Dimension originalDim,
                                      final Dimension containerDim) {
        resultDim.setSize(originalDim);
        if (resultDim.width > containerDim.width) {
            //Adjusting height for max width:
            resultDim.height = ( resultDim.height * containerDim.width ) / resultDim.width;
            resultDim.width = containerDim.width;
        }
        if (resultDim.height > containerDim.height) {
            //Adjusting width for max height:
            resultDim.width = ( resultDim.width * containerDim.height ) / resultDim.height;
            resultDim.height = containerDim.height;
        }
    }

    private static class CustomButton extends JPanel {
        private Image img;
        private String text;

        public void setImage(final Image img) {
            this.img = img;
            final Dimension imgDim = new Dimension(img.getWidth(null), img.getHeight(null));
            setMinimumSize(imgDim);
            setPreferredSize(imgDim);
            repaint();
        }

        public Image getImage() {
            return img;
        }

        public void setText(final String text) {
            this.text = text;
            repaint();
        }

        public String getText() {
            return text;
        }

        @Override
        protected void paintComponent(final Graphics g) {
            super.paintComponent(g);

            //Drawing the image:
            g.drawImage(img, 0, 0, null);

            //Drawing the text:
            //For centering the text, I used code from:
            //https://stackoverflow.com/questions/27706197/how-can-i-center-graphics-drawstring-in-java
            final FontMetrics metrics = g.getFontMetrics(g.getFont());
            final int x = (img.getWidth(null) - metrics.stringWidth(text)) / 2;
            final int y = (img.getHeight(null) - metrics.getHeight()) / 2 + metrics.getAscent();
            g.drawString(text, x, y);
        }
    }

    private static void createAndShowGUI() {
        final JFrame frame = new JFrame();
        frame.setSize(400, 400);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        final CustomButton button = new CustomButton();
        button.setSize(new Dimension(5, 5));
        button.setImage(bi);
        button.setText("Hello World");
        //button.setHorizontalTextPosition(SwingConstants.CENTER);
        //button.setOpaque(false);
        //button.setBorder(BorderFactory.createLineBorder(Color.BLACK));

        button.addMouseListener(new MouseListener() {

            private int count = 0;

            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getSource() == button) {

                    //Get the mouse click position (in pixels),
                    //relative to the top-left corner of label:
                    final Point relativeClickPoint = e.getPoint();

                    //Obtain alpha value from the TYPE_INT_ARGB pixel:
                    final int pixel = bi.getRGB(relativeClickPoint.x, relativeClickPoint.y);
                    final int alpha = bi.getColorModel().getAlpha(pixel);

                    if (alpha > 0) { //Check if the pixel is not transparent.
                        if (count % 2 == 0) {
                            button.setText("Bye");
                        } else {
                            button.setText("Hello World");
                        }
                        count++;
                    }
                }
            }

            @Override
            public void mouseEntered(MouseEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void mouseExited(MouseEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void mousePressed(MouseEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void mouseReleased(MouseEvent e) {
                // TODO Auto-generated method stub

            }
        });


        final JPanel singleCenteredComponentJPanel = new JPanel(new GridBagLayout());
        singleCenteredComponentJPanel.add(button);
        frame.add(singleCenteredComponentJPanel);

        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

Alternatively, if you want normal buttons, istead of labels, it seems here you can reshape buttons as well ! 另外,如果您想要普通的按钮,而不是标签,似乎在这里您也可以重塑按钮的形状!

Other than that, I have also tried the following: 除此之外,我还尝试了以下方法:
1) Using JLayeredPane s. 1)使用JLayeredPane There is a tutorial explaining them, and I guessed they could probably have a method to obtain the order of the visible pane for a given Point , or something like that, but they don't. 有一个教程对它们进行了解释,我猜想他们可能有一种方法可以获取给定Point或类似对象的可见窗格的顺序,但事实并非如此。
2) Using Container.getComponentAt(Point) and Container.findComponentAt(Point) in the MouseListener , but (as I found out after testing) these methods don't "see through" non-opaque (+transparent) pixels. 2)在MouseListener使用Container.getComponentAt(Point)Container.findComponentAt(Point) ,但是(正如我在测试后发现的那样),这些方法不会“透视”非透明(+透明)像素。
3) Searching for reshaping or translucency in JPanel s (inspired by How to Create Translucent and Shaped Windows ), but nothing found. 3)在JPanel搜索重塑或半透明(受“ 如何创建半透明和成形的Windows”启发),但未找到任何内容。
4) How to Decorate Components with the JLayer Class with first line saying: 4) 如何用JLayer类装饰组件 ,第一行说:

... enables you to draw on components and respond to component events without modifying the underlying component directly. ...使您能够利用组件并响应组件事件,而无需直接修改基础组件。

seems promising, but I'm done here. 看起来很有希望,但我在这里完成了。

That's it for me for now. 现在就这些了。 Goodbye. 再见。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM