-1

I'm developing an application in Java, and I've finished writing the three main class files - however I've hit a confusing error. I'm at the moment just "attempting" to draw pixels upon the screen but my pixels array doesn't work.

I'm getting the IndexOutOfBoundsException in my Render.java even though I'm getting now warnings or errors in the code?

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);
    }
}

Error

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)
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Miadric
  • 11
  • 1
  • 4

3 Answers3

3

Your pixels array of is of the size width * height. You're attempting to access width + height * width. As you may imagine, that's not going to go down well with Mr. Java.

christopher
  • 26,815
  • 5
  • 55
  • 89
0

It looks to me like you're trying to super-impose a render of height and width

256, 256 (65536 pixels)

onto a screen of height and width

300, 190; (57000 pixels)

and you're using the same indexes for both of them.


maybe you want to make your render match your screen

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

instead of hard-coding to 256x256 like you are

0

The Screen object is created with a height of 190 pixels, but the Render object created in the Screen constructor has a height of 256 pixels. You need to make sure you don't overwrite the bounds of your Screen.

Note that WIDTH * HEIGHT = 300 * 190 = 57000. (From the WIDTH and HEIGHT defined in the Display class.)

matts
  • 6,738
  • 1
  • 33
  • 50