1

I want do draw a rectangle in my JFrame window, but I'am always getting a nullpointer error.. Why is it happening? what is the best (correct) way to draw graphics like rectangles, gradients, etc or something like falling snow in swing?

This is the Exception:

Exception in thread "Thread-0" java.lang.NullPointerException
    at gui.Window.run(Window.java:24)
    at gui.Window$1.run(Window.java:34)
    at java.lang.Thread.run(Unknown Source)

And source:

public class Window extends JFrame implements Runnable {

    private boolean run = true;

    public Window() {
        super.setSize(500, 500);
        super.setTitle("MY GUI");
        super.setDefaultCloseOperation(EXIT_ON_CLOSE);
        super.setContentPane(new Container());
    }

    @Override
    public void run() {
        Graphics g = super.getContentPane().getGraphics();
        while (this.run) {
            g.setColor(new Color(0, 0, 0, 255));
            g.fillRect(0, 0, 200, 200);
        }
    }

    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                Window window = new Window();
                window.run();
            }
        }).start();
    }   
}

Error line 24: g.setColor(new Color(0, 0, 0, 255));

Why is it doing that?

1
  • g is probably null check super.getContentPane().getGraphics();, Set a breakpoint there and debug it.. Commented Dec 20, 2013 at 17:48

2 Answers 2

7

The code you posted makes no sense.

First of all, every interaction with Swing components (except calls to repaint()) must be done in the event dispatch thread.

Second, there is no point in running an infinite loop that would constantly paint the same thing on a Graphics.

Third, that's not how it works. You can't get the Graphics associated to a component and paint on it. Instead, you must override the paintComponent(Graphics) method of a Swing component, wait for swing to call this method, and use the provided Graphics argument to paint whatever you want. If you want to change what is being painted, then you need to call repaint() on this element. Don't do that with JFrame. Create a subclass of JComponent or JPanel, and add an instance of the subclass to a JFrame, and then make this JFrame visible:

public class CustomComponent extends JComponent {
    @Override
    public void paintComponent(Graphics g) {
         // paint here
    }

    @Override
    public Dimension getPreferredSize() {
        // return preferred size here
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame f = new JFrame();
                f.add(new CustomComponent());
                f.pack(); 
                f.setVisible(true);
            }
        });
    }
}
Sign up to request clarification or add additional context in comments.

Comments

0

getGraphics will return null if the component is not visible.

To make your Window visible you have to call setVisible(bool).

You also have to be careful using threads with Swing.

4 Comments

Thanks! But why is it so laggy when I run it?
@user3123545: probably because you're constantly painting. Infinite busy loops are not a good idea.
Because you're repainting the window in an infinite loop
@user31223545 Use a JPanel to paint on and override the paintComponent method. You shouldnt paint on top level containers like JFrame

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.