繁体   English   中英

如何在java.applet.Applet中获取java.awt.Graphics的实例?

[英]How to get an instance of java.awt.Graphics in a java.applet.Applet?

我目前正在为我的计算机科学课编写Snake游戏。 但是,我遇到了很多困难(因为我是自己中唯一一个独自工作的人),因此我不得不重新启动。

现在,我只是想从我制作的第二个类(细分)中创建一组对象(名为Snake)。

我在第26行获得了NullPointerException: g.fillRect(xValue, yValue, size, size); 我应该在哪里获取Graphics实例以调用此方法?

import java.awt.*;
import java.applet.*;

public class Segment extends Applet
{
   private Graphics g;

   private int xValue;
   private int yValue;
   private int size;

   public Segment () {}

  public Segment(int x, int y)
  {
  xValue = x;
  yValue = y;

  size = 10;

  drawSegment(g);
   }

   public void drawSegment(Graphics g)
   {
      g.fillRect(xValue, yValue, size, size);
   }

  }

import java.awt.*;
import java.applet.*;

public class SnakeGame extends Applet
{
   private Segment[] snake;
   private Graphics g;

   private int length;
   private int sxValue;
   private int syValue;

   public SnakeGame()
   {
      length = 6;
      snake = new Segment[length];
      sxValue = 100;
      syValue = 100;

      for (int c = 0; c < snake.length; c++)
      {
         snake[c] = new Segment(sxValue, syValue);
         sxValue = sxValue + 10;     
      }

      drawSnake(g);

    }

   public void drawSnake(Graphics g)
   {
      for(int counter = 0; counter < length; counter++)
      {
          snake[counter].drawSegment(g);

      }  
    }


}

但是,我不断收到诸如

java.lang.NullPointerException
at Segment.drawSegment(Segment.java:26)
at Segment.<init>(Segment.java:21)
at SnakeGame.<init>(SnakeGame.java:22)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
at java.lang.Class.newInstance(Class.java:433)
at sun.applet.AppletPanel.createApplet(AppletPanel.java:799)
at sun.applet.AppletPanel.runLoader(AppletPanel.java:728)
at sun.applet.AppletPanel.run(AppletPanel.java:378)
at java.lang.Thread.run(Thread.java:745)

您声明Graphics g; 并且不要实例化它。 因此,您将一个null值传递给drawSegment(Graphics g)并尝试调用g.fillRect(xValue, yValue, size, size); 在该null对象上。

您正在使用的java.awt.Graphics类只是一个抽象类。 该对象需要通过某种实现实例化-由您或由框架进行。

由于您使用的是继承了Component的Applet ,请尝试Component.getGraphics()来获取图形对象。

private Graphics g = getGraphics();

然后,您在构造函数中调用绘图方法。 这不是一个好习惯。 实例化一个对象(这里是一个applet)并绘制它是不同的。

另外,这里的每个类都有自己的Graphics变量。 似乎应该对所有绘图使用单个实例,并将其传递给每个可绘制对象。

从自定义绘制组件的paint(Graphics)paintComponent(Graphics)方法中获取Graphics对象。 那个时间(当JVM请求时)是应该绘制AWT / Swing GUI的时间。 有关更多详细信息和工作源,请参见执行自定义绘画

一般提示/问题。

  1. 为什么要编写小程序? 如果是由于老师指定了原因,请向他们介绍为什么CS老师应该停止教Java小程序
  2. 为什么要使用AWT? 有很多充分的理由,请参阅此答案 ,以放弃使用AWT的组件而支持Swing。
  3. 通常认为最好在添加到顶层容器的PanelCanvasJPanel中进行自定义渲染,而不是在容器本身中进行自定义渲染。 这更容易适应,因为我们可以在小程序,框架,对话框或其他面板的布局约束中显示面板。 还有其他优点。
  4. 上面有两个applet,但只有SnakeGame应该是applet。 相反, Segment类应该只知道在被要求时如何将自己绘制到Graphics对象。 然后, SnakeGame可以存储Segment对象的列表,并(在需要时)依次绘制每个对象。
  5. 不要声明一个applet的构造函数,因为没有办法确保在Event Dispatch Thread上调用它。 init()方法中“仅第一次”执行所有操作。 但是,请认真避免使用小程序,因为它们是一种过时的技术,只会让您头疼。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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