简体   繁体   English

如何在JLabel中使ImageIcon的背景透明

[英]How do i make the Background of an ImageIcon transparent in a JLabel

I want to put an Image onto another Image using JLabels and ImageIcon. 我想使用JLabels和ImageIcon将一个图像放置到另一个图像上。 Everything works, but i couldnt find out how to make the Background of the Image transparent. 一切正常,但是我找不到如何使图像背景透明的方法。 Basically i want to program a Game, but i dont want the player to be a perfect rectangle. 基本上我想编程一个游戏,但我不想让玩家成为一个完美的矩形。 So here is my Code which works so far: 因此,这是到目前为止有效的代码:

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

public class Game {
    JFrame frame = new JFrame();
    JLabel label1 = new JLabel();
    JLabel label2 = new JLabel();

    public Game() {
        frame.setVisible(true);
        frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
        frame.setTitle("just a test");
        frame.setResizable(true);
        frame.getContentPane().setLayout(null);
        frame.setBounds(400, 200, 915, 600);

        label1.setBounds(0, -195, 900, 890);
        label2.setBounds(50, 200, 260, 240);

        frame.getContentPane().add(label2);
        frame.getContentPane().add(label1);

        ImageIcon icon1 = new ImageIcon("icons/landscape.png");
        ImageIcon icon2 = new ImageIcon("icons/mario1.png");

        label1.setIcon(icon1);
        label2.setIcon(icon2);
    }
    public static void main(String[] args) {
        Game game = new Game();

    }
}

I recommend the very same as Hovercraft Full Of Eels, though I'll explain the reasoning behind it. 尽管我将解释其背后的原因,但我还是推荐与“气垫船充满鳗鱼”相同的东西。 According to your cuerrent setup, your JLabel fills in all transparent pixels with an opaque color. 根据您的设置,您的JLabel将使用不透明的颜色填充所有透明的像素。 It is irrelevant whether mario1.png has a transparent background, as the JLabel in which it's implemented fills in the transparent pixels with the color of its background. mario1.png是否具有透明背景无关紧要,因为在其中实现了JLabel的JLabel会用背景颜色填充透明像素。 There are two potential fixes to this. 有两个潜在的解决方案。 Use a singular JLabel, as Hovercraft suggests, or use JComponent instead. 按照Hovercraft的建议,使用单数JLabel,或者改用JComponent。 I'd recommend using the latter, as if you are programming a game, then you wouldn't want your Mario sprite moving in conjunction to the background, and you have overall more control with the JComponent class in your current circumstances. 我建议您使用后者,就像您在编写游戏一样,那样您就不希望将Mario Sprite移到后台,并且在当前情况下可以更好地控制JComponent类。

Here's the Oracle Doc for the JComponent class: https://docs.oracle.com/javase/tutorial/uiswing/components/jcomponent.html 这是JComponent类的Oracle文档: https : //docs.oracle.com/javase/tutorial/uiswing/components/jcomponent.html

I'd be willing to give you simplified sample code, if you so desire. 如果您愿意,我愿意为您提供简化的示例代码。

A JLabel is by nature transparent -- that is its opaque property is by default false (unlike JPanel which is opaque by default), and so if you place a transparent image into an ImageIcon and make this a JLabel's Icon via .setIcon(...) and add the JLabel to a container such as a JPanel, the displayed icon's transparent regions will remain transparent, showing the background image. JLabel本质上是透明的-也就是说,它的opaque属性默认情况下为false(与默认情况下不透明的JPanel不同),因此,如果将透明图像放入ImageIcon并通过.setIcon(...)并将JLabel添加到诸如JPanel的容器中,显示的图标的透明区域将保持透明,显示背景图像。 For example, given this image as a sprite, one that displays a filled circle with transparent pixels around it: 例如,假设此图像为sprite,则在其周围显示带有透明像素的实心圆:

在此处输入图片说明

So if a mouse listener is added to the JLabel it can be dragged around the container. 因此,如果将鼠标侦听器添加到JLabel,则可以将其拖动到容器周围。

eg, 例如,

import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;

@SuppressWarnings("serial")
public class SpriteOnBackground extends JPanel {
    // Image attribution:
    // By Adam Evans - M31, the Andromeda Galaxy (now with h-alpha)
    // Uploaded by NotFromUtrecht, CC BY 2.0, 
    // https://commons.wikimedia.org/w/index.php?curid=12654493
    public static final String ANDROMEDA_IMAGE = "https://upload.wikimedia.org/wikipedia/commons/"
            + "thumb/9/98/Andromeda_Galaxy_%28with_h-alpha%29.jpg/"
            + "1280px-Andromeda_Galaxy_%28with_h-alpha%29.jpg";
    public static final String SPRITE_IMAGE = "https://upload.wikimedia.org/wikipedia/commons/"
            + "thumb/a/a1/Glossy_3d_blue_blue2.png/"
            + "120px-Glossy_3d_blue_blue2.png";
    private Image background;
    private JLabel spriteLabel = new JLabel();

    public SpriteOnBackground(Image bg, Image spriteImg) {
        background = bg;
        spriteLabel.setIcon(new ImageIcon(spriteImg));
        spriteLabel.setSize(spriteLabel.getPreferredSize());
        setLayout(null);
        add(spriteLabel);

        MyMouse myMouse = new MyMouse();
        spriteLabel.addMouseListener(myMouse);
        spriteLabel.addMouseMotionListener(myMouse);
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet() || background == null) {
            return super.getPreferredSize();
        }
        // make JPanel the size of the image
        int w = background.getWidth(this);
        int h = background.getHeight(this);
        return new Dimension(w, h);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        // draw background image
        g.drawImage(background, 0, 0, this);
    }

    // mouse listener to drag the JLabel around the GUI
    private class MyMouse extends MouseAdapter {
        private Point p1;
        private Point pSprite;

        @Override
        public void mousePressed(MouseEvent e) {
            p1 = e.getLocationOnScreen();
            pSprite = spriteLabel.getLocation();
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            if (p1 != null) {
                moveSprite(e);
            }
        }

        private void moveSprite(MouseEvent e) {
            Point p2 = e.getLocationOnScreen();
            int x = pSprite.x + p2.x - p1.x;
            int y = pSprite.y + p2.y - p1.y;
            Point newP = new Point(x, y);
            spriteLabel.setLocation(newP);
            repaint();
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            if (p1 != null) {
                moveSprite(e);
            }
            p1 = null;
        }
    }

    private static void createAndShowGui() {
        SpriteOnBackground mainPanel = null;
        try {
            URL backgroundUrl = new URL(ANDROMEDA_IMAGE);
            Image backGroundImg = ImageIO.read(backgroundUrl);

            URL spriteUrl = new URL(SPRITE_IMAGE);
            Image spriteImg = ImageIO.read(spriteUrl);
            mainPanel = new SpriteOnBackground(backGroundImg, spriteImg);
        } catch (IOException e) {
            e.printStackTrace();
        }

        JFrame frame = new JFrame("Sprite On Background");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM