我正在尝试为Game Engine Architecture中的类(class)构建一个简单的游戏基础。但是我的JFrame不会显示任何内容。
我的代码当前的结构如下:
Implementation.java(这是我正在创建的Engine软件包的任意实现)
public class Implementation {
public static void main(String[] args){
World w = new World("Hej", "M:\\workspace\\SP6\\pics\\tulips.jpg",1024,768);
}
}
世界.java
public class World extends JFrame{
private static final long serialVersionUID = 1L;
private SpritePanel spritePanel;
private JPanel bottom;
private int width;
private int height;
public World(String windowCaption, String bgPath, int width, int height){
super(windowCaption);
spritePanel = new SpritePanel(bgPath);
add(spritePanel, BorderLayout.CENTER);
System.out.println(spritePanel);
bottom = new JPanel();
bottom.add(new JLabel("Hej"));
add(bottom, BorderLayout.SOUTH);
Dimension size = new Dimension(width,height);
setSize(size);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
setVisible(true);
validate();
repaint();
}
SpritePanel.java
public class SpritePanel extends JPanel {
private static final long serialVersionUID = 1L;
private ImageIcon background;
private ArrayList<Sprite> sprites = new ArrayList<Sprite>();
public SpritePanel(String bgPath){
background = new ImageIcon(bgPath);
setLayout(null);
Dimension size = new Dimension(background.getIconWidth(), background.getIconHeight());
setPreferredSize(size);
setMaximumSize(size);
setMinimumSize(size);
}
@Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(background.getImage(), 0, 0, this);
System.out.println("painted panel");
}
}
因此,目前的基本 Action 流程(据我所知):
事情是JPanel中的paintComponent方法,而SpritePanel似乎没有被调用。如您所见,我在paintComponent的SpritePanel中添加了System.out.println,并且该行从未执行。
我注意到的另一件事是,程序包似乎知道组件在那里。因为如果我评论三行
spritePanel = new SpritePanel(bgPath);
add(spritePanel, BorderLayout.CENTER);
System.out.println(spritePanel);
运行程序时,Windows的大小减小为“底部” -JPanel的大小。我看不到添加到面板中的JLabel,但窗口大小就是它的大小。所以pack()方法似乎正在寻找组件的尺寸。
如果我评论添加了底部面板的三行内容,则窗口大小将减小为无高度,并且宽度将从标准图标减小。
我一直在尝试不同的方法来使其正常工作,但无济于事。我之前已经使用Swing进行了编程并制作了工作程序,但似乎在这里找不到问题。
帮助非常感谢。
最佳答案
您的String路径可能有问题。但是,您应该做什么,而不是读取文件,而是应该读取URL,并从类路径中加载。在部署时,您会发现文件路径不起作用,因此最好将图像打包为embedded resource,然后将图像放在类路径中。这样做时我没有任何问题。这就是我所做的。
World w = new World("Hej", "/resources/stackoverflow5.png", 1024, 768);
background = new ImageIcon(SpritePanel.class.getResource(bgPath));
resources
包中一切正常
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Implementation {
public static void main(String[] args) {
World w = new World("Hej", "/resources/stackoverflow5.png", 1024, 768);
}
}
class World extends JFrame {
private static final long serialVersionUID = 1L;
private SpritePanel spritePanel;
private JPanel bottom;
private int width;
private int height;
public World(String windowCaption, String bgPath, int width, int height) {
super(windowCaption);
spritePanel = new SpritePanel(bgPath);
add(spritePanel, BorderLayout.CENTER);
System.out.println(spritePanel);
bottom = new JPanel();
bottom.add(new JLabel("Hej"));
add(bottom, BorderLayout.SOUTH);
Dimension size = new Dimension(width, height);
setSize(size);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
setVisible(true);
validate();
repaint();
}
class SpritePanel extends JPanel {
private static final long serialVersionUID = 1L;
private ImageIcon background;
//private ArrayList<Sprite> sprites = new ArrayList<Sprite>();
public SpritePanel(String bgPath) {
background = new ImageIcon(SpritePanel.class.getResource(bgPath));
setLayout(null);
Dimension size = new Dimension(background.getIconWidth(), background.getIconHeight());
setPreferredSize(size);
setMaximumSize(size);
setMinimumSize(size);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(background.getImage(), 0, 0, this);
System.out.println("painted panel");
}
}
}
旁注
setSize()
。您已经pack()
了。最好还是打包。 pack()
放在setLocationRelativeTo()
之前。如果之后使用pack()
,您会发现您的相框将不在所需的位置。 public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run() {
new World("Hej", "/resources/stackoverflow5.png", 1024, 768);
}
});
}
setExtendedState(JFrame.MAXIMIZED_BOTH);
setSize()
也将无法正常工作,因为之后您要调用pack()
。