这是我在这个论坛的第一篇文章,如果我在这里格式化或发布礼仪时出错,请提前原谅我。
我对Java Swing编程相当陌生,我一直试图为个人项目创建简单的塔防游戏,但是在我的应用程序中绘制图像时遇到了麻烦。我在这个论坛和甲骨文的许多java教程中都环顾四周,但我从来没有找到一个有助于解决这个问题的解决方案,所以我不得不求助于自己。 / p>
public static void main(String[] args)
{
new DotO();
}
public DotO()
{
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
private void createAndShowGUI()
{
backgroundPanel = new JPanel();
setBorder(BorderFactory.createLineBorder(Color.black));
loadBackground();
setBackground(Color.white);
//1. Create the frame.
JFrame frame = new JFrame("Defense Of The Origin");
//2. Optional: What happens when the frame closes?
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//4. Size the frame.
frame.setSize(SIZEX, SIZEY);
//5. Show it.
frame.setVisible(true);
//3. Add Background Panel
frame.add(backgroundPanel);
}
private void loadBackground()
{
String fileName = "resources/Background.jpg";
try
{
URL url = getClass().getResource(fileName);
backgroundImage = ImageIO.read(url);
}
catch(MalformedURLException mue)
{
System.out.println("url: " + mue.getMessage());
}
catch(IOException ioe)
{
System.out.println("read: " + ioe.getMessage());
}
}
@Override
protected void paintComponent(Graphics g)
{
System.out.println("painted");
super.paintComponent(g);
int w = getWidth();
int h = getHeight();
g.drawImage(backgroundImage, 0, 0, w, h, this);
System.out.println("it's working");
}
框架确实打开,在首选尺寸上没有任何问题,但框架上没有任何内容。我只看到一个灰色空间,当我将一个System.out.print放在paintComponent方法中时,它不会在控制台中显示,所以我知道应用程序从未实际运行paintComponent方法。任何建议将不胜感激!
答案 0 :(得分:2)
这显然属于一个类
class DotO extends JPanel { ... }
但是,在createAndShowGUI
方法中,您正在创建新面板并将此面板添加到框架中。在此面板中,不会覆盖paintComponent
方法。
另一方面,你永远不会创造一个"可见" DotO
的实例。您只是创建DotO
的实例,但从不将其添加到框架中。
一种解决方案是省略backgroundPanel
,而不是
frame.add(backgroundPanel);
你可以打电话
// Add "this" to the panel. "this" is the DotO instance
// where the `paintComponent` method is overridden
frame.add(this);
您应该考虑将GUI创建从DotO
类中拉出来,并在main
方法中创建框架,如下所示:
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
private static void createAndShowGUI()
{
//1. Create the frame.
JFrame frame = new JFrame("Defense Of The Origin");
//2. Optional: What happens when the frame closes?
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//4. Size the frame.
frame.setSize(SIZEX, SIZEY);
//5. Show it.
frame.setVisible(true);
// Here, create an instance of "DotO", and add it to the frame!
frame.add(new DotO());
}
// In the DotO constructor, only do what has to be done
// specifically for this DotO instance:
public DotO()
{
setBorder(BorderFactory.createLineBorder(Color.black));
loadBackground();
setBackground(Color.white);
}
但现在可以将其视为一个细节。
编辑回应评论:
为了绘制多个图像,您可以像背景图像一样加载和绘制它们(但在背景图像之后,出于显而易见的原因)。
可以在这里提出许多进一步的建议。虽然严格来说,这不是问题+答案网站的目的,但应该通过阅读教程和代码示例来完成。
所以Q& A纯粹主义者:现在请离开,一些未回答的事情:
我知道Swing是一个很好的毒药":只需几行代码,你的第一帧就会有一些图像。但这并不意味着您在创建游戏时不必计划和提前考虑。你不能只是编写更多代码"希望"一些不错的东西"会出来的。
因此,我建议您首先考虑游戏的结构应该如何。你会上哪节课?根据班级的字段和方法,每个班级的责任应该是什么?
编写"测试片段"肯定没错。某些功能。例如,用于加载和显示背景图像的测试片段;-)但是,您无法通过从头开始将大量代码编写到单个类中来创建游戏。
此处的指南偶尔会在单词中描述 您想要实现的目标。作为一个例子(非常"压缩",以说明要点):
我想要一个具有一定范围的塔,可以拍摄并可以在屏幕上绘画
这可以帮助粗略派生一个结构:
产生类似
的类class Tower {
float range;
void shoot() {...}
void paintInto(Graphics g) {...}
}
(这实际上只是一个非常粗略的准则!)
此外,还有许多细节需要考虑。例如,您随后会注意到将loadBackground()
方法更改为类似
private void loadImage(String fileName)
{
...
}
可以被称为
的方法background = loadImage("resources/Background.jpg");
tower = loadImage("resources/Tower.jpg");
但同样:这些是您可以从教程和代码示例中学到的东西(并且您希望(希望)迟早会自动执行)