两个 JLabel 在鼠标悬停时相互复制背景和内容
Two JLabels copying backgrounds and contents from each other on mouse over
我正在尝试为几个填充有文本的 JLabel 元素创建 mouseOver 视觉效果。这个想法是当鼠标进入时让每个标签变暗,然后 return 当鼠标离开它的区域时它恢复正常。此外,所有标签都放置在具有背景图像的面板上。
虽然很简单,但我遇到了无法克服的恶劣行为。
错误 1:我第一次将鼠标移到标签上时,它显示我的主要 window 的左上角作为背景。
错误 2:然后,每次我将鼠标移到一个标签上一次,然后将其移到第二个标签上时,第二个标签将其背景更改为 "summ background"(面板图像 + 半透明背景)第一个标签。在那之上,似乎即使是第一个标签的文本内容也在 "copied" 到第二个标签的背景。每次标签更改只发生一次:如果我将鼠标移到同一个标签上两次,则第二次鼠标悬停事件被正确绘制。
我已经尝试过使用 MouseMotionListener,这是一个不同的元素 (JButton),尝试过组件修改方法,甚至还尝试过重写绘制方法。没有结果。
我附上了显示所描述行为的动画 GIF:
Two JLabels copying backgrounds and contents from each other
我对 Swing 比较陌生,所以我不熟悉它的注意事项。知道是什么原因造成的吗?
自定义面板class:
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);
}
}
}
鼠标监听器class:
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();
}
主窗口class:
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 了解更多信息和问题的几个解决方案。您可以:
- 在标签上自定义绘画以手动绘制背景
- 使用包装器组件并让该组件为您绘制。
我想我已经找到了解决办法。两个虫子都消失了。我所做的是添加父容器的(在我的例子中是带有板背景的面板)重绘:
@Override
public void mouseEntered(MouseEvent e) {
JLabel component = (JLabel)e.getComponent();
component.setBackground(HOVER_SHADOW);
component.setCursor(CURSOR_HAND);
component.setOpaque(true);
Container container = component.getParent();
component.repaint();
container.repaint(); //fix
}
@Override
public void mouseExited(MouseEvent e) {
JLabel component = (JLabel)e.getComponent();
component.setBackground(null);
component.setCursor(CURSOR_DEFAULT);
component.setOpaque(false);
Container container = component.getParent();
component.repaint();
container.repaint(); //fix
}
感谢大家的帮助;)
我正在尝试为几个填充有文本的 JLabel 元素创建 mouseOver 视觉效果。这个想法是当鼠标进入时让每个标签变暗,然后 return 当鼠标离开它的区域时它恢复正常。此外,所有标签都放置在具有背景图像的面板上。
虽然很简单,但我遇到了无法克服的恶劣行为。
错误 1:我第一次将鼠标移到标签上时,它显示我的主要 window 的左上角作为背景。
错误 2:然后,每次我将鼠标移到一个标签上一次,然后将其移到第二个标签上时,第二个标签将其背景更改为 "summ background"(面板图像 + 半透明背景)第一个标签。在那之上,似乎即使是第一个标签的文本内容也在 "copied" 到第二个标签的背景。每次标签更改只发生一次:如果我将鼠标移到同一个标签上两次,则第二次鼠标悬停事件被正确绘制。
我已经尝试过使用 MouseMotionListener,这是一个不同的元素 (JButton),尝试过组件修改方法,甚至还尝试过重写绘制方法。没有结果。
我附上了显示所描述行为的动画 GIF: Two JLabels copying backgrounds and contents from each other
我对 Swing 比较陌生,所以我不熟悉它的注意事项。知道是什么原因造成的吗?
自定义面板class:
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);
}
}
}
鼠标监听器class:
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();
}
主窗口class:
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 了解更多信息和问题的几个解决方案。您可以:
- 在标签上自定义绘画以手动绘制背景
- 使用包装器组件并让该组件为您绘制。
我想我已经找到了解决办法。两个虫子都消失了。我所做的是添加父容器的(在我的例子中是带有板背景的面板)重绘:
@Override
public void mouseEntered(MouseEvent e) {
JLabel component = (JLabel)e.getComponent();
component.setBackground(HOVER_SHADOW);
component.setCursor(CURSOR_HAND);
component.setOpaque(true);
Container container = component.getParent();
component.repaint();
container.repaint(); //fix
}
@Override
public void mouseExited(MouseEvent e) {
JLabel component = (JLabel)e.getComponent();
component.setBackground(null);
component.setCursor(CURSOR_DEFAULT);
component.setOpaque(false);
Container container = component.getParent();
component.repaint();
container.repaint(); //fix
}
感谢大家的帮助;)