gpt4 book ai didi

java - 当我在 Jpanel 中使用 drawImage 时,为什么它会失败

转载 作者:行者123 更新时间:2023-12-01 09:52:51 25 4
gpt4 key购买 nike

我正在用 Java 做一个简单平台游戏的初始部分。我创建了一个名为 entity 的类,它扩展了 JPanel 并成功将其添加到窗口中。

import javax.swing.*;
import java.awt.*;

/**
* Created by bw12954 on 27/05/16.
*/
public abstract class Entity extends JPanel {

private final SpriteSheet sprites;

private Point location;
private Dimension dimensions;

public Entity(int x, int y, int w, int h, SpriteSheet sprites)
{
location = new Point(x, y);
dimensions = new Dimension(w, h);
this.sprites = sprites;
}

public Entity(int x, int y, int w, int h)
{
this(x, y, w, h, null);
}

@Override
public Dimension getPreferredSize()
{
return dimensions;
}

public void setLocation(int x, int y)
{
location.setLocation(x, y);
}

/* Some code removed here for brevity */

@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(sprites.get(),
(int)location.getX(),
(int)location.getY(),
null);
}

}

如果我将其直接添加到 JFrame 中,如下所示,则图形将按照我的预期显示在窗口上(请注意,Player 是 Entity 的一个非常简单的子类)

public class Window {

private JFrame window;

public Window()
{
SwingUtilities.invokeLater(this::run);
}

private void run()
{
try {
window = new JFrame();
window.setDefaultCloseOperation(window.EXIT_ON_CLOSE);
window.setLocationByPlatform(true);
window.setUndecorated(true);
Player p = new Player(0,0);
window.add(p);
window.setExtendedState(JFrame.MAXIMIZED_BOTH);
window.setVisible(true);
} catch (IOException e) {
// TODO handle exception
e.printStackTrace();
}
}
}

但是 - 当我创建一个名为 World 的类(它也扩展了 JPanel)时,请将 that 添加到窗口中,然后在其构造函数中使用 add() 方法来添加一个新的播放器,它不会出现。有趣的是,如果我将 setBackground() 添加到玩家/实体的构造函数中,我可以在实体应该所在的位置看到一个彩色方 block 。只是drawImage 似乎不起作用。

如果其他人知道这里发生了什么,我们将不胜感激!

最佳答案

If I add this directly to the JFrame as below, then the graphic shows up on the window as I would expect it to

框架内容 Pane 的默认布局管理器是 BorderLayout。任何添加到框架而不受约束的组件都将添加到“CENTER”,这意味着组件会自动调整大小以填充整个空间。

However - when I create a class called World which also extends JPanel, add that to the window instead, then use the add() method in its constructor to add a new Player to it, it doesn't appear.

JPanel 的默认布局管理器是 FlowLayout,它尊重添加到其中的任何组件的首选大小,并将根据布局管理器的规则。

Interestingly, if I add setBackground() to the constructor for Player/Entity, I can see a coloured square where the entity SHOULD be. Its just that drawImage doesn't appear to work

可能是因为您的首选尺寸计算不正确,导致图像被截断。

  location     = new Point(x, y);
dimensions = new Dimension(w, h);

上述代码仅在 Point 为 (0, 0) 时才有效。更一般的情况代码应该是:

  location     = new Point(x, y);
dimensions = new Dimension(x + w, y + h);

因为您需要考虑相对于组件实际绘制图像的位置。

因此,当您执行此操作时,您应该会看到图像,但是您不会在正确的位置看到图像,因为布局管理器将覆盖该位置。

因此,如果您想继续使用这种使用组件的方法,您将需要使用空布局,这意味着您将需要手动使用每个组件的 setSize(...) 和 setLocation(...) 。在这种情况下,组件的大小将为 (w, h),您将使用以下命令绘制图像:

  g.drawImage(sprites.get(), 0, 0, this);

但请注意,如果您使用组件方法,则甚至不需要创建自定义组件。您可以将 JLabelImageIcon 一起使用。您可以在创建标签时分配图标。

关于java - 当我在 Jpanel 中使用 drawImage 时,为什么它会失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37499527/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com