0

I have a method to set the 'texture' of a JPanel, however it is throwing a NullPointerException, and i cannot figure out why.

Method:

void setTexutre(Image tileImage) {
    Graphics g = panel.getGraphics();
    int width = (int) getBounds().getWidth();
    int height = (int) getBounds().getHeight();
    int imageW = tileImage.getWidth(panel);
    int imageH = tileImage.getHeight(panel);
    for (int x5 = 0; x5 < width; x5 += imageW) {
        for (int y5 = 0; y5 < height; y5 += imageH) {
            g.drawImage(tileImage, x5, y5, panel);
        }
    }
    panel.paint(g);
}

The NullPointerException is thrown when i call "g.drawImage(tileImage, x5, y5, panel);"

And yes, the image is a real image, i have checked. In the method above panel is defined as a new JPanel, and intializes normally when I do not call the method.

Thanks for any help!

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
Socratic Phoenix
  • 556
  • 1
  • 7
  • 19
  • Use `TexturePaint`, as shown in the examples cited [here](http://stackoverflow.com/a/24746585/230513). – trashgod Mar 10 '15 at 09:13

2 Answers2

2
  1. DON'T use Graphics g = panel.getGraphics();
  2. NEVER call panel.paint(g);

See Painting in AWT and Swing and Performing Custom Painting for more details about how painting works in Swing/AWT.

getGraphics may return null (it's even documented as saying so) and you SHOULD never rely on it, it's not how custom painting works. Instead, you should override the components paintComponent method and perform your custom painting within it.

You don't control the paint process and should never call paint directly, Swing uses a passive rendering algorithm, this means that components are update ad-hoc, when ever the RepaintManager decides that they need to be repainted. This means, even if you could get your current code to work, the moment the RepaintManager decides to repaint panel, all you rendering would be lost...

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
-1

The following is the class I used for anyone else looking at this question.

package i.am.not.posting.the.real.pack.name;

import java.awt.Graphics;
import java.awt.image.BufferedImage;

import javax.swing.JPanel;

public class TiledPanel extends JPanel {

    private BufferedImage tileImage;

    public TiledPanel(BufferedImage tileImage) {
        this.tileImage = tileImage;
    }

    protected void paintComponent(Graphics g) {
        int width = getWidth();
        int height = getHeight();
        int imageW = tileImage.getWidth();
        int imageH = tileImage.getHeight();
        // Tile the image to fill our area.
        for (int x = 0; x < width; x += imageW) {
            for (int y = 0; y < height; y += imageH) {
                g.drawImage(tileImage, x, y, this);
            }
        }
    }
}

simply creating a TilePanel object will correctly tile the image.

vwegert
  • 18,371
  • 3
  • 37
  • 55
Socratic Phoenix
  • 556
  • 1
  • 7
  • 19
  • You've broken the paint chain - See [Painting in AWT and Swing](http://www.oracle.com/technetwork/java/painting-140037.html) for details about how painting works in Swing – MadProgrammer Mar 10 '15 at 23:07
  • Why downvote? And what do you mean I have broken the paint chain? 1. It works, 2. I did see that tutorial. – Socratic Phoenix Mar 18 '15 at 00:14
  • It's downvoted because it's a bad example of how to perform custom painting. It might "work" but it's at risk of allowing paint artefacts to remain within the graphics context and/or encourage bad practice which could lead to further paint artefacts – MadProgrammer Mar 18 '15 at 02:27
  • 1. Artefacts = Art**i**facts, 2. would it be fixed if i added super.paintComponent? – Socratic Phoenix Apr 30 '15 at 20:03