我想使用JLabels和ImageIcon将Image放到另一个Image上。一切正常,但我无法找到如何使图像的背景透明。基本上我想编写一个游戏,但我不希望玩家成为一个完美的矩形。所以这是我的代码到目前为止工作:
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();
}
}
我推荐和Hovercraft Full Of Eels一样,不过我会解释它背后的原因。根据您的设置,您的JLabel将填充所有透明像素,并使用不透明的颜色。 mario1.png是否具有透明背景是无关紧要的,因为它实现的JLabel用其背景颜色填充透明像素。这有两个可能的解决方案。像Hovercraft建议的那样使用单个JLabel,或者使用JComponent代替。我建议使用后者,就好像你正在编写一个游戏,然后你不希望你的Mario sprite与后台一起移动,并且你在当前情况下对JComponent类有更多的控制。
这是JComponent类的Oracle Doc:https://docs.oracle.com/javase/tutorial/uiswing/components/jcomponent.html
如果你愿意,我愿意给你简化的示例代码。
JLabel本质上是透明的 - 它的opaque属性默认是false(不像JPanel,默认情况下是不透明的),所以如果你将透明图像放入ImageIcon并通过.setIcon(...)
将它变成JLabel的Icon并添加JLabel对于诸如JPanel的容器,显示的图标的透明区域将保持透明,显示背景图像。例如,将此图像指定为精灵,会在其周围显示带有透明像素的实心圆圈:
因此,如果将鼠标侦听器添加到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());
}
}