1

Edit (it's not the opaque attribute that's causing the problem, it's updating the JLabel's background attribute): I am using a MouseMotionListener to setText() for a JLabel to whatever the mouse's current position is. The JLabel starts out with the correct background color/transparency at first running of the program. Whenever the text/mouseMotion is updated the JLabel is no longer transparent.

Updated runnable code:

For example:

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() + "\nMouse 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);
  }
}

The JLabel starts out transparent/slightly grey then changes with the mouse motion to not transparent and entirely black. The transparency is determined in the background color.

I've pretty much tried changing the background color everywhere I could think of, but it's not working..

I would like it to remain the color the entire time (the color that it has at startup).

ARC
  • 352
  • 4
  • 13
  • 2
    Can you please post a [SSCCE](http://pscode.org/sscce.html)? We cannot see much from your code snippet. – Howard Jun 08 '12 at 19:34
  • 1
    Btw - `JLabel`'s are by default not opaque (== not non-transparent == transparent). If you want bottom image - you needn't invoke `setOpaque(false)`. I see you're setting opaque to `true` (== with background == non-transparent) so it would be better to just leave opaqueness as it is by default. – Xeon Jun 08 '12 at 19:57
  • +1 for [sscce](http://sscce.org/). – trashgod Jun 09 '12 at 13:38

3 Answers3

4

You have declared that your JLabel is opaque, which means that it is fully responsible for drawing its own background. Yet you have set it's background color to a semi-transparent color. That is a contradiction and is the cause of your problem.

You can fix the appearance of your JLabel by using mt.repaint(); instead of mouseLocation.repaint(); thus forcing a re-draw of the area of the entire panel behind the JLabel (in gray) followed by a re-draw of the JLabel in your semi-transparent color.

If you want to avoid the cost of re-painting your entire mt object, then you need to nest your JLabel inside some smaller component which you can redraw quickly.

Enwired
  • 1,563
  • 1
  • 12
  • 26
  • Sorry, I have to demur: [opacity](http://java.sun.com/products/jfc/tsc/articles/painting/index.html#props) is orthogonal to transparency. See also this [answer](http://stackoverflow.com/a/3518047/230513) and this [answer](http://stackoverflow.com/a/10961732/230513). – trashgod Jun 09 '12 at 14:20
  • JComponent opacity and transparency are different things in Java. But the way they were used in the example is very questionable. Unless you can guarantee that the component containing the "opaque but transparent" JLabel will always be re-painted before the JLabel itself is re-painted, the results will be unpredictable. When I run the sample code, the majority of the re-paints involve first painting a solid black background, but every once in a while some random stuff from some buffered image is displayed behind the JLabel. – Enwired Jun 11 '12 at 21:33
  • +1 Agree; this [example](http://stackoverflow.com/a/7213546/230513) addresses a question about similar [artifacts](http://i.stack.imgur.com/ga7n1.png). – trashgod Jun 12 '12 at 03:29
  • Thanks. I did not realize that, you've cleared up my confusion. – ARC Jun 18 '12 at 12:42
3

You have to call JLabel#repaint() for switching from Opaque(true) to Opaque(false) and vice versa, for every of MouseEvents that fired from (Xxx)MouseListeners, because this method missed in the API, rest is here with description by @kleapatra

Community
  • 1
  • 1
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • Interesting, text and color are bound properties, but [opacity](http://java.sun.com/products/jfc/tsc/articles/painting/index.html#props) is not. – trashgod Jun 08 '12 at 23:43
3

I'm not sure why you're changing the label's transparency. Making the label opaque and adjusting it's background saturation may be sufficient, as shown below.

A few notes on your implmentation:

  • Kudos for using the event dispatch thread.
  • Let the layout do the work; use setSize() sparingly.
  • Don't mix AWT and Swing components needlessly.
  • Don't swallow exceptions.

enter image description here

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);
    }
}
Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • 1
    This is definitely a simpler approach. One reason that the user might have wanted a semi-transparent background for the JLabel is if he wants it to look different in each Look and Feel. – Enwired Jun 11 '12 at 21:36
  • 1
    user1442870's comment was correct, the example I used was simply something I threw together to give an example for the particular problem I was having because the program I was working on was too large post the entire source. Thank you very much for the notes though, I am relatively new to user interface programming and was unaware of the AWT/Swing mixing aspect (I made that mistake on the program I am working on). – ARC Jun 18 '12 at 13:13