简体   繁体   中英

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. 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. 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. There are two potential fixes to this. Use a singular JLabel, as Hovercraft suggests, or use JComponent instead. 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.

Here's the Oracle Doc for the JComponent class: 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. For example, given this image as a sprite, one that displays a filled circle with transparent pixels around it:

在此处输入图片说明

So if a mouse listener is added to the JLabel it can be dragged around the container.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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