paintComponent is not working (Java)

Linkxgl picture Linkxgl · Feb 23, 2013 · Viewed 8.1k times · Source

I have been trying to override and use the paint component method instead of the paint method because I've seen it been suggested in multiple questions around here.

I've looked through many questions but I still can't seem to get this to work. I'm posting my original piece of code used to render a screen. I am thinking that extending JFrame is not the right way to go and instead I need to extend JPanel, and use paint component from there. I have another object where I actually extend the JPanel, and add in the JFrame (for rendering).

Here is the object I use to render, this, by the way works perfectly overriding the paint method.

package render;


import java.util.Arrays;

import javax.swing.*;

import java.awt.*; //Graphics, Graphics2D, Image

import sprites.Picture;


public class Window extends JFrame{
    private static final long serialVersionUID = 1L;

    public static Picture[] image_list =  new Picture[0]; // All the images I want to render
    private static String win_title = "Window"; // The name of the window
    private static CustomComponents cc = new CustomComponents();


    public Window(){
        setTitle(win_title); // set my title
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // close when you hit x button
        setUndecorated(true); // window has nothing on it

    }


    // paints all the images in image list according to their priority

    public void display(){
        add(cc);
        CustomComponents.updateImageList(image_list);
        pack();

        setMinimumSize(getSize());
        setLocationRelativeTo(null); // puts the screen in the middle
        setResizable(false); // can't resize the window
        setVisible(true); // to see the window


    }



    public double[] getWinSize(){
        double[] size = {this.getSize().getWidth(),this.getSize().getWidth()};

        return size;
    }

    public static void endAll(){
        for (Picture i:image_list){
            i = null;
        }
        image_list = new Picture[0];
        CustomComponents.updateImageList(image_list);
    }

    // close the window (seen in the game object)
    public static void close(){
        System.exit(0);
    }

    // called when adding a new sprite to the image_list array
    public static void addPicture(Picture element){
        Picture[] result = Arrays.copyOf(image_list, image_list.length +1); // does the same thing as the addObject method in objects
        result[image_list.length] = element;
        image_list = result;
        Arrays.sort(image_list);
        CustomComponents.updateImageList(image_list);

    }

    // updates the screen... Just repaints everything
    public void update() {
        cc.repaint();

    }

}


class CustomComponents extends JComponent {

    private static final long serialVersionUID = 1L;

    private static Picture[] image_list;

    public static void updateImageList(Picture[] image_list){
        CustomComponents.image_list = image_list;
    }

    @Override
    public Dimension getMinimumSize() {
        return new Dimension(640,360);
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(640,360);
    }

    @Override
    public Dimension getMaximumSize() {
        return new Dimension(640,360);
    }

    @Override
    public void paintComponent(Graphics graphics) {
        super.paintComponent(graphics);
        Graphics2D g2d = (Graphics2D) graphics;
        for (Picture i:image_list){
            if (i.getVisibility()){
            g2d.drawImage(i.getPic(), i.getXY()[0], i.getXY()[1], this);
            }
        }
        Toolkit.getDefaultToolkit().sync(); // this is for linux machines
        graphics.dispose(); // just good programming practice to collect the garbage
    }
}

I would post the object that actually adds in the window but it's way too convoluted now, and only a few thing happens. In the constructor I add the JFrame window above, and then I use a timer to call the update method on the JFrame object.

If you guys really need to the code I can post it but hopefully this will be enough.

Answer

mKorbel picture mKorbel · Feb 23, 2013
  • don't paint

    1. by using paintComponent() directly to the JFrame,
    2. not good idea to paint directly to JFrame, JFrame isn't proper container for this job
    3. have to use paint() instead of paintComponent() for JFrame,
  • Add @Override before any methods that you think should override a parent method, here the paintComponent(...) method. This way, the compiler will warn you if you are in fact not overriding what you thought you were.

  • put JComponent / JPanel to the JFrame

  • override getPreferredSize for JComponent / JPanel (your hardcoded // window size handle) , otherwise JComponent / JPanel returns zero dimension, simple nothing will be visible on the creen