Java — исключение IndexOutOfBoundsException

Я разрабатываю приложение на Java и закончил писать три основных файла классов, однако столкнулся с запутанной ошибкой. В данный момент я просто «пытаюсь» рисовать пиксели на экране, но мой массив пикселей не работает.

Я получаю IndexOutOfBoundsException в моем Render.java, хотя сейчас я получаю предупреждения или ошибки в коде?


Display.java

public class Display extends Canvas implements Runnable {

private static final long serialVersionUID = 1L;

public static final int WIDTH = 300;
public static final int HEIGHT = 190;
public static final int SCALE = 3;

public static Dimension DIMENSION = new Dimension(WIDTH * SCALE, HEIGHT * SCALE);

public static final String TITLE = "Untitled Project";

public int[] pixels;

public boolean isRunning = false;

public Thread thread;
public Screen screen;
public Render render;

public BufferedImage img;

public Display() {
    screen = new Screen(WIDTH, HEIGHT);
    img = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
    pixels = ((DataBufferInt) img.getRaster().getDataBuffer()).getData();
}

public void start(boolean isDebug) {
    if (isRunning)
        return;

    isRunning = true;

    thread = new Thread(this);
    thread.start();
}

public void stop() {
    if (!isRunning)
        return;

    isRunning = false;

    try {
        thread.join();
    } catch (Exception e) {
        e.printStackTrace();
        System.exit(0);
    }
}

private void render() {
    BufferStrategy bs = this.getBufferStrategy();

    if (bs == null) {
        createBufferStrategy(3);
        return;
    }

    screen.render();

    for (int i = 0; i < WIDTH * HEIGHT; i++)
        pixels[i] = screen.pixels[i];

    Graphics g = bs.getDrawGraphics();

    g.drawImage(img, 0, 0, WIDTH, HEIGHT, null);
    g.dispose();
    bs.show();
}

private void tick() {

}

public void run() {
    while (isRunning) {
        render();
        tick();
    }
}

public static void main(String[] args) {
    Display display = new Display();
        display.setMinimumSize(DIMENSION);
        display.setMaximumSize(DIMENSION);
        display.setPreferredSize(DIMENSION);

    JFrame frame = new JFrame();
        frame.setTitle(TITLE);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());
        frame.add(display, BorderLayout.CENTER);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setResizable(false);
        frame.setVisible(true);

    display.start(true);
}
}

Render.java

public class Render {

public final int width;
public final int height;
public final int[] pixels;

public Render(int width, int height) {
    this.width = width;
    this.height = height;
    pixels = new int[width * height];
}

public void draw(Render render, int xOffset, int yOffset) {
    for (int y = 0; y < render.height; y++) {

        int yPix = y + yOffset;

        for (int x = 0; x < render.width; x++) {
            int xPix = x + xOffset;

    ERROR -->   pixels[xPix + yPix * width] = render.pixels[x + y * render.width];
      }
    }
  }
}

Screen.java

public class Screen extends Render {

public Render render;
public Random random;

public Screen(int width, int height) {
    super(width, height);
    render = new Render(256, 256);
    random = new Random();

    for (int i = 0; i < 256 * 256; i++) {
        render.pixels[i] = random.nextInt();
    }
}

public void render() {
    draw(render, 0, 0);
}
}

Ошибка

Exception in thread "Thread-2" java.lang.ArrayIndexOutOfBoundsException: 57000
at com.willajhughes.java.graphics.Render.draw(Render.java:23)
at com.willajhughes.java.graphics.Screen.render(Screen.java:21)
at com.willajhughes.java.Display.render(Display.java:76)
at com.willajhughes.java.Display.run(Display.java:94)
at java.lang.Thread.run(Unknown Source)

Заранее спасибо!

--

Будут


person Miadric    schedule 16.08.2013    source источник
comment
xPix + yPix * width или x + y * render.width больше или равно pixels.length.   -  person Luiggi Mendoza    schedule 16.08.2013
comment
@LuiggiMendoza, ты не говори...   -  person Sam I am says Reinstate Monica    schedule 16.08.2013
comment
Как цитата. Убедитесь, что размер всегда указан в ваших ШИРИНЕ и ВЫСОТЕ, то есть в пикселях [(xPix + yPix * ширина) % WIDTH], если вы не совсем уверены в своих расчетах по индексам.   -  person Arnaldo Ignacio Gaspar Véjar    schedule 16.08.2013


Ответы (3)


Ваш массив pixels имеет размер width * height. Вы пытаетесь получить доступ к width + height * width. Как вы понимаете, это не понравится г-ну Яве.

person christopher    schedule 16.08.2013
comment
в каком случае xPix не меньше width? и yPix не менее height - person Sam I am says Reinstate Monica; 16.08.2013
comment
Дело не в этом? В какой-то момент они на 1 меньше, чем width и height. И затем OP пытается сослаться на xPix + yPix * width. Я прошу прощения. Это на 2 меньше, чем на width + height * width. - person christopher; 16.08.2013

Объект Screen создается с высотой 190 пикселей, а объект Render, созданный в конструкторе Screen, имеет высоту 256 пикселей. Вам нужно убедиться, что вы не перезаписываете границы вашего Screen.

Обратите внимание, что WIDTH * HEIGHT = 300 * 190 = 57000. (Из WIDTH и HEIGHT, определенных в классе Display.)

person matts    schedule 16.08.2013

Мне кажется, вы пытаетесь супер-наложить render высоты и ширины

256, 256 (65536 pixels)

на экран высотой и шириной

300, 190; (57000 pixels)

и вы используете одни и те же индексы для них обоих.


может быть, вы хотите, чтобы ваш рендер соответствовал вашему экрану

render = new Render(this.width, this.height);

вместо жесткого кодирования до 256x256, как у вас

person Sam I am says Reinstate Monica    schedule 16.08.2013