1

When I run this code, I cant see the oval, I can only see a blank frame. I know that I can use the paintComponent(Graphics g) method, but I am curious to know why my code wont work.

public class Check {

    public static void main(String[] args) {    
        Check c = new Check();
        c.init();   
    }

    public void init() {

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(3);   

        JPanel panel = new JPanel();

        frame.setSize(new Dimension(800, 600));
        frame.setTitle("Test");
        frame.setVisible(true);
        frame.getContentPane().add(panel);

        Graphics2D g = (Graphics2D)panel.getGraphics();
        g.setColor(Color.BLUE);
        g.fillOval(50, 50, 50, 50);

    }
bill
  • 11
  • 3
  • just a guess, but i think `panel` is added with size 0x0 –  Aug 04 '15 at 15:39
  • Reopened the question because the duplicate link does not answer the question and the example posted was not a good example because the GUI was not created on the EDT and the custom painting did not override getPreferredSize(). The Swing tutorial on [Custom Painting](http://docs.oracle.com/javase/tutorial/uiswing/painting/step1.html) shows the better way to do this by overriding the `paintComponent()` and the `getPreferredSize() method and by placing all the code on the Event Dispatch Thread. – camickr Aug 04 '15 at 15:59
  • @Gimby, glad you agree with my answer. – camickr Aug 04 '15 at 16:00
  • *"Thanks you all for helping me! The order was the problem.."* The question is not an appropriate place to put the answer! It should go into a separate answer below (yes, you **can** answer your own question). BTW - unless the custom painting code has been completely redesigned, the problem has not really been fixed. – Andrew Thompson Aug 04 '15 at 22:10

1 Answers1

3

All Swing code should be executed on the Event Dispatch Thread (EDT). This makes sure the code is single threaded. Read the Swing tutorial on Concurrency for more information. The tutorial also includes a section on Custom Painting you should read.

In your example the code is not executed in the order you think it is because some of the painting code is placed on the EDT and the frame is repainted after the oval is painted.

import java.awt.*;
import javax.swing.*;

public class Check {

    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                Check c = new Check();
                c.init();
            }
        });
    }

    public void init() {

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(3);

        JPanel panel = new JPanel();

        frame.setSize(new Dimension(800, 600));
        frame.setTitle("Test");
        frame.getContentPane().add(panel);
        frame.setVisible(true);

        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                Graphics2D g = (Graphics2D)panel.getGraphics();
                g.setColor(Color.BLUE);
                g.fillOval(50, 50, 50, 50);
            }
        });
    }
}

This is another reason why you should never use getGraphics(). It is only temporary painting and will be lost as soon as Swing determines a components needs to be repainted. Just try resizing the frame and see what happens.

camickr
  • 321,443
  • 19
  • 166
  • 288
  • Good that you reopened this. Now perhaps you should revert the question back to the way it was before it was closed :/ – Gimby Aug 05 '15 at 07:38