关于java:JLabel的背景颜色在更新setText()时发生更改

JLabel's background color changes when updated setText()

编辑(不是造成问题的不透明属性,它是在更新JLabel的background属性):
我正在使用MouseMotionListener将JLabel的setText()设置为鼠标的当前位置。 JLabel会在程序首次运行时以正确的背景色/透明度开始。 每当text / mouseMotion更新时,JLabel就不再透明。

更新了可运行代码:

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.TextArea;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;

public class MouseTester extends JFrame {
public static void main(String[] args) {
try {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            MouseTester.createMouseTester();
        }
    });
} catch (Throwable t) {
    System.exit(1);
}
}
private static MouseTester mt = null;
private JLabel mouseLocation = null;
private static Color labelBackgroundColor = new Color(0, 0, 0, 127);
private static Color labelForegroundColor = Color.WHITE;

public static void createMouseTester() {
      if (mt != null)
          return;
      mt = new MouseTester();
      mt.setVisible(true);
}

private MouseTester() {
      super();
      mt = this;
      setResizable(true);
      Dimension dScreen = Toolkit.getDefaultToolkit().getScreenSize();
      setMinimumSize(new Dimension(Math.min(800, dScreen.width), Math.min(590,
      dScreen.height)));
      setSize(getMinimumSize());
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

      mouseLocation = new JLabel(" Lat/Long");
      mouseLocation.setOpaque(true);
      mouseLocation.setBackground(labelBackgroundColor);
      mouseLocation.setForeground(labelForegroundColor);
      mouseLocation.setToolTipText("The MGRS coordinates.");

      Component textArea = new TextArea("Move mouse here to see mouse motion info...");

      // Add a mouse motion listener to capture mouse motion events
      textArea.addMouseMotionListener(new MouseMotionAdapter() {

public void mouseMoved(MouseEvent evt) {
      TextArea source = (TextArea) evt.getSource();
          // Process current position of cursor while all mouse buttons are up.
            mouseLocation.setText(source.getText() +"\
Mouse moved ["
+
          evt.getPoint().x +"," + evt.getPoint().y +"]");
            mouseLocation.setBackground(labelBackgroundColor);
            mouseLocation.setForeground(labelForegroundColor);
            mouseLocation.setOpaque(true);
            mouseLocation.repaint();

      }
      public void mouseDragged(MouseEvent evt) {

      }
  });

  // Add the components to the frame; by default, the frame has a border layout
        mt.add(textArea, BorderLayout.NORTH);
        mouseLocation.setOpaque(true);
        mouseLocation.setBackground(labelBackgroundColor);
        mouseLocation.setForeground(labelForegroundColor);
        mt.add(mouseLocation, BorderLayout.SOUTH);

        int width = 300;
        int height = 300;
        mt.setSize(width, height);
  }
}

JLabel开始为透明/浅灰色,然后随着鼠标移动而变为不透明和全黑。 透明性由背景色决定。

我已经尝试过在所有我能想到的地方更改背景颜色,但是它不起作用。

我希望它始终保持颜色(启动时的颜色)。


您已经声明您的JLabel不透明,这意味着它完全负责绘制自己的背景。但是,您已将其背景色设置为半透明色。这是一个矛盾,是造成您问题的原因。

您可以通过使用mt.repaint();而不是mouseLocation.repaint();来修复JLabel的外观,从而强制重新绘制JLabel后面的整个面板区域(灰色),然后在您的半图中重新绘制JLabel -透明的颜色。

如果要避免重新绘制整个mt对象的开销,则需要将JLabel嵌套在一些较小的组件中,以便快速重绘。


我不确定为什么要更改标签的透明度。如下所示,使标签不透明并调整其背景饱和度可能就足够了。

有关实现的一些注意事项:

  • 使用事件分发线程的荣誉。
  • 让布局完成工作;谨慎使用setSize()
  • 不要不必要地混合使用AWT和Swing组件。
  • 不要吞下异常。

enter image description here

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

public class MouseTester extends JFrame {
    private static MouseTester mt;
    private static Color labelBackgroundColor = Color.gray;
    private static Color labelForegroundColor = Color.white;
    private JLabel mouseLocation;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                MouseTester.createMouseTester();
            }
        });
    }

    public static void createMouseTester() {
        mt = new MouseTester();
        mt.setVisible(true);
    }

    private MouseTester() {
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mouseLocation = new JLabel("Lat/Long", JLabel.CENTER);
        mouseLocation.setOpaque(true);
        mouseLocation.setBackground(labelBackgroundColor);
        mouseLocation.setForeground(labelForegroundColor);
        mouseLocation.setToolTipText("The MGRS coordinates.");
        JTextArea textArea = new JTextArea(
           "Move mouse here to see mouse motion info...");
        textArea.addMouseMotionListener(new MouseMotionAdapter() {

            @Override
            public void mouseMoved(MouseEvent me) {
                mouseLocation.setText("Mouse moved ["
                    + me.getX() +"," + me.getY() +"]");
            }
        });
        this.add(textArea, BorderLayout.CENTER);
        this.add(mouseLocation, BorderLayout.SOUTH);
        this.pack();
        this.setSize(320, 240); // content placeholder
        this.setLocationRelativeTo(null);
    }
}


对于从(Xxx)MouseListeners触发的每个MouseEvents,必须调用JLabel#repaint()Opaque(true)切换到Opaque(false),反之亦然,因为API中缺少此方法,其余部分由@kleapatra进行描述