java - 两个 JLabel 在鼠标悬停时相互复制背景和内容

标签 java swing background jlabel mouseover

我正在尝试为几个填充文本的 JLabel 元素创建 mouseOver 视觉效果。这个想法是当鼠标进入时使每个标签变暗,然后当鼠标离开其区域时将其恢复正常。此外,所有标签都放置在具有背景图像的面板上。

虽然很简单,但我遇到了无法克服的令人讨厌的行为。

错误 1:当我第一次将鼠标移到标签上时,它会显示主窗口的左上角作为其背景。

错误2:然后,每当我将鼠标移到一个标签上一次,然后将其移到第二个标签上时,第二个标签的背景就会更改为第一个标签的“总背景”(面板图像+半透明背景)。在上面,似乎甚至第一个标签的文本内容也被“复制”到第二个标签的背景。每次标签更改只会发生一次:如果我将鼠标移到同一标签上两次,则第二个鼠标悬停事件将正确绘制。

我已经尝试过使用 MouseMotionListener,一个不同的元素(JButton),使用组件修改方法,并尝试覆盖绘制方法。没有结果。

我附上了一个动画 GIF,显示了所描述的行为: Two JLabels copying backgrounds and contents from each other

我对 Swing 比较陌生,所以我不熟悉它的注意事项。知道什么可能会导致这种情况吗?

自定义面板类:

public class ImagePanel extends JPanel{
    private static final long serialVersionUID = -3995745756635082049L;

    private Image image = null;

    public ImagePanel(Image image){
        this.image = image;
    }

    public void paintComponent(Graphics g){
        super.paintComponent(g);
        if(image != null){
            g.drawImage(image, 0, 0, this);
        }
    }
}

MouseListener 类:

public class MouseHoverPiece implements MouseListener{

private static final Cursor CURSOR_HAND = new Cursor(Cursor.HAND_CURSOR);
private static final Cursor CURSOR_DEFAULT = new Cursor(Cursor.DEFAULT_CURSOR);
private static final Color HOVER_SHADOW = new Color(40, 80, 60, 50);

@Override
public void mouseEntered(MouseEvent e) {
    JLabel component = (JLabel)e.getComponent();
    component.setBackground(HOVER_SHADOW);
    component.setCursor(CURSOR_HAND);
    component.setOpaque(true);
    component.repaint();
}

@Override
public void mouseExited(MouseEvent e) {
    JLabel component = (JLabel)e.getComponent();
    component.setBackground(null);
    component.setCursor(CURSOR_DEFAULT);
    component.setOpaque(false);
    component.repaint();
}

主窗口类:

Image background = ResourceLoader.loadImage("board.png");
ImagePanel panel = new ImagePanel(background);
panel.setBounds(10, 55, 480, 480);
panel.setLayout(null);
panel_main.add(panel);

final JLabel lblNewLabel1 = new JLabel("N");
lblNewLabel1.setHorizontalAlignment(SwingConstants.CENTER);
lblNewLabel1.setOpaque(false);
lblNewLabel1.setBounds(25, 24, 52, 52);
lblNewLabel1.setFont(lblNewLabel1.getFont().deriveFont(42f));
lblNewLabel1.addMouseListener(new MouseHoverPiece());
panel.add(lblNewLabel1);

final JLabel lblNewLabel2 = new JLabel("O");
lblNewLabel2.setHorizontalAlignment(SwingConstants.CENTER);
lblNewLabel2.setOpaque(false);
lblNewLabel2.setBounds(25+52+2, 24, 52, 52);
lblNewLabel2.setFont(lblNewLabel2.getFont().deriveFont(42f));
lblNewLabel2.addMouseListener(new MouseHoverPiece());
panel.add(lblNewLabel2);

最佳答案

private static final Color HOVER_SHADOW = new Color(40, 80, 60, 50);

Swing 组件在透明背景方面存在问题,因为您违反了绘画规则,该规则规定不透明组件将完全绘制背景。

查看Backgrounds With Transparency了解更多信息和问题的一些解决方案。您可以:

  1. 在标签上进行自定义绘画以手动绘制背景
  2. 使用包装器组件并让该组件为您进行绘制。

关于java - 两个 JLabel 在鼠标悬停时相互复制背景和内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35423515/

相关文章:

java - 方法引用转换如何工作?

java - 有效Java : should I override equals() and hashCode() if the objects I'm creating are never compared with each other?

java - JLabel 右对齐图标和文本

Java自定义组件像素颜色

android - 将背景图像设置为 View 会拉伸(stretch)我的 View

css - 背景颜色,背景图片没有填满整个css盒模型

java - 如何在更短的时间内遍历大型 Java 整数列表?

java - 猜测次数的问题不会针对新的尝试进行更新,并且在输入数字 1005,1006 时代码会导致错误?

java - 有人可以解释一下这个 java Swing 代码吗?

ios - 如何使用 swift 在 Xcode 中设置背景图片?