2

I have a JFrame created with GUI builder of Netbeans, which contains a JPanel only. I have created a method getPanel for getting a reference to this JPanel:

public class ShowDrawings extends JFrame {

    public ShowDrawings() {
        initComponents();
    }

    public JPanel getPanel(){
        return panel;
    }

    private JPanel panel;
}

In my main function I am doing:

public class Main {
    public static void main(String[] args){
        ShowDrawings sd = new ShowDrawings();
        sd.setSize(800, 600);
        Graphics g = sd.getPanel().getGraphics();
        g.setColor(Color.BLACK);
        g.drawOval(400, 300, 50, 50);
        sd.getPanel().paint(g);
        sd.repaint();
        sd.setVisible(true);
    }
}

But it does not draw anything. Please help me. I have looked some related questions but they are all suggesting extending JPanel and overriding its paint method. But I did not want to do that way. Thanks.

mKorbel
  • 109,525
  • 20
  • 134
  • 319
Olcay Ertaş
  • 5,987
  • 8
  • 76
  • 112
  • If you are using GUI builder of Netbeans,it should not cause any problem.I have used it many times.Can you please post full code? – joey rohan Dec 27 '12 at 15:40

2 Answers2

6

I have looked some related questions but they are all suggesting extending JPanel and overriding its paint method. But I did not want to do that way

You should not override JPanel paint() method, rather paintComponent(..). This is best practice and should be done if you want code that will not produce anomalies. Also doing it in your current approach (as you have seen) makes creating persistent drawings a lot harder as they are wiped away on repaint()

Rather extend JPanel and override paintComponent(Graphics g) not forgetting to call super.paintComponent(g) as first call in overridden paintComponent(..) method. Also dont forget to override getPreferredSize() of JPanel so that we can return correct dimensions and pack() may be called on JFrame (+1 to @mKorbels comment):

Here is some example code:

enter image description here

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Test {

    public Test() {
        initComponents();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Test();
            }
        });
    }

    private void initComponents() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel testPanel = new JPanel() {
            @Override
            protected void paintComponent(Graphics grphcs) {
                super.paintComponent(grphcs);

                Graphics2D g2d = (Graphics2D) grphcs;

                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

                g2d.setColor(Color.GREEN);
                //g2d.drawOval(10,10,100,100);//I like fill :P
                g2d.fillOval(10,10,100,100);

            }

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

        frame.add(testPanel);

        frame.pack();
        frame.setVisible(true);
    }
}
David Kroukamp
  • 36,155
  • 13
  • 81
  • 138
  • For circles and other ellipses, you might want to also `g.setRenderingHint( RenderingHints. KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE)`, see http://stackoverflow.com/a/31221395/1143274 – Evgeni Sergeev Jul 05 '15 at 02:14
3

The first time you repaint() your ShowDrawings sd frame anything you've painted like this (sd.getPanel().getGraphics().drawOval(...)) would be erased by the original JPanel#paintComponent() method.

As Andrew Thompson has written:

Do not use Component.getGraphics(). Instead, subclass and override the paint() (AWT), or paintComponent() (Swing) method.

Component.getGraphics() simply can't work. Java uses a callback mechanism for drawing graphics. You are not supposed to "push" graphics information into a component using getGraphics(). Instead you are supposed to wait until Java calls your paint()/paintComponent() method. At that moment you are supposed to provide the Component with the drawings you would like to do.

If you're just checking/debugging something you could even do something like this:

class Test {
    private JPanel panel = new JPanel() {
        public void paintComponent(Graphics g) {
             g.setColor(Color.BLACK);
             g.drawOval(400, 300, 50, 50);
        }
    };
}
Community
  • 1
  • 1
Xeon
  • 5,949
  • 5
  • 31
  • 52