1

Edit:

I submitted a bug for the below (it may take a a few days to become approved though): http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7043319

Some more details:

  • It works with Windows Sun JDK 1.6 versions 13 and 17
  • It fails on Ubuntu 11.04 x64 with both OpenJDK 1.6.0_22 and Sun JDK 1.6.0_24

What I want is to make a background image panel with additional panels on top of it (with additional components - e.g. JButtons, custom shapes, etc. - in them) and draw all that correctly. I'm using JLayeredPane for that purpose in my app, but for the sake of an example the below code should suffice. I'm open to suggestions about how to do what I want regardless of the below problem.

I'm running into the issue that the painting is behaving really weird. It doesn't repaint fully (e.g. only the top part above the image), it repaints in - from what I've noticed increasingly spaced - steps (e.g. 1st paint, 3rd paint, 9th paint, 21st paint, 64th paint, etc.). My guess is that I'm going too much into implementation here - is there anything obviously wrong with the below?

On a separate note, there are three commented lines below. Interestingly enough, uncommenting any of them and commenting the following line solves the problem. The images are with the following attributes (and it seems it doesn't matter which image - just the size):

cat.jpg       JPEG 640x533 640x533+0+0 8-bit DirectClass  110KB 0.000u 0:00.000
cat-small.jpg JPEG 200x167 200x167+0+0 8-bit DirectClass 7.99KB 0.000u 0:00.000

Here's the Java code I'm having issues with:

import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;

public class SwingDrawingPrb {
  public static void main(String[] args) throws Exception {
    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    final JFrame frame = new JFrame("SwingDrawingPrb");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    final Container contentPane = frame.getContentPane();

    frame.setLocation(550, 50);
    frame.setSize(1000, 800);
    frame.setVisible(true);

//    ImageIcon image = new ImageIcon(SwingDrawingPrb.class.getResource("/cat-small.jpg"));
    ImageIcon image = new ImageIcon(SwingDrawingPrb.class.getResource("/cat.jpg"));  

    final JPanel imagePanel = new JPanel() {
//      Color trans = new Color(255, 0, 0, 255);
      Color trans = new Color(255, 0, 0, 64);

      protected void paintComponent(Graphics g) {
        System.out.println("painting");
        g.setColor(Color.white);
        g.fillRect(0, 0, getWidth(), getHeight());
        g.setColor(trans);
        g.fillRect(0, 0, getWidth(), getHeight());
        g.setColor(Color.blue);
        g.drawLine(0, 0, 1000, 1000);
      }
    };
    imagePanel.setBounds(0, 0, image.getIconWidth() + 200, image.getIconHeight() + 200);
    imagePanel.setLayout(null);

//     JLabel imageLabel = new JLabel("Hello, world!");
    JLabel imageLabel = new JLabel(image);

    imageLabel.setBounds(100, 100, image.getIconWidth(), image.getIconHeight());
    imageLabel.addMouseMotionListener(new MouseAdapter() {
      public void mouseMoved(MouseEvent e) {
        System.out.println("mouseMoved");
        imagePanel.repaint();
      }
    });
    imagePanel.add(imageLabel);

    contentPane.add(imagePanel);
  }
}
icyrock.com
  • 27,952
  • 4
  • 66
  • 85

1 Answers1

3

You need to add:

imagePanel.setOpaque(false);

See Backgrounds With Transparency for more information.

camickr
  • 321,443
  • 19
  • 166
  • 288
  • Tried that already camickr, doesn't work. Actually, tried a lot of stuff that doesn't work :) As you see I'm doing a fillRect with Color.white, so it doesn't get "darker" red all the time. The issues it that it just doesn't paint everything. It paints a part (almost always a part above the image, but sometimes other effects are visible). If you have a minute, try running it - you'll see what I mean. – icyrock.com May 09 '11 at 02:11
  • One more thing - sometimes (but not always - this is one more thing I don't understand), on the startup the frame gets painted correctly - i.e an image of a cat over a blue line going north-east over a transparent red rectangle, as it is supposed to. Now on any other repainting - either because I manually call repaint in the mouseMoved or because I resize the window - it repaints badly. – icyrock.com May 09 '11 at 02:23
  • I missed that you fill the background with WHITE first. I actually don't notice any painting problems at all. The background is a light red color, with a blue diagonal line and the image paints over the diagonal line. I'm using JDK6.7 on XP. Maybe you have a version or platform issue. – camickr May 09 '11 at 02:28
  • Also, I should note that sometimes on startup I just get a grey screen. This is because you make the frame visible before adding components to the frame. The setVisible(true) method should be the last method invoked. – camickr May 09 '11 at 02:32
  • That might be the case - I'm on Ubuntu 11.04 with OpenJDK 1.6.0_22 (same results with Sun JDK 1.6.0_24), which might be the case. I'm keen to think it's the OS (well, whatever layer that is responsible for this anyway). Let me try on Windows. – icyrock.com May 09 '11 at 02:36
  • Agree for setVisible - I was playing with it to see whether that's the issue, so I left it there. – icyrock.com May 09 '11 at 02:37
  • OK, this works fine under Windows XP, java 1.6.0_17. I'll try to test it with 1.6.0_24 on XP and see if that makes a difference, but I'm more inclined to think is something on the OS side. Thanks for the help camickr! – icyrock.com May 09 '11 at 03:00