Java Swing 透明度绘制问题

发布于 2024-11-06 00:33:36 字数 3049 浏览 0 评论 0原文

编辑:

我提交了以下错误(不过可能需要几天时间才能获得批准): https://bugs.java.com/bugdatabase/view_bug?bug_id=7043319

一些更多细节:

  • 它适用于 Windows Sun JDK 1.6 版本 13 和 17
  • 它在使用 OpenJDK 的 Ubuntu 11.04 x64 上失败1.6.0_22 和 Sun JDK 1.6.0_24

我想要的是制作一个背景图像面板,其顶部有附加面板(其中有附加组件 - 例如 JButtons、自定义形状等)并正确绘制所有内容。我正在使用 JLayeredPane 来实现此目的在我的应用程序中,但为了举例,下面的代码应该足够了。无论以下问题如何,我都愿意接受有关如何做我想做的事情的建议。

我遇到的问题是这幅画的表现非常奇怪。它不会完全重新绘制(例如,仅图像上方的顶部部分),它会按照我注意到的间隔越来越大的步骤重新绘制(例如,第 1 次绘制、第 3 次绘制、第 9 次绘制、第 21 次绘制、第 64 次绘制等。 )。我的猜测是我在这里过多地进行了实现 - 下面有什么明显的错误吗?

另请注意,下面有三行注释。有趣的是,取消注释其中任何一个并注释以下行可以解决问题。这些图像具有以下属性(似乎哪个图像并不重要 - 只是大小):

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

这是我遇到问题的 Java 代码:

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);
  }
}

Edit:

I submitted a bug for the below (it may take a a few days to become approved though):
https://bugs.java.com/bugdatabase/view_bug?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);
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

执手闯天涯 2024-11-13 00:33:36

您需要添加:

imagePanel.setOpaque(false);

有关详细信息,请参阅透明背景

You need to add:

imagePanel.setOpaque(false);

See Backgrounds With Transparency for more information.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文